diff options
| author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-04-29 07:44:44 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-07 15:21:05 -0400 |
| commit | 6c493f8b28c6744995e92801a20dca192635dd22 (patch) | |
| tree | 90ebbef8d3823edfb23157b894aacd7d4e5a5330 /drivers/media/video/cpia2 | |
| parent | 04ef052419ac61f28c6b7eafbe5d8e82c02bbee2 (diff) | |
[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>
Diffstat (limited to 'drivers/media/video/cpia2')
| -rw-r--r-- | drivers/media/video/cpia2/cpia2.h | 34 | ||||
| -rw-r--r-- | drivers/media/video/cpia2/cpia2_core.c | 142 | ||||
| -rw-r--r-- | drivers/media/video/cpia2/cpia2_usb.c | 78 | ||||
| -rw-r--r-- | drivers/media/video/cpia2/cpia2_v4l.c | 846 | ||||
| -rw-r--r-- | drivers/media/video/cpia2/cpia2dev.h | 50 |
5 files changed, 363 insertions, 787 deletions
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h index ab252188981..cdef677d57e 100644 --- a/drivers/media/video/cpia2/cpia2.h +++ b/drivers/media/video/cpia2/cpia2.h | |||
| @@ -32,11 +32,12 @@ | |||
| 32 | #define __CPIA2_H__ | 32 | #define __CPIA2_H__ |
| 33 | 33 | ||
| 34 | #include <linux/videodev2.h> | 34 | #include <linux/videodev2.h> |
| 35 | #include <media/v4l2-common.h> | ||
| 36 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
| 37 | #include <linux/poll.h> | 36 | #include <linux/poll.h> |
| 37 | #include <media/v4l2-common.h> | ||
| 38 | #include <media/v4l2-device.h> | ||
| 39 | #include <media/v4l2-ctrls.h> | ||
| 38 | 40 | ||
| 39 | #include "cpia2dev.h" | ||
| 40 | #include "cpia2_registers.h" | 41 | #include "cpia2_registers.h" |
| 41 | 42 | ||
| 42 | /* define for verbose debug output */ | 43 | /* define for verbose debug output */ |
| @@ -65,7 +66,6 @@ | |||
| 65 | 66 | ||
| 66 | /* Flicker Modes */ | 67 | /* Flicker Modes */ |
| 67 | #define NEVER_FLICKER 0 | 68 | #define NEVER_FLICKER 0 |
| 68 | #define ANTI_FLICKER_ON 1 | ||
| 69 | #define FLICKER_60 60 | 69 | #define FLICKER_60 60 |
| 70 | #define FLICKER_50 50 | 70 | #define FLICKER_50 50 |
| 71 | 71 | ||
| @@ -148,7 +148,6 @@ enum { | |||
| 148 | #define DEFAULT_BRIGHTNESS 0x46 | 148 | #define DEFAULT_BRIGHTNESS 0x46 |
| 149 | #define DEFAULT_CONTRAST 0x93 | 149 | #define DEFAULT_CONTRAST 0x93 |
| 150 | #define DEFAULT_SATURATION 0x7f | 150 | #define DEFAULT_SATURATION 0x7f |
| 151 | #define DEFAULT_TARGET_KB 0x30 | ||
| 152 | 151 | ||
| 153 | /* Power state */ | 152 | /* Power state */ |
| 154 | #define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER | 153 | #define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER |
| @@ -287,7 +286,6 @@ struct camera_params { | |||
| 287 | struct { | 286 | struct { |
| 288 | u8 cam_register; | 287 | u8 cam_register; |
| 289 | u8 flicker_mode_req; /* 1 if flicker on, else never flicker */ | 288 | u8 flicker_mode_req; /* 1 if flicker on, else never flicker */ |
| 290 | int mains_frequency; | ||
| 291 | } flicker_control; | 289 | } flicker_control; |
| 292 | 290 | ||
| 293 | struct { | 291 | struct { |
| @@ -337,7 +335,7 @@ struct camera_params { | |||
| 337 | u8 vc_control; | 335 | u8 vc_control; |
| 338 | u8 vc_mp_direction; | 336 | u8 vc_mp_direction; |
| 339 | u8 vc_mp_data; | 337 | u8 vc_mp_data; |
| 340 | u8 target_kb; | 338 | u8 quality; |
| 341 | } vc_params; | 339 | } vc_params; |
| 342 | 340 | ||
| 343 | struct { | 341 | struct { |
| @@ -366,23 +364,23 @@ struct framebuf { | |||
| 366 | struct framebuf *next; | 364 | struct framebuf *next; |
| 367 | }; | 365 | }; |
| 368 | 366 | ||
| 369 | struct cpia2_fh { | ||
| 370 | enum v4l2_priority prio; | ||
| 371 | u8 mmapped; | ||
| 372 | }; | ||
| 373 | |||
| 374 | struct camera_data { | 367 | struct camera_data { |
| 375 | /* locks */ | 368 | /* locks */ |
| 369 | struct v4l2_device v4l2_dev; | ||
| 376 | struct mutex v4l2_lock; /* serialize file operations */ | 370 | struct mutex v4l2_lock; /* serialize file operations */ |
| 377 | struct v4l2_prio_state prio; | 371 | struct v4l2_ctrl_handler hdl; |
| 372 | struct { | ||
| 373 | /* Lights control cluster */ | ||
| 374 | struct v4l2_ctrl *top_light; | ||
| 375 | struct v4l2_ctrl *bottom_light; | ||
| 376 | }; | ||
| 377 | struct v4l2_ctrl *usb_alt; | ||
| 378 | 378 | ||
| 379 | /* camera status */ | 379 | /* camera status */ |
| 380 | volatile int present; /* Is the camera still present? */ | ||
| 381 | int open_count; /* # of process that have camera open */ | ||
| 382 | int first_image_seen; | 380 | int first_image_seen; |
| 383 | u8 mains_freq; /* for flicker control */ | ||
| 384 | enum sensors sensor_type; | 381 | enum sensors sensor_type; |
| 385 | u8 flush; | 382 | u8 flush; |
| 383 | struct v4l2_fh *stream_fh; | ||
| 386 | u8 mmapped; | 384 | u8 mmapped; |
| 387 | int streaming; /* 0 = no, 1 = yes */ | 385 | int streaming; /* 0 = no, 1 = yes */ |
| 388 | int xfer_mode; /* XFER_BULK or XFER_ISOC */ | 386 | int xfer_mode; /* XFER_BULK or XFER_ISOC */ |
| @@ -390,7 +388,7 @@ struct camera_data { | |||
| 390 | 388 | ||
| 391 | /* v4l */ | 389 | /* v4l */ |
| 392 | int video_size; /* VIDEO_SIZE_ */ | 390 | int video_size; /* VIDEO_SIZE_ */ |
| 393 | struct video_device *vdev; /* v4l videodev */ | 391 | struct video_device vdev; /* v4l videodev */ |
| 394 | u32 width; | 392 | u32 width; |
| 395 | u32 height; /* Its size */ | 393 | u32 height; /* Its size */ |
| 396 | __u32 pixelformat; /* Format fourcc */ | 394 | __u32 pixelformat; /* Format fourcc */ |
| @@ -425,6 +423,7 @@ struct camera_data { | |||
| 425 | /* v4l */ | 423 | /* v4l */ |
| 426 | int cpia2_register_camera(struct camera_data *cam); | 424 | int cpia2_register_camera(struct camera_data *cam); |
| 427 | void cpia2_unregister_camera(struct camera_data *cam); | 425 | void cpia2_unregister_camera(struct camera_data *cam); |
| 426 | void cpia2_camera_release(struct v4l2_device *v4l2_dev); | ||
| 428 | 427 | ||
| 429 | /* core */ | 428 | /* core */ |
| 430 | int cpia2_reset_camera(struct camera_data *cam); | 429 | int cpia2_reset_camera(struct camera_data *cam); |
| @@ -443,7 +442,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd); | |||
| 443 | int cpia2_do_command(struct camera_data *cam, | 442 | int cpia2_do_command(struct camera_data *cam, |
| 444 | unsigned int command, | 443 | unsigned int command, |
| 445 | unsigned char direction, unsigned char param); | 444 | unsigned char direction, unsigned char param); |
| 446 | struct camera_data *cpia2_init_camera_struct(void); | 445 | struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf); |
| 447 | int cpia2_init_camera(struct camera_data *cam); | 446 | int cpia2_init_camera(struct camera_data *cam); |
| 448 | int cpia2_allocate_buffers(struct camera_data *cam); | 447 | int cpia2_allocate_buffers(struct camera_data *cam); |
| 449 | void cpia2_free_buffers(struct camera_data *cam); | 448 | void cpia2_free_buffers(struct camera_data *cam); |
| @@ -454,7 +453,6 @@ unsigned int cpia2_poll(struct camera_data *cam, | |||
| 454 | int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma); | 453 | int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma); |
| 455 | void cpia2_set_property_flip(struct camera_data *cam, int prop_val); | 454 | void cpia2_set_property_flip(struct camera_data *cam, int prop_val); |
| 456 | void cpia2_set_property_mirror(struct camera_data *cam, int prop_val); | 455 | void cpia2_set_property_mirror(struct camera_data *cam, int prop_val); |
| 457 | int cpia2_set_target_kb(struct camera_data *cam, unsigned char value); | ||
| 458 | int cpia2_set_gpio(struct camera_data *cam, unsigned char setting); | 456 | int cpia2_set_gpio(struct camera_data *cam, unsigned char setting); |
| 459 | int cpia2_set_fps(struct camera_data *cam, int framerate); | 457 | int cpia2_set_fps(struct camera_data *cam, int framerate); |
| 460 | 458 | ||
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c index ee91e295c90..17188e23477 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, | |||
| 66 | static int config_sensor_500(struct camera_data *cam, | 66 | static int config_sensor_500(struct camera_data *cam, |
| 67 | int reqwidth, int reqheight); | 67 | int reqwidth, int reqheight); |
| 68 | static int set_all_properties(struct camera_data *cam); | 68 | static int set_all_properties(struct camera_data *cam); |
| 69 | static void get_color_params(struct camera_data *cam); | ||
| 70 | static void wake_system(struct camera_data *cam); | 69 | static void wake_system(struct camera_data *cam); |
| 71 | static void set_lowlight_boost(struct camera_data *cam); | 70 | static void set_lowlight_boost(struct camera_data *cam); |
| 72 | static void reset_camera_struct(struct camera_data *cam); | 71 | static void reset_camera_struct(struct camera_data *cam); |
| @@ -453,15 +452,6 @@ int cpia2_do_command(struct camera_data *cam, | |||
| 453 | cam->params.version.vp_device_hi = cmd.buffer.block_data[0]; | 452 | cam->params.version.vp_device_hi = cmd.buffer.block_data[0]; |
| 454 | cam->params.version.vp_device_lo = cmd.buffer.block_data[1]; | 453 | cam->params.version.vp_device_lo = cmd.buffer.block_data[1]; |
| 455 | break; | 454 | break; |
| 456 | case CPIA2_CMD_GET_VP_BRIGHTNESS: | ||
| 457 | cam->params.color_params.brightness = cmd.buffer.block_data[0]; | ||
| 458 | break; | ||
| 459 | case CPIA2_CMD_GET_CONTRAST: | ||
| 460 | cam->params.color_params.contrast = cmd.buffer.block_data[0]; | ||
| 461 | break; | ||
| 462 | case CPIA2_CMD_GET_VP_SATURATION: | ||
| 463 | cam->params.color_params.saturation = cmd.buffer.block_data[0]; | ||
| 464 | break; | ||
| 465 | case CPIA2_CMD_GET_VP_GPIO_DATA: | 455 | case CPIA2_CMD_GET_VP_GPIO_DATA: |
| 466 | cam->params.vp_params.gpio_data = cmd.buffer.block_data[0]; | 456 | cam->params.vp_params.gpio_data = cmd.buffer.block_data[0]; |
| 467 | break; | 457 | break; |
| @@ -617,6 +607,7 @@ int cpia2_reset_camera(struct camera_data *cam) | |||
| 617 | { | 607 | { |
| 618 | u8 tmp_reg; | 608 | u8 tmp_reg; |
| 619 | int retval = 0; | 609 | int retval = 0; |
| 610 | int target_kb; | ||
| 620 | int i; | 611 | int i; |
| 621 | struct cpia2_command cmd; | 612 | struct cpia2_command cmd; |
| 622 | 613 | ||
| @@ -800,9 +791,16 @@ int cpia2_reset_camera(struct camera_data *cam) | |||
| 800 | } | 791 | } |
| 801 | cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg); | 792 | cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg); |
| 802 | 793 | ||
| 803 | /* Set target size (kb) on vc */ | 794 | /* Set target size (kb) on vc |
| 795 | This is a heuristic based on the quality parameter and the raw | ||
| 796 | framesize in kB divided by 16 (the compression factor when the | ||
| 797 | quality is 100%) */ | ||
| 798 | target_kb = (cam->width * cam->height * 2 / 16384) * | ||
| 799 | cam->params.vc_params.quality / 100; | ||
| 800 | if (target_kb < 1) | ||
| 801 | target_kb = 1; | ||
| 804 | cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB, | 802 | cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB, |
| 805 | TRANSFER_WRITE, cam->params.vc_params.target_kb); | 803 | TRANSFER_WRITE, target_kb); |
| 806 | 804 | ||
| 807 | /* Wiggle VC Reset */ | 805 | /* Wiggle VC Reset */ |
| 808 | /*** | 806 | /*** |
| @@ -1538,23 +1536,17 @@ static int set_all_properties(struct camera_data *cam) | |||
| 1538 | * framerate and user_mode were already set (set_default_user_mode). | 1536 | * framerate and user_mode were already set (set_default_user_mode). |
| 1539 | **/ | 1537 | **/ |
| 1540 | 1538 | ||
| 1541 | cpia2_set_color_params(cam); | ||
| 1542 | |||
| 1543 | cpia2_usb_change_streaming_alternate(cam, | 1539 | cpia2_usb_change_streaming_alternate(cam, |
| 1544 | cam->params.camera_state.stream_mode); | 1540 | cam->params.camera_state.stream_mode); |
| 1545 | 1541 | ||
| 1546 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, | ||
| 1547 | cam->params.vp_params.user_effects); | ||
| 1548 | |||
| 1549 | cpia2_set_flicker_mode(cam, | ||
| 1550 | cam->params.flicker_control.flicker_mode_req); | ||
| 1551 | |||
| 1552 | cpia2_do_command(cam, | 1542 | cpia2_do_command(cam, |
| 1553 | CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, | 1543 | CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, |
| 1554 | TRANSFER_WRITE, cam->params.vp_params.gpio_direction); | 1544 | TRANSFER_WRITE, cam->params.vp_params.gpio_direction); |
| 1555 | cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE, | 1545 | cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE, |
| 1556 | cam->params.vp_params.gpio_data); | 1546 | cam->params.vp_params.gpio_data); |
| 1557 | 1547 | ||
| 1548 | v4l2_ctrl_handler_setup(&cam->hdl); | ||
| 1549 | |||
| 1558 | wake_system(cam); | 1550 | wake_system(cam); |
| 1559 | 1551 | ||
| 1560 | set_lowlight_boost(cam); | 1552 | set_lowlight_boost(cam); |
| @@ -1569,7 +1561,6 @@ static int set_all_properties(struct camera_data *cam) | |||
| 1569 | *****************************************************************************/ | 1561 | *****************************************************************************/ |
| 1570 | void cpia2_save_camera_state(struct camera_data *cam) | 1562 | void cpia2_save_camera_state(struct camera_data *cam) |
| 1571 | { | 1563 | { |
| 1572 | get_color_params(cam); | ||
| 1573 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0); | 1564 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0); |
| 1574 | cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ, | 1565 | cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ, |
| 1575 | 0); | 1566 | 0); |
| @@ -1577,30 +1568,6 @@ void cpia2_save_camera_state(struct camera_data *cam) | |||
| 1577 | /* Don't get framerate or target_kb. Trust the values we already have */ | 1568 | /* Don't get framerate or target_kb. Trust the values we already have */ |
| 1578 | } | 1569 | } |
| 1579 | 1570 | ||
| 1580 | /****************************************************************************** | ||
| 1581 | * | ||
| 1582 | * get_color_params | ||
| 1583 | * | ||
| 1584 | *****************************************************************************/ | ||
| 1585 | static void get_color_params(struct camera_data *cam) | ||
| 1586 | { | ||
| 1587 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, TRANSFER_READ, 0); | ||
| 1588 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, TRANSFER_READ, 0); | ||
| 1589 | cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, TRANSFER_READ, 0); | ||
| 1590 | } | ||
| 1591 | |||
| 1592 | /****************************************************************************** | ||
| 1593 | * | ||
| 1594 | * cpia2_set_color_params | ||
| 1595 | * | ||
| 1596 | *****************************************************************************/ | ||
| 1597 | void cpia2_set_color_params(struct camera_data *cam) | ||
| 1598 | { | ||
| 1599 | DBG("Setting color params\n"); | ||
| 1600 | cpia2_set_brightness(cam, cam->params.color_params.brightness); | ||
| 1601 | cpia2_set_contrast(cam, cam->params.color_params.contrast); | ||
| 1602 | cpia2_set_saturation(cam, cam->params.color_params.saturation); | ||
| 1603 | } | ||
| 1604 | 1571 | ||
| 1605 | /****************************************************************************** | 1572 | /****************************************************************************** |
| 1606 | * | 1573 | * |
| @@ -1664,15 +1631,9 @@ int cpia2_set_flicker_mode(struct camera_data *cam, int mode) | |||
| 1664 | 1631 | ||
| 1665 | switch(mode) { | 1632 | switch(mode) { |
| 1666 | case NEVER_FLICKER: | 1633 | case NEVER_FLICKER: |
| 1667 | cam->params.flicker_control.flicker_mode_req = mode; | ||
| 1668 | break; | ||
| 1669 | case FLICKER_60: | 1634 | case FLICKER_60: |
| 1670 | cam->params.flicker_control.flicker_mode_req = mode; | ||
| 1671 | cam->params.flicker_control.mains_frequency = 60; | ||
| 1672 | break; | ||
| 1673 | case FLICKER_50: | 1635 | case FLICKER_50: |
| 1674 | cam->params.flicker_control.flicker_mode_req = mode; | 1636 | cam->params.flicker_control.flicker_mode_req = mode; |
| 1675 | cam->params.flicker_control.mains_frequency = 50; | ||
| 1676 | break; | 1637 | break; |
| 1677 | default: | 1638 | default: |
| 1678 | err = -EINVAL; | 1639 | err = -EINVAL; |
| @@ -1701,6 +1662,7 @@ void cpia2_set_property_flip(struct camera_data *cam, int prop_val) | |||
| 1701 | { | 1662 | { |
| 1702 | cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP; | 1663 | cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP; |
| 1703 | } | 1664 | } |
| 1665 | cam->params.vp_params.user_effects = cam_reg; | ||
| 1704 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, | 1666 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, |
| 1705 | cam_reg); | 1667 | cam_reg); |
| 1706 | } | 1668 | } |
| @@ -1725,37 +1687,13 @@ void cpia2_set_property_mirror(struct camera_data *cam, int prop_val) | |||
| 1725 | { | 1687 | { |
| 1726 | cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR; | 1688 | cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR; |
| 1727 | } | 1689 | } |
| 1690 | cam->params.vp_params.user_effects = cam_reg; | ||
| 1728 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, | 1691 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, |
| 1729 | cam_reg); | 1692 | cam_reg); |
| 1730 | } | 1693 | } |
| 1731 | 1694 | ||
| 1732 | /****************************************************************************** | 1695 | /****************************************************************************** |
| 1733 | * | 1696 | * |
| 1734 | * set_target_kb | ||
| 1735 | * | ||
| 1736 | * The new Target KB is set in cam->params.vc_params.target_kb and | ||
| 1737 | * activates on reset. | ||
| 1738 | *****************************************************************************/ | ||
| 1739 | |||
| 1740 | int cpia2_set_target_kb(struct camera_data *cam, unsigned char value) | ||
| 1741 | { | ||
| 1742 | DBG("Requested target_kb = %d\n", value); | ||
| 1743 | if (value != cam->params.vc_params.target_kb) { | ||
| 1744 | |||
| 1745 | cpia2_usb_stream_pause(cam); | ||
| 1746 | |||
| 1747 | /* reset camera for new target_kb */ | ||
| 1748 | cam->params.vc_params.target_kb = value; | ||
| 1749 | cpia2_reset_camera(cam); | ||
| 1750 | |||
| 1751 | cpia2_usb_stream_resume(cam); | ||
| 1752 | } | ||
| 1753 | |||
| 1754 | return 0; | ||
| 1755 | } | ||
| 1756 | |||
| 1757 | /****************************************************************************** | ||
| 1758 | * | ||
| 1759 | * cpia2_set_gpio | 1697 | * cpia2_set_gpio |
| 1760 | * | 1698 | * |
| 1761 | *****************************************************************************/ | 1699 | *****************************************************************************/ |
| @@ -1843,7 +1781,7 @@ void cpia2_set_brightness(struct camera_data *cam, unsigned char value) | |||
| 1843 | if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0) | 1781 | if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0) |
| 1844 | value++; | 1782 | value++; |
| 1845 | DBG("Setting brightness to %d (0x%0x)\n", value, value); | 1783 | DBG("Setting brightness to %d (0x%0x)\n", value, value); |
| 1846 | cpia2_do_command(cam,CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE,value); | 1784 | cpia2_do_command(cam, CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE, value); |
| 1847 | } | 1785 | } |
| 1848 | 1786 | ||
| 1849 | /****************************************************************************** | 1787 | /****************************************************************************** |
| @@ -1854,7 +1792,6 @@ void cpia2_set_brightness(struct camera_data *cam, unsigned char value) | |||
| 1854 | void cpia2_set_contrast(struct camera_data *cam, unsigned char value) | 1792 | void cpia2_set_contrast(struct camera_data *cam, unsigned char value) |
| 1855 | { | 1793 | { |
| 1856 | DBG("Setting contrast to %d (0x%0x)\n", value, value); | 1794 | DBG("Setting contrast to %d (0x%0x)\n", value, value); |
| 1857 | cam->params.color_params.contrast = value; | ||
| 1858 | cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value); | 1795 | cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value); |
| 1859 | } | 1796 | } |
| 1860 | 1797 | ||
| @@ -1866,7 +1803,6 @@ void cpia2_set_contrast(struct camera_data *cam, unsigned char value) | |||
| 1866 | void cpia2_set_saturation(struct camera_data *cam, unsigned char value) | 1803 | void cpia2_set_saturation(struct camera_data *cam, unsigned char value) |
| 1867 | { | 1804 | { |
| 1868 | DBG("Setting saturation to %d (0x%0x)\n", value, value); | 1805 | DBG("Setting saturation to %d (0x%0x)\n", value, value); |
| 1869 | cam->params.color_params.saturation = value; | ||
| 1870 | cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value); | 1806 | cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value); |
| 1871 | } | 1807 | } |
| 1872 | 1808 | ||
| @@ -2168,14 +2104,10 @@ static void reset_camera_struct(struct camera_data *cam) | |||
| 2168 | /*** | 2104 | /*** |
| 2169 | * The following parameter values are the defaults from the register map. | 2105 | * The following parameter values are the defaults from the register map. |
| 2170 | ***/ | 2106 | ***/ |
| 2171 | cam->params.color_params.brightness = DEFAULT_BRIGHTNESS; | ||
| 2172 | cam->params.color_params.contrast = DEFAULT_CONTRAST; | ||
| 2173 | cam->params.color_params.saturation = DEFAULT_SATURATION; | ||
| 2174 | cam->params.vp_params.lowlight_boost = 0; | 2107 | cam->params.vp_params.lowlight_boost = 0; |
| 2175 | 2108 | ||
| 2176 | /* FlickerModes */ | 2109 | /* FlickerModes */ |
| 2177 | cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER; | 2110 | cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER; |
| 2178 | cam->params.flicker_control.mains_frequency = 60; | ||
| 2179 | 2111 | ||
| 2180 | /* jpeg params */ | 2112 | /* jpeg params */ |
| 2181 | cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT; | 2113 | cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT; |
| @@ -2188,7 +2120,7 @@ static void reset_camera_struct(struct camera_data *cam) | |||
| 2188 | cam->params.vp_params.gpio_data = 0; | 2120 | cam->params.vp_params.gpio_data = 0; |
| 2189 | 2121 | ||
| 2190 | /* Target kb params */ | 2122 | /* Target kb params */ |
| 2191 | cam->params.vc_params.target_kb = DEFAULT_TARGET_KB; | 2123 | cam->params.vc_params.quality = 100; |
| 2192 | 2124 | ||
| 2193 | /*** | 2125 | /*** |
| 2194 | * Set Sensor FPS as fast as possible. | 2126 | * Set Sensor FPS as fast as possible. |
| @@ -2228,7 +2160,7 @@ static void reset_camera_struct(struct camera_data *cam) | |||
| 2228 | * | 2160 | * |
| 2229 | * Initializes camera struct, does not call reset to fill in defaults. | 2161 | * Initializes camera struct, does not call reset to fill in defaults. |
| 2230 | *****************************************************************************/ | 2162 | *****************************************************************************/ |
| 2231 | struct camera_data *cpia2_init_camera_struct(void) | 2163 | struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf) |
| 2232 | { | 2164 | { |
| 2233 | struct camera_data *cam; | 2165 | struct camera_data *cam; |
| 2234 | 2166 | ||
| @@ -2239,8 +2171,13 @@ struct camera_data *cpia2_init_camera_struct(void) | |||
| 2239 | return NULL; | 2171 | return NULL; |
| 2240 | } | 2172 | } |
| 2241 | 2173 | ||
| 2174 | cam->v4l2_dev.release = cpia2_camera_release; | ||
| 2175 | if (v4l2_device_register(&intf->dev, &cam->v4l2_dev) < 0) { | ||
| 2176 | v4l2_err(&cam->v4l2_dev, "couldn't register v4l2_device\n"); | ||
| 2177 | kfree(cam); | ||
| 2178 | return NULL; | ||
| 2179 | } | ||
| 2242 | 2180 | ||
| 2243 | cam->present = 1; | ||
| 2244 | mutex_init(&cam->v4l2_lock); | 2181 | mutex_init(&cam->v4l2_lock); |
| 2245 | init_waitqueue_head(&cam->wq_stream); | 2182 | init_waitqueue_head(&cam->wq_stream); |
| 2246 | 2183 | ||
| @@ -2373,11 +2310,6 @@ long cpia2_read(struct camera_data *cam, | |||
| 2373 | return -EINVAL; | 2310 | return -EINVAL; |
| 2374 | } | 2311 | } |
| 2375 | 2312 | ||
| 2376 | if (!cam->present) { | ||
| 2377 | LOG("%s: camera removed\n",__func__); | ||
| 2378 | return 0; /* EOF */ | ||
| 2379 | } | ||
| 2380 | |||
| 2381 | if (!cam->streaming) { | 2313 | if (!cam->streaming) { |
| 2382 | /* Start streaming */ | 2314 | /* Start streaming */ |
| 2383 | cpia2_usb_stream_start(cam, | 2315 | cpia2_usb_stream_start(cam, |
| @@ -2393,12 +2325,12 @@ long cpia2_read(struct camera_data *cam, | |||
| 2393 | if (frame->status != FRAME_READY) { | 2325 | if (frame->status != FRAME_READY) { |
| 2394 | mutex_unlock(&cam->v4l2_lock); | 2326 | mutex_unlock(&cam->v4l2_lock); |
| 2395 | wait_event_interruptible(cam->wq_stream, | 2327 | wait_event_interruptible(cam->wq_stream, |
| 2396 | !cam->present || | 2328 | !video_is_registered(&cam->vdev) || |
| 2397 | (frame = cam->curbuff)->status == FRAME_READY); | 2329 | (frame = cam->curbuff)->status == FRAME_READY); |
| 2398 | mutex_lock(&cam->v4l2_lock); | 2330 | mutex_lock(&cam->v4l2_lock); |
| 2399 | if (signal_pending(current)) | 2331 | if (signal_pending(current)) |
| 2400 | return -ERESTARTSYS; | 2332 | return -ERESTARTSYS; |
| 2401 | if (!cam->present) | 2333 | if (!video_is_registered(&cam->vdev)) |
| 2402 | return 0; | 2334 | return 0; |
| 2403 | } | 2335 | } |
| 2404 | 2336 | ||
| @@ -2423,17 +2355,10 @@ long cpia2_read(struct camera_data *cam, | |||
| 2423 | unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, | 2355 | unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, |
| 2424 | poll_table *wait) | 2356 | poll_table *wait) |
| 2425 | { | 2357 | { |
| 2426 | unsigned int status=0; | 2358 | unsigned int status = v4l2_ctrl_poll(filp, wait); |
| 2427 | 2359 | ||
| 2428 | if (!cam) { | 2360 | if ((poll_requested_events(wait) & (POLLIN | POLLRDNORM)) && |
| 2429 | ERR("%s: Internal error, camera_data not found!\n",__func__); | 2361 | !cam->streaming) { |
| 2430 | return POLLERR; | ||
| 2431 | } | ||
| 2432 | |||
| 2433 | if (!cam->present) | ||
| 2434 | return POLLHUP; | ||
| 2435 | |||
| 2436 | if(!cam->streaming) { | ||
| 2437 | /* Start streaming */ | 2362 | /* Start streaming */ |
| 2438 | cpia2_usb_stream_start(cam, | 2363 | cpia2_usb_stream_start(cam, |
| 2439 | cam->params.camera_state.stream_mode); | 2364 | cam->params.camera_state.stream_mode); |
| @@ -2441,10 +2366,8 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, | |||
| 2441 | 2366 | ||
| 2442 | poll_wait(filp, &cam->wq_stream, wait); | 2367 | poll_wait(filp, &cam->wq_stream, wait); |
| 2443 | 2368 | ||
| 2444 | if(!cam->present) | 2369 | if (cam->curbuff->status == FRAME_READY) |
| 2445 | status = POLLHUP; | 2370 | status |= POLLIN | POLLRDNORM; |
| 2446 | else if(cam->curbuff->status == FRAME_READY) | ||
| 2447 | status = POLLIN | POLLRDNORM; | ||
| 2448 | 2371 | ||
| 2449 | return status; | 2372 | return status; |
| 2450 | } | 2373 | } |
| @@ -2462,12 +2385,9 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma) | |||
| 2462 | unsigned long start = (unsigned long) adr; | 2385 | unsigned long start = (unsigned long) adr; |
| 2463 | unsigned long page, pos; | 2386 | unsigned long page, pos; |
| 2464 | 2387 | ||
| 2465 | if (!cam) | ||
| 2466 | return -ENODEV; | ||
| 2467 | |||
| 2468 | DBG("mmap offset:%ld size:%ld\n", start_offset, size); | 2388 | DBG("mmap offset:%ld size:%ld\n", start_offset, size); |
| 2469 | 2389 | ||
| 2470 | if (!cam->present) | 2390 | if (!video_is_registered(&cam->vdev)) |
| 2471 | return -ENODEV; | 2391 | return -ENODEV; |
| 2472 | 2392 | ||
| 2473 | if (size > cam->frame_size*cam->num_frames || | 2393 | if (size > cam->frame_size*cam->num_frames || |
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c index 59c797c1527..95b5d6e7cdc 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 | * |
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 077eb1db80a..bb4f1d0de82 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
| @@ -39,15 +39,15 @@ | |||
| 39 | #include <linux/videodev2.h> | 39 | #include <linux/videodev2.h> |
| 40 | #include <linux/stringify.h> | 40 | #include <linux/stringify.h> |
| 41 | #include <media/v4l2-ioctl.h> | 41 | #include <media/v4l2-ioctl.h> |
| 42 | #include <media/v4l2-event.h> | ||
| 42 | 43 | ||
| 43 | #include "cpia2.h" | 44 | #include "cpia2.h" |
| 44 | #include "cpia2dev.h" | ||
| 45 | 45 | ||
| 46 | static int video_nr = -1; | 46 | static int video_nr = -1; |
| 47 | module_param(video_nr, int, 0); | 47 | module_param(video_nr, int, 0); |
| 48 | MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)"); | 48 | MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)"); |
| 49 | 49 | ||
| 50 | static int buffer_size = 68*1024; | 50 | static int buffer_size = 68 * 1024; |
| 51 | module_param(buffer_size, int, 0); | 51 | module_param(buffer_size, int, 0); |
| 52 | MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)"); | 52 | MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)"); |
| 53 | 53 | ||
| @@ -62,18 +62,10 @@ MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-" | |||
| 62 | __stringify(USBIF_ISO_6) ", default " | 62 | __stringify(USBIF_ISO_6) ", default " |
| 63 | __stringify(DEFAULT_ALT) ")"); | 63 | __stringify(DEFAULT_ALT) ")"); |
| 64 | 64 | ||
| 65 | static int flicker_freq = 60; | 65 | static int flicker_mode; |
| 66 | module_param(flicker_freq, int, 0); | ||
| 67 | MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" __stringify(50) "or" | ||
| 68 | __stringify(60) ", default " | ||
| 69 | __stringify(60) ")"); | ||
| 70 | |||
| 71 | static int flicker_mode = NEVER_FLICKER; | ||
| 72 | module_param(flicker_mode, int, 0); | 66 | module_param(flicker_mode, int, 0); |
| 73 | MODULE_PARM_DESC(flicker_mode, | 67 | MODULE_PARM_DESC(flicker_mode, "Flicker frequency (0 (disabled), " __stringify(50) " or " |
| 74 | "Flicker supression (" __stringify(NEVER_FLICKER) "or" | 68 | __stringify(60) ", default 0)"); |
| 75 | __stringify(ANTI_FLICKER_ON) ", default " | ||
| 76 | __stringify(NEVER_FLICKER) ")"); | ||
| 77 | 69 | ||
| 78 | MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>"); | 70 | MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>"); |
| 79 | MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); | 71 | MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); |
| @@ -82,153 +74,7 @@ MODULE_LICENSE("GPL"); | |||
| 82 | MODULE_VERSION(CPIA_VERSION); | 74 | MODULE_VERSION(CPIA_VERSION); |
| 83 | 75 | ||
| 84 | #define ABOUT "V4L-Driver for Vision CPiA2 based cameras" | 76 | #define ABOUT "V4L-Driver for Vision CPiA2 based cameras" |
| 85 | 77 | #define CPIA2_CID_USB_ALT (V4L2_CID_USER_BASE | 0xf000) | |
| 86 | struct control_menu_info { | ||
| 87 | int value; | ||
| 88 | char name[32]; | ||
| 89 | }; | ||
| 90 | |||
| 91 | static struct control_menu_info framerate_controls[] = | ||
| 92 | { | ||
| 93 | { CPIA2_VP_FRAMERATE_6_25, "6.25 fps" }, | ||
| 94 | { CPIA2_VP_FRAMERATE_7_5, "7.5 fps" }, | ||
| 95 | { CPIA2_VP_FRAMERATE_12_5, "12.5 fps" }, | ||
| 96 | { CPIA2_VP_FRAMERATE_15, "15 fps" }, | ||
| 97 | { CPIA2_VP_FRAMERATE_25, "25 fps" }, | ||
| 98 | { CPIA2_VP_FRAMERATE_30, "30 fps" }, | ||
| 99 | }; | ||
| 100 | #define NUM_FRAMERATE_CONTROLS (ARRAY_SIZE(framerate_controls)) | ||
| 101 | |||
| 102 | static struct control_menu_info flicker_controls[] = | ||
| 103 | { | ||
| 104 | { NEVER_FLICKER, "Off" }, | ||
| 105 | { FLICKER_50, "50 Hz" }, | ||
| 106 | { FLICKER_60, "60 Hz" }, | ||
| 107 | }; | ||
| 108 | #define NUM_FLICKER_CONTROLS (ARRAY_SIZE(flicker_controls)) | ||
| 109 | |||
| 110 | static struct control_menu_info lights_controls[] = | ||
| 111 | { | ||
| 112 | { 0, "Off" }, | ||
| 113 | { 64, "Top" }, | ||
| 114 | { 128, "Bottom" }, | ||
| 115 | { 192, "Both" }, | ||
| 116 | }; | ||
| 117 | #define NUM_LIGHTS_CONTROLS (ARRAY_SIZE(lights_controls)) | ||
| 118 | #define GPIO_LIGHTS_MASK 192 | ||
| 119 | |||
| 120 | static struct v4l2_queryctrl controls[] = { | ||
| 121 | { | ||
| 122 | .id = V4L2_CID_BRIGHTNESS, | ||
| 123 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 124 | .name = "Brightness", | ||
| 125 | .minimum = 0, | ||
| 126 | .maximum = 255, | ||
| 127 | .step = 1, | ||
| 128 | .default_value = DEFAULT_BRIGHTNESS, | ||
| 129 | }, | ||
| 130 | { | ||
| 131 | .id = V4L2_CID_CONTRAST, | ||
| 132 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 133 | .name = "Contrast", | ||
| 134 | .minimum = 0, | ||
| 135 | .maximum = 255, | ||
| 136 | .step = 1, | ||
| 137 | .default_value = DEFAULT_CONTRAST, | ||
| 138 | }, | ||
| 139 | { | ||
| 140 | .id = V4L2_CID_SATURATION, | ||
| 141 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 142 | .name = "Saturation", | ||
| 143 | .minimum = 0, | ||
| 144 | .maximum = 255, | ||
| 145 | .step = 1, | ||
| 146 | .default_value = DEFAULT_SATURATION, | ||
| 147 | }, | ||
| 148 | { | ||
| 149 | .id = V4L2_CID_HFLIP, | ||
| 150 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
| 151 | .name = "Mirror Horizontally", | ||
| 152 | .minimum = 0, | ||
| 153 | .maximum = 1, | ||
| 154 | .step = 1, | ||
| 155 | .default_value = 0, | ||
| 156 | }, | ||
| 157 | { | ||
| 158 | .id = V4L2_CID_VFLIP, | ||
| 159 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
| 160 | .name = "Flip Vertically", | ||
| 161 | .minimum = 0, | ||
| 162 | .maximum = 1, | ||
| 163 | .step = 1, | ||
| 164 | .default_value = 0, | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | .id = CPIA2_CID_TARGET_KB, | ||
| 168 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 169 | .name = "Target KB", | ||
| 170 | .minimum = 0, | ||
| 171 | .maximum = 255, | ||
| 172 | .step = 1, | ||
| 173 | .default_value = DEFAULT_TARGET_KB, | ||
| 174 | }, | ||
| 175 | { | ||
| 176 | .id = CPIA2_CID_GPIO, | ||
| 177 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 178 | .name = "GPIO", | ||
| 179 | .minimum = 0, | ||
| 180 | .maximum = 255, | ||
| 181 | .step = 1, | ||
| 182 | .default_value = 0, | ||
| 183 | }, | ||
| 184 | { | ||
| 185 | .id = CPIA2_CID_FLICKER_MODE, | ||
| 186 | .type = V4L2_CTRL_TYPE_MENU, | ||
| 187 | .name = "Flicker Reduction", | ||
| 188 | .minimum = 0, | ||
| 189 | .maximum = NUM_FLICKER_CONTROLS-1, | ||
| 190 | .step = 1, | ||
| 191 | .default_value = 0, | ||
| 192 | }, | ||
| 193 | { | ||
| 194 | .id = CPIA2_CID_FRAMERATE, | ||
| 195 | .type = V4L2_CTRL_TYPE_MENU, | ||
| 196 | .name = "Framerate", | ||
| 197 | .minimum = 0, | ||
| 198 | .maximum = NUM_FRAMERATE_CONTROLS-1, | ||
| 199 | .step = 1, | ||
| 200 | .default_value = NUM_FRAMERATE_CONTROLS-1, | ||
| 201 | }, | ||
| 202 | { | ||
| 203 | .id = CPIA2_CID_USB_ALT, | ||
| 204 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 205 | .name = "USB Alternate", | ||
| 206 | .minimum = USBIF_ISO_1, | ||
| 207 | .maximum = USBIF_ISO_6, | ||
| 208 | .step = 1, | ||
| 209 | .default_value = DEFAULT_ALT, | ||
| 210 | }, | ||
| 211 | { | ||
| 212 | .id = CPIA2_CID_LIGHTS, | ||
| 213 | .type = V4L2_CTRL_TYPE_MENU, | ||
| 214 | .name = "Lights", | ||
| 215 | .minimum = 0, | ||
| 216 | .maximum = NUM_LIGHTS_CONTROLS-1, | ||
| 217 | .step = 1, | ||
| 218 | .default_value = 0, | ||
| 219 | }, | ||
| 220 | { | ||
| 221 | .id = CPIA2_CID_RESET_CAMERA, | ||
| 222 | .type = V4L2_CTRL_TYPE_BUTTON, | ||
| 223 | .name = "Reset Camera", | ||
| 224 | .minimum = 0, | ||
| 225 | .maximum = 0, | ||
| 226 | .step = 0, | ||
| 227 | .default_value = 0, | ||
| 228 | }, | ||
| 229 | }; | ||
| 230 | #define NUM_CONTROLS (ARRAY_SIZE(controls)) | ||
| 231 | |||
| 232 | 78 | ||
| 233 | /****************************************************************************** | 79 | /****************************************************************************** |
| 234 | * | 80 | * |
| @@ -238,38 +84,27 @@ static struct v4l2_queryctrl controls[] = { | |||
| 238 | static int cpia2_open(struct file *file) | 84 | static int cpia2_open(struct file *file) |
| 239 | { | 85 | { |
| 240 | struct camera_data *cam = video_drvdata(file); | 86 | struct camera_data *cam = video_drvdata(file); |
| 241 | struct cpia2_fh *fh; | 87 | int retval = v4l2_fh_open(file); |
| 242 | |||
| 243 | if (!cam) { | ||
| 244 | ERR("Internal error, camera_data not found!\n"); | ||
| 245 | return -ENODEV; | ||
| 246 | } | ||
| 247 | 88 | ||
| 248 | if (!cam->present) | 89 | if (retval) |
| 249 | return -ENODEV; | 90 | return retval; |
| 250 | 91 | ||
| 251 | if (cam->open_count == 0) { | 92 | if (v4l2_fh_is_singular_file(file)) { |
| 252 | if (cpia2_allocate_buffers(cam)) | 93 | if (cpia2_allocate_buffers(cam)) { |
| 94 | v4l2_fh_release(file); | ||
| 253 | return -ENOMEM; | 95 | return -ENOMEM; |
| 96 | } | ||
| 254 | 97 | ||
| 255 | /* reset the camera */ | 98 | /* reset the camera */ |
| 256 | if (cpia2_reset_camera(cam) < 0) | 99 | if (cpia2_reset_camera(cam) < 0) { |
| 100 | v4l2_fh_release(file); | ||
| 257 | return -EIO; | 101 | return -EIO; |
| 102 | } | ||
| 258 | 103 | ||
| 259 | cam->APP_len = 0; | 104 | cam->APP_len = 0; |
| 260 | cam->COM_len = 0; | 105 | cam->COM_len = 0; |
| 261 | } | 106 | } |
| 262 | 107 | ||
| 263 | fh = kmalloc(sizeof(*fh), GFP_KERNEL); | ||
| 264 | if (!fh) | ||
| 265 | return -ENOMEM; | ||
| 266 | file->private_data = fh; | ||
| 267 | fh->prio = V4L2_PRIORITY_UNSET; | ||
| 268 | v4l2_prio_open(&cam->prio, &fh->prio); | ||
| 269 | fh->mmapped = 0; | ||
| 270 | |||
| 271 | ++cam->open_count; | ||
| 272 | |||
| 273 | cpia2_dbg_dump_registers(cam); | 108 | cpia2_dbg_dump_registers(cam); |
| 274 | return 0; | 109 | return 0; |
| 275 | } | 110 | } |
| @@ -283,37 +118,22 @@ static int cpia2_close(struct file *file) | |||
| 283 | { | 118 | { |
| 284 | struct video_device *dev = video_devdata(file); | 119 | struct video_device *dev = video_devdata(file); |
| 285 | struct camera_data *cam = video_get_drvdata(dev); | 120 | struct camera_data *cam = video_get_drvdata(dev); |
| 286 | struct cpia2_fh *fh = file->private_data; | ||
| 287 | 121 | ||
| 288 | if (cam->present && | 122 | if (video_is_registered(&cam->vdev) && v4l2_fh_is_singular_file(file)) { |
| 289 | (cam->open_count == 1 || fh->prio == V4L2_PRIORITY_RECORD)) { | ||
| 290 | cpia2_usb_stream_stop(cam); | 123 | cpia2_usb_stream_stop(cam); |
| 291 | 124 | ||
| 292 | if (cam->open_count == 1) { | 125 | /* save camera state for later open */ |
| 293 | /* save camera state for later open */ | 126 | cpia2_save_camera_state(cam); |
| 294 | cpia2_save_camera_state(cam); | ||
| 295 | 127 | ||
| 296 | cpia2_set_low_power(cam); | 128 | cpia2_set_low_power(cam); |
| 297 | cpia2_free_buffers(cam); | 129 | cpia2_free_buffers(cam); |
| 298 | } | ||
| 299 | } | 130 | } |
| 300 | 131 | ||
| 301 | if (fh->mmapped) | 132 | if (cam->stream_fh == file->private_data) { |
| 133 | cam->stream_fh = NULL; | ||
| 302 | cam->mmapped = 0; | 134 | cam->mmapped = 0; |
| 303 | v4l2_prio_close(&cam->prio, fh->prio); | ||
| 304 | file->private_data = NULL; | ||
| 305 | kfree(fh); | ||
| 306 | |||
| 307 | if (--cam->open_count == 0) { | ||
| 308 | cpia2_free_buffers(cam); | ||
| 309 | if (!cam->present) { | ||
| 310 | video_unregister_device(dev); | ||
| 311 | kfree(cam); | ||
| 312 | return 0; | ||
| 313 | } | ||
| 314 | } | 135 | } |
| 315 | 136 | return v4l2_fh_release(file); | |
| 316 | return 0; | ||
| 317 | } | 137 | } |
| 318 | 138 | ||
| 319 | /****************************************************************************** | 139 | /****************************************************************************** |
| @@ -327,16 +147,9 @@ static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count, | |||
| 327 | struct camera_data *cam = video_drvdata(file); | 147 | struct camera_data *cam = video_drvdata(file); |
| 328 | int noblock = file->f_flags&O_NONBLOCK; | 148 | int noblock = file->f_flags&O_NONBLOCK; |
| 329 | 149 | ||
| 330 | struct cpia2_fh *fh = file->private_data; | ||
| 331 | |||
| 332 | if(!cam) | 150 | if(!cam) |
| 333 | return -EINVAL; | 151 | return -EINVAL; |
| 334 | 152 | ||
| 335 | /* Priority check */ | ||
| 336 | if(fh->prio != V4L2_PRIORITY_RECORD) { | ||
| 337 | return -EBUSY; | ||
| 338 | } | ||
| 339 | |||
| 340 | return cpia2_read(cam, buf, count, noblock); | 153 | return cpia2_read(cam, buf, count, noblock); |
| 341 | } | 154 | } |
| 342 | 155 | ||
| @@ -349,15 +162,6 @@ static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count, | |||
| 349 | static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait) | 162 | static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait) |
| 350 | { | 163 | { |
| 351 | struct camera_data *cam = video_drvdata(filp); | 164 | struct camera_data *cam = video_drvdata(filp); |
| 352 | struct cpia2_fh *fh = filp->private_data; | ||
| 353 | |||
| 354 | if(!cam) | ||
| 355 | return POLLERR; | ||
| 356 | |||
| 357 | /* Priority check */ | ||
| 358 | if(fh->prio != V4L2_PRIORITY_RECORD) { | ||
| 359 | return POLLERR; | ||
| 360 | } | ||
| 361 | 165 | ||
| 362 | return cpia2_poll(cam, filp, wait); | 166 | return cpia2_poll(cam, filp, wait); |
| 363 | } | 167 | } |
| @@ -384,36 +188,13 @@ static int sync(struct camera_data *cam, int frame_nr) | |||
| 384 | mutex_lock(&cam->v4l2_lock); | 188 | mutex_lock(&cam->v4l2_lock); |
| 385 | if (signal_pending(current)) | 189 | if (signal_pending(current)) |
| 386 | return -ERESTARTSYS; | 190 | return -ERESTARTSYS; |
| 387 | if(!cam->present) | 191 | if (!video_is_registered(&cam->vdev)) |
| 388 | return -ENOTTY; | 192 | return -ENOTTY; |
| 389 | } | 193 | } |
| 390 | } | 194 | } |
| 391 | 195 | ||
| 392 | /****************************************************************************** | 196 | /****************************************************************************** |
| 393 | * | 197 | * |
| 394 | * ioctl_set_gpio | ||
| 395 | * | ||
| 396 | *****************************************************************************/ | ||
| 397 | |||
| 398 | static long cpia2_default(struct file *file, void *fh, bool valid_prio, | ||
| 399 | int cmd, void *arg) | ||
| 400 | { | ||
| 401 | struct camera_data *cam = video_drvdata(file); | ||
| 402 | __u32 gpio_val; | ||
| 403 | |||
| 404 | if (cmd != CPIA2_CID_GPIO) | ||
| 405 | return -EINVAL; | ||
| 406 | |||
| 407 | gpio_val = *(__u32*) arg; | ||
| 408 | |||
| 409 | if (gpio_val &~ 0xFFU) | ||
| 410 | return -EINVAL; | ||
| 411 | |||
| 412 | return cpia2_set_gpio(cam, (unsigned char)gpio_val); | ||
| 413 | } | ||
| 414 | |||
| 415 | /****************************************************************************** | ||
| 416 | * | ||
| 417 | * ioctl_querycap | 198 | * ioctl_querycap |
| 418 | * | 199 | * |
| 419 | * V4L2 device capabilities | 200 | * V4L2 device capabilities |
| @@ -465,9 +246,11 @@ static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *v | |||
| 465 | if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0) | 246 | if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0) |
| 466 | memset(vc->bus_info,0, sizeof(vc->bus_info)); | 247 | memset(vc->bus_info,0, sizeof(vc->bus_info)); |
| 467 | 248 | ||
| 468 | vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | | 249 | vc->device_caps = V4L2_CAP_VIDEO_CAPTURE | |
| 469 | V4L2_CAP_READWRITE | | 250 | V4L2_CAP_READWRITE | |
| 470 | V4L2_CAP_STREAMING; | 251 | V4L2_CAP_STREAMING; |
| 252 | vc->capabilities = vc->device_caps | | ||
| 253 | V4L2_CAP_DEVICE_CAPS; | ||
| 471 | 254 | ||
| 472 | return 0; | 255 | return 0; |
| 473 | } | 256 | } |
| @@ -610,22 +393,12 @@ static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh, | |||
| 610 | struct v4l2_format *f) | 393 | struct v4l2_format *f) |
| 611 | { | 394 | { |
| 612 | struct camera_data *cam = video_drvdata(file); | 395 | struct camera_data *cam = video_drvdata(file); |
| 613 | struct cpia2_fh *fh = _fh; | ||
| 614 | int err, frame; | 396 | int err, frame; |
| 615 | 397 | ||
| 616 | err = v4l2_prio_check(&cam->prio, fh->prio); | ||
| 617 | if (err) | ||
| 618 | return err; | ||
| 619 | err = cpia2_try_fmt_vid_cap(file, _fh, f); | 398 | err = cpia2_try_fmt_vid_cap(file, _fh, f); |
| 620 | if(err != 0) | 399 | if(err != 0) |
| 621 | return err; | 400 | return err; |
| 622 | 401 | ||
| 623 | /* Ensure that only this process can change the format. */ | ||
| 624 | err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD); | ||
| 625 | if(err != 0) { | ||
| 626 | return err; | ||
| 627 | } | ||
| 628 | |||
| 629 | cam->pixelformat = f->fmt.pix.pixelformat; | 402 | cam->pixelformat = f->fmt.pix.pixelformat; |
| 630 | 403 | ||
| 631 | /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle | 404 | /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle |
| @@ -713,240 +486,126 @@ static int cpia2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *c) | |||
| 713 | return 0; | 486 | return 0; |
| 714 | } | 487 | } |
| 715 | 488 | ||
| 716 | /****************************************************************************** | 489 | struct framerate_info { |
| 717 | * | 490 | int value; |
| 718 | * ioctl_queryctrl | 491 | struct v4l2_fract period; |
| 719 | * | 492 | }; |
| 720 | * V4L2 query possible control variables | ||
| 721 | * | ||
| 722 | *****************************************************************************/ | ||
| 723 | 493 | ||
| 724 | static int cpia2_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) | 494 | static const struct framerate_info framerate_controls[] = { |
| 495 | { CPIA2_VP_FRAMERATE_6_25, { 4, 25 } }, | ||
| 496 | { CPIA2_VP_FRAMERATE_7_5, { 2, 15 } }, | ||
| 497 | { CPIA2_VP_FRAMERATE_12_5, { 2, 25 } }, | ||
| 498 | { CPIA2_VP_FRAMERATE_15, { 1, 15 } }, | ||
| 499 | { CPIA2_VP_FRAMERATE_25, { 1, 25 } }, | ||
| 500 | { CPIA2_VP_FRAMERATE_30, { 1, 30 } }, | ||
| 501 | }; | ||
| 502 | |||
| 503 | static int cpia2_g_parm(struct file *file, void *fh, struct v4l2_streamparm *p) | ||
| 725 | { | 504 | { |
| 726 | struct camera_data *cam = video_drvdata(file); | 505 | struct camera_data *cam = video_drvdata(file); |
| 506 | struct v4l2_captureparm *cap = &p->parm.capture; | ||
| 727 | int i; | 507 | int i; |
| 728 | 508 | ||
| 729 | for(i=0; i<NUM_CONTROLS; ++i) { | 509 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 730 | if(c->id == controls[i].id) { | ||
| 731 | memcpy(c, controls+i, sizeof(*c)); | ||
| 732 | break; | ||
| 733 | } | ||
| 734 | } | ||
| 735 | |||
| 736 | if(i == NUM_CONTROLS) | ||
| 737 | return -EINVAL; | 510 | return -EINVAL; |
| 738 | 511 | ||
| 739 | /* Some devices have additional limitations */ | 512 | cap->capability = V4L2_CAP_TIMEPERFRAME; |
| 740 | switch(c->id) { | 513 | cap->readbuffers = cam->num_frames; |
| 741 | case V4L2_CID_BRIGHTNESS: | 514 | for (i = 0; i < ARRAY_SIZE(framerate_controls); i++) |
| 742 | /*** | 515 | if (cam->params.vp_params.frame_rate == framerate_controls[i].value) { |
| 743 | * Don't let the register be set to zero - bug in VP4 | 516 | cap->timeperframe = framerate_controls[i].period; |
| 744 | * flash of full brightness | 517 | break; |
| 745 | ***/ | ||
| 746 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) | ||
| 747 | c->minimum = 1; | ||
| 748 | break; | ||
| 749 | case V4L2_CID_VFLIP: | ||
| 750 | // VP5 Only | ||
| 751 | if(cam->params.pnp_id.device_type == DEVICE_STV_672) | ||
| 752 | c->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
| 753 | break; | ||
| 754 | case CPIA2_CID_FRAMERATE: | ||
| 755 | if(cam->params.pnp_id.device_type == DEVICE_STV_672 && | ||
| 756 | cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){ | ||
| 757 | // Maximum 15fps | ||
| 758 | for(i=0; i<c->maximum; ++i) { | ||
| 759 | if(framerate_controls[i].value == | ||
| 760 | CPIA2_VP_FRAMERATE_15) { | ||
| 761 | c->maximum = i; | ||
| 762 | c->default_value = i; | ||
| 763 | } | ||
| 764 | } | ||
| 765 | } | 518 | } |
| 766 | break; | ||
| 767 | case CPIA2_CID_FLICKER_MODE: | ||
| 768 | // Flicker control only valid for 672. | ||
| 769 | if(cam->params.pnp_id.device_type != DEVICE_STV_672) | ||
| 770 | c->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
| 771 | break; | ||
| 772 | case CPIA2_CID_LIGHTS: | ||
| 773 | // Light control only valid for the QX5 Microscope. | ||
| 774 | if(cam->params.pnp_id.product != 0x151) | ||
| 775 | c->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
| 776 | break; | ||
| 777 | default: | ||
| 778 | break; | ||
| 779 | } | ||
| 780 | |||
| 781 | return 0; | 519 | return 0; |
| 782 | } | 520 | } |
| 783 | 521 | ||
| 784 | /****************************************************************************** | 522 | static int cpia2_s_parm(struct file *file, void *fh, struct v4l2_streamparm *p) |
| 785 | * | ||
| 786 | * ioctl_querymenu | ||
| 787 | * | ||
| 788 | * V4L2 query possible control variables | ||
| 789 | * | ||
| 790 | *****************************************************************************/ | ||
| 791 | |||
| 792 | static int cpia2_querymenu(struct file *file, void *fh, struct v4l2_querymenu *m) | ||
| 793 | { | 523 | { |
| 794 | struct camera_data *cam = video_drvdata(file); | 524 | struct camera_data *cam = video_drvdata(file); |
| 525 | struct v4l2_captureparm *cap = &p->parm.capture; | ||
| 526 | struct v4l2_fract tpf = cap->timeperframe; | ||
| 527 | int max = ARRAY_SIZE(framerate_controls) - 1; | ||
| 528 | int ret; | ||
| 529 | int i; | ||
| 795 | 530 | ||
| 796 | switch(m->id) { | 531 | ret = cpia2_g_parm(file, fh, p); |
| 797 | case CPIA2_CID_FLICKER_MODE: | 532 | if (ret || !tpf.denominator || !tpf.numerator) |
| 798 | if (m->index >= NUM_FLICKER_CONTROLS) | 533 | return ret; |
| 799 | return -EINVAL; | 534 | |
| 535 | /* Maximum 15 fps for this model */ | ||
| 536 | if (cam->params.pnp_id.device_type == DEVICE_STV_672 && | ||
| 537 | cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) | ||
| 538 | max -= 2; | ||
| 539 | for (i = 0; i <= max; i++) { | ||
| 540 | struct v4l2_fract f1 = tpf; | ||
| 541 | struct v4l2_fract f2 = framerate_controls[i].period; | ||
| 542 | |||
| 543 | f1.numerator *= f2.denominator; | ||
| 544 | f2.numerator *= f1.denominator; | ||
| 545 | if (f1.numerator >= f2.numerator) | ||
| 546 | break; | ||
| 547 | } | ||
| 548 | if (i > max) | ||
| 549 | i = max; | ||
| 550 | cap->timeperframe = framerate_controls[i].period; | ||
| 551 | return cpia2_set_fps(cam, framerate_controls[i].value); | ||
| 552 | } | ||
| 800 | 553 | ||
| 801 | strcpy(m->name, flicker_controls[m->index].name); | 554 | static const struct { |
| 802 | break; | 555 | u32 width; |
| 803 | case CPIA2_CID_FRAMERATE: | 556 | u32 height; |
| 804 | { | 557 | } cpia2_framesizes[] = { |
| 805 | int maximum = NUM_FRAMERATE_CONTROLS - 1; | 558 | { 640, 480 }, |
| 806 | if(cam->params.pnp_id.device_type == DEVICE_STV_672 && | 559 | { 352, 288 }, |
| 807 | cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){ | 560 | { 320, 240 }, |
| 808 | // Maximum 15fps | 561 | { 288, 216 }, |
| 809 | int i; | 562 | { 256, 192 }, |
| 810 | for(i=0; i<maximum; ++i) { | 563 | { 224, 168 }, |
| 811 | if(framerate_controls[i].value == | 564 | { 192, 144 }, |
| 812 | CPIA2_VP_FRAMERATE_15) | 565 | { 176, 144 }, |
| 813 | maximum = i; | 566 | }; |
| 814 | } | ||
| 815 | } | ||
| 816 | if (m->index > maximum) | ||
| 817 | return -EINVAL; | ||
| 818 | 567 | ||
| 819 | strcpy(m->name, framerate_controls[m->index].name); | 568 | static int cpia2_enum_framesizes(struct file *file, void *fh, |
| 820 | break; | 569 | struct v4l2_frmsizeenum *fsize) |
| 821 | } | 570 | { |
| 822 | case CPIA2_CID_LIGHTS: | ||
| 823 | if (m->index >= NUM_LIGHTS_CONTROLS) | ||
| 824 | return -EINVAL; | ||
| 825 | 571 | ||
| 826 | strcpy(m->name, lights_controls[m->index].name); | 572 | if (fsize->pixel_format != V4L2_PIX_FMT_MJPEG && |
| 827 | break; | 573 | fsize->pixel_format != V4L2_PIX_FMT_JPEG) |
| 828 | default: | ||
| 829 | return -EINVAL; | 574 | return -EINVAL; |
| 830 | } | 575 | if (fsize->index >= ARRAY_SIZE(cpia2_framesizes)) |
| 576 | return -EINVAL; | ||
| 577 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
| 578 | fsize->discrete.width = cpia2_framesizes[fsize->index].width; | ||
| 579 | fsize->discrete.height = cpia2_framesizes[fsize->index].height; | ||
| 831 | 580 | ||
| 832 | return 0; | 581 | return 0; |
| 833 | } | 582 | } |
| 834 | 583 | ||
| 835 | /****************************************************************************** | 584 | static int cpia2_enum_frameintervals(struct file *file, void *fh, |
| 836 | * | 585 | struct v4l2_frmivalenum *fival) |
| 837 | * ioctl_g_ctrl | ||
| 838 | * | ||
| 839 | * V4L2 get the value of a control variable | ||
| 840 | * | ||
| 841 | *****************************************************************************/ | ||
| 842 | |||
| 843 | static int cpia2_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) | ||
| 844 | { | 586 | { |
| 845 | struct camera_data *cam = video_drvdata(file); | 587 | struct camera_data *cam = video_drvdata(file); |
| 588 | int max = ARRAY_SIZE(framerate_controls) - 1; | ||
| 589 | int i; | ||
| 846 | 590 | ||
| 847 | switch(c->id) { | 591 | if (fival->pixel_format != V4L2_PIX_FMT_MJPEG && |
| 848 | case V4L2_CID_BRIGHTNESS: | 592 | fival->pixel_format != V4L2_PIX_FMT_JPEG) |
| 849 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, | ||
| 850 | TRANSFER_READ, 0); | ||
| 851 | c->value = cam->params.color_params.brightness; | ||
| 852 | break; | ||
| 853 | case V4L2_CID_CONTRAST: | ||
| 854 | cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, | ||
| 855 | TRANSFER_READ, 0); | ||
| 856 | c->value = cam->params.color_params.contrast; | ||
| 857 | break; | ||
| 858 | case V4L2_CID_SATURATION: | ||
| 859 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, | ||
| 860 | TRANSFER_READ, 0); | ||
| 861 | c->value = cam->params.color_params.saturation; | ||
| 862 | break; | ||
| 863 | case V4L2_CID_HFLIP: | ||
| 864 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, | ||
| 865 | TRANSFER_READ, 0); | ||
| 866 | c->value = (cam->params.vp_params.user_effects & | ||
| 867 | CPIA2_VP_USER_EFFECTS_MIRROR) != 0; | ||
| 868 | break; | ||
| 869 | case V4L2_CID_VFLIP: | ||
| 870 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, | ||
| 871 | TRANSFER_READ, 0); | ||
| 872 | c->value = (cam->params.vp_params.user_effects & | ||
| 873 | CPIA2_VP_USER_EFFECTS_FLIP) != 0; | ||
| 874 | break; | ||
| 875 | case CPIA2_CID_TARGET_KB: | ||
| 876 | c->value = cam->params.vc_params.target_kb; | ||
| 877 | break; | ||
| 878 | case CPIA2_CID_GPIO: | ||
| 879 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA, | ||
| 880 | TRANSFER_READ, 0); | ||
| 881 | c->value = cam->params.vp_params.gpio_data; | ||
| 882 | break; | ||
| 883 | case CPIA2_CID_FLICKER_MODE: | ||
| 884 | { | ||
| 885 | int i, mode; | ||
| 886 | cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES, | ||
| 887 | TRANSFER_READ, 0); | ||
| 888 | if(cam->params.flicker_control.cam_register & | ||
| 889 | CPIA2_VP_FLICKER_MODES_NEVER_FLICKER) { | ||
| 890 | mode = NEVER_FLICKER; | ||
| 891 | } else { | ||
| 892 | if(cam->params.flicker_control.cam_register & | ||
| 893 | CPIA2_VP_FLICKER_MODES_50HZ) { | ||
| 894 | mode = FLICKER_50; | ||
| 895 | } else { | ||
| 896 | mode = FLICKER_60; | ||
| 897 | } | ||
| 898 | } | ||
| 899 | for(i=0; i<NUM_FLICKER_CONTROLS; i++) { | ||
| 900 | if(flicker_controls[i].value == mode) { | ||
| 901 | c->value = i; | ||
| 902 | break; | ||
| 903 | } | ||
| 904 | } | ||
| 905 | if(i == NUM_FLICKER_CONTROLS) | ||
| 906 | return -EINVAL; | ||
| 907 | break; | ||
| 908 | } | ||
| 909 | case CPIA2_CID_FRAMERATE: | ||
| 910 | { | ||
| 911 | int maximum = NUM_FRAMERATE_CONTROLS - 1; | ||
| 912 | int i; | ||
| 913 | for(i=0; i<= maximum; i++) { | ||
| 914 | if(cam->params.vp_params.frame_rate == | ||
| 915 | framerate_controls[i].value) | ||
| 916 | break; | ||
| 917 | } | ||
| 918 | if(i > maximum) | ||
| 919 | return -EINVAL; | ||
| 920 | c->value = i; | ||
| 921 | break; | ||
| 922 | } | ||
| 923 | case CPIA2_CID_USB_ALT: | ||
| 924 | c->value = cam->params.camera_state.stream_mode; | ||
| 925 | break; | ||
| 926 | case CPIA2_CID_LIGHTS: | ||
| 927 | { | ||
| 928 | int i; | ||
| 929 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA, | ||
| 930 | TRANSFER_READ, 0); | ||
| 931 | for(i=0; i<NUM_LIGHTS_CONTROLS; i++) { | ||
| 932 | if((cam->params.vp_params.gpio_data&GPIO_LIGHTS_MASK) == | ||
| 933 | lights_controls[i].value) { | ||
| 934 | break; | ||
| 935 | } | ||
| 936 | } | ||
| 937 | if(i == NUM_LIGHTS_CONTROLS) | ||
| 938 | return -EINVAL; | ||
| 939 | c->value = i; | ||
| 940 | break; | ||
| 941 | } | ||
| 942 | case CPIA2_CID_RESET_CAMERA: | ||
| 943 | return -EINVAL; | 593 | return -EINVAL; |
| 944 | default: | ||
| 945 | return -EINVAL; | ||
| 946 | } | ||
| 947 | |||
| 948 | DBG("Get control id:%d, value:%d\n", c->id, c->value); | ||
| 949 | 594 | ||
| 595 | /* Maximum 15 fps for this model */ | ||
| 596 | if (cam->params.pnp_id.device_type == DEVICE_STV_672 && | ||
| 597 | cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) | ||
| 598 | max -= 2; | ||
| 599 | if (fival->index > max) | ||
| 600 | return -EINVAL; | ||
| 601 | for (i = 0; i < ARRAY_SIZE(cpia2_framesizes); i++) | ||
| 602 | if (fival->width == cpia2_framesizes[i].width && | ||
| 603 | fival->height == cpia2_framesizes[i].height) | ||
| 604 | break; | ||
| 605 | if (i == ARRAY_SIZE(cpia2_framesizes)) | ||
| 606 | return -EINVAL; | ||
| 607 | fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
| 608 | fival->discrete = framerate_controls[fival->index].period; | ||
| 950 | return 0; | 609 | return 0; |
| 951 | } | 610 | } |
| 952 | 611 | ||
| @@ -958,72 +617,54 @@ static int cpia2_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) | |||
| 958 | * | 617 | * |
| 959 | *****************************************************************************/ | 618 | *****************************************************************************/ |
| 960 | 619 | ||
| 961 | static int cpia2_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) | 620 | static int cpia2_s_ctrl(struct v4l2_ctrl *ctrl) |
| 962 | { | 621 | { |
| 963 | struct camera_data *cam = video_drvdata(file); | 622 | struct camera_data *cam = |
| 964 | int i; | 623 | container_of(ctrl->handler, struct camera_data, hdl); |
| 965 | int retval = 0; | 624 | static const int flicker_table[] = { |
| 625 | NEVER_FLICKER, | ||
| 626 | FLICKER_50, | ||
| 627 | FLICKER_60, | ||
| 628 | }; | ||
| 966 | 629 | ||
| 967 | DBG("Set control id:%d, value:%d\n", c->id, c->value); | 630 | DBG("Set control id:%d, value:%d\n", ctrl->id, ctrl->val); |
| 968 | |||
| 969 | /* Check that the value is in range */ | ||
| 970 | for(i=0; i<NUM_CONTROLS; i++) { | ||
| 971 | if(c->id == controls[i].id) { | ||
| 972 | if(c->value < controls[i].minimum || | ||
| 973 | c->value > controls[i].maximum) { | ||
| 974 | return -EINVAL; | ||
| 975 | } | ||
| 976 | break; | ||
| 977 | } | ||
| 978 | } | ||
| 979 | if(i == NUM_CONTROLS) | ||
| 980 | return -EINVAL; | ||
| 981 | 631 | ||
| 982 | switch(c->id) { | 632 | switch (ctrl->id) { |
| 983 | case V4L2_CID_BRIGHTNESS: | 633 | case V4L2_CID_BRIGHTNESS: |
| 984 | cpia2_set_brightness(cam, c->value); | 634 | cpia2_set_brightness(cam, ctrl->val); |
| 985 | break; | 635 | break; |
| 986 | case V4L2_CID_CONTRAST: | 636 | case V4L2_CID_CONTRAST: |
| 987 | cpia2_set_contrast(cam, c->value); | 637 | cpia2_set_contrast(cam, ctrl->val); |
| 988 | break; | 638 | break; |
| 989 | case V4L2_CID_SATURATION: | 639 | case V4L2_CID_SATURATION: |
| 990 | cpia2_set_saturation(cam, c->value); | 640 | cpia2_set_saturation(cam, ctrl->val); |
| 991 | break; | 641 | break; |
| 992 | case V4L2_CID_HFLIP: | 642 | case V4L2_CID_HFLIP: |
| 993 | cpia2_set_property_mirror(cam, c->value); | 643 | cpia2_set_property_mirror(cam, ctrl->val); |
| 994 | break; | 644 | break; |
| 995 | case V4L2_CID_VFLIP: | 645 | case V4L2_CID_VFLIP: |
| 996 | cpia2_set_property_flip(cam, c->value); | 646 | cpia2_set_property_flip(cam, ctrl->val); |
| 997 | break; | 647 | break; |
| 998 | case CPIA2_CID_TARGET_KB: | 648 | case V4L2_CID_POWER_LINE_FREQUENCY: |
| 999 | retval = cpia2_set_target_kb(cam, c->value); | 649 | return cpia2_set_flicker_mode(cam, flicker_table[ctrl->val]); |
| 650 | case V4L2_CID_ILLUMINATORS_1: | ||
| 651 | return cpia2_set_gpio(cam, (cam->top_light->val << 6) | | ||
| 652 | (cam->bottom_light->val << 7)); | ||
| 653 | case V4L2_CID_JPEG_ACTIVE_MARKER: | ||
| 654 | cam->params.compression.inhibit_htables = | ||
| 655 | !(ctrl->val & V4L2_JPEG_ACTIVE_MARKER_DHT); | ||
| 1000 | break; | 656 | break; |
| 1001 | case CPIA2_CID_GPIO: | 657 | case V4L2_CID_JPEG_COMPRESSION_QUALITY: |
| 1002 | retval = cpia2_set_gpio(cam, c->value); | 658 | cam->params.vc_params.quality = ctrl->val; |
| 1003 | break; | ||
| 1004 | case CPIA2_CID_FLICKER_MODE: | ||
| 1005 | retval = cpia2_set_flicker_mode(cam, | ||
| 1006 | flicker_controls[c->value].value); | ||
| 1007 | break; | ||
| 1008 | case CPIA2_CID_FRAMERATE: | ||
| 1009 | retval = cpia2_set_fps(cam, framerate_controls[c->value].value); | ||
| 1010 | break; | 659 | break; |
| 1011 | case CPIA2_CID_USB_ALT: | 660 | case CPIA2_CID_USB_ALT: |
| 1012 | retval = cpia2_usb_change_streaming_alternate(cam, c->value); | 661 | cam->params.camera_state.stream_mode = ctrl->val; |
| 1013 | break; | ||
| 1014 | case CPIA2_CID_LIGHTS: | ||
| 1015 | retval = cpia2_set_gpio(cam, lights_controls[c->value].value); | ||
| 1016 | break; | ||
| 1017 | case CPIA2_CID_RESET_CAMERA: | ||
| 1018 | cpia2_usb_stream_pause(cam); | ||
| 1019 | cpia2_reset_camera(cam); | ||
| 1020 | cpia2_usb_stream_resume(cam); | ||
| 1021 | break; | 662 | break; |
| 1022 | default: | 663 | default: |
| 1023 | retval = -EINVAL; | 664 | return -EINVAL; |
| 1024 | } | 665 | } |
| 1025 | 666 | ||
| 1026 | return retval; | 667 | return 0; |
| 1027 | } | 668 | } |
| 1028 | 669 | ||
| 1029 | /****************************************************************************** | 670 | /****************************************************************************** |
| @@ -1084,6 +725,8 @@ static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompres | |||
| 1084 | 725 | ||
| 1085 | cam->params.compression.inhibit_htables = | 726 | cam->params.compression.inhibit_htables = |
| 1086 | !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT); | 727 | !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT); |
| 728 | parms->jpeg_markers &= V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI | | ||
| 729 | V4L2_JPEG_MARKER_DHT; | ||
| 1087 | 730 | ||
| 1088 | if(parms->APP_len != 0) { | 731 | if(parms->APP_len != 0) { |
| 1089 | if(parms->APP_len > 0 && | 732 | if(parms->APP_len > 0 && |
| @@ -1270,12 +913,12 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | |||
| 1270 | struct framebuf *cb=cam->curbuff; | 913 | struct framebuf *cb=cam->curbuff; |
| 1271 | mutex_unlock(&cam->v4l2_lock); | 914 | mutex_unlock(&cam->v4l2_lock); |
| 1272 | wait_event_interruptible(cam->wq_stream, | 915 | wait_event_interruptible(cam->wq_stream, |
| 1273 | !cam->present || | 916 | !video_is_registered(&cam->vdev) || |
| 1274 | (cb=cam->curbuff)->status == FRAME_READY); | 917 | (cb=cam->curbuff)->status == FRAME_READY); |
| 1275 | mutex_lock(&cam->v4l2_lock); | 918 | mutex_lock(&cam->v4l2_lock); |
| 1276 | if (signal_pending(current)) | 919 | if (signal_pending(current)) |
| 1277 | return -ERESTARTSYS; | 920 | return -ERESTARTSYS; |
| 1278 | if(!cam->present) | 921 | if (!video_is_registered(&cam->vdev)) |
| 1279 | return -ENOTTY; | 922 | return -ENOTTY; |
| 1280 | frame = cb->num; | 923 | frame = cb->num; |
| 1281 | } | 924 | } |
| @@ -1299,56 +942,39 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | |||
| 1299 | return 0; | 942 | return 0; |
| 1300 | } | 943 | } |
| 1301 | 944 | ||
| 1302 | static int cpia2_g_priority(struct file *file, void *_fh, enum v4l2_priority *p) | ||
| 1303 | { | ||
| 1304 | struct cpia2_fh *fh = _fh; | ||
| 1305 | |||
| 1306 | *p = fh->prio; | ||
| 1307 | return 0; | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio) | ||
| 1311 | { | ||
| 1312 | struct camera_data *cam = video_drvdata(file); | ||
| 1313 | struct cpia2_fh *fh = _fh; | ||
| 1314 | |||
| 1315 | if (cam->streaming && prio != fh->prio && | ||
| 1316 | fh->prio == V4L2_PRIORITY_RECORD) | ||
| 1317 | /* Can't drop record priority while streaming */ | ||
| 1318 | return -EBUSY; | ||
| 1319 | |||
| 1320 | if (prio == V4L2_PRIORITY_RECORD && prio != fh->prio && | ||
| 1321 | v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) | ||
| 1322 | /* Only one program can record at a time */ | ||
| 1323 | return -EBUSY; | ||
| 1324 | return v4l2_prio_change(&cam->prio, &fh->prio, prio); | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type) | 945 | static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type) |
| 1328 | { | 946 | { |
| 1329 | struct camera_data *cam = video_drvdata(file); | 947 | struct camera_data *cam = video_drvdata(file); |
| 948 | int ret = -EINVAL; | ||
| 1330 | 949 | ||
| 1331 | DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming); | 950 | DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming); |
| 1332 | if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 951 | if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 1333 | return -EINVAL; | 952 | return -EINVAL; |
| 1334 | 953 | ||
| 1335 | if (!cam->streaming) | 954 | if (!cam->streaming) { |
| 1336 | return cpia2_usb_stream_start(cam, | 955 | ret = cpia2_usb_stream_start(cam, |
| 1337 | cam->params.camera_state.stream_mode); | 956 | cam->params.camera_state.stream_mode); |
| 1338 | return -EINVAL; | 957 | if (!ret) |
| 958 | v4l2_ctrl_grab(cam->usb_alt, true); | ||
| 959 | } | ||
| 960 | return ret; | ||
| 1339 | } | 961 | } |
| 1340 | 962 | ||
| 1341 | static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) | 963 | static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) |
| 1342 | { | 964 | { |
| 1343 | struct camera_data *cam = video_drvdata(file); | 965 | struct camera_data *cam = video_drvdata(file); |
| 966 | int ret = -EINVAL; | ||
| 1344 | 967 | ||
| 1345 | DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming); | 968 | DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming); |
| 1346 | if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 969 | if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 1347 | return -EINVAL; | 970 | return -EINVAL; |
| 1348 | 971 | ||
| 1349 | if (cam->streaming) | 972 | if (cam->streaming) { |
| 1350 | return cpia2_usb_stream_stop(cam); | 973 | ret = cpia2_usb_stream_stop(cam); |
| 1351 | return -EINVAL; | 974 | if (!ret) |
| 975 | v4l2_ctrl_grab(cam->usb_alt, false); | ||
| 976 | } | ||
| 977 | return ret; | ||
| 1352 | } | 978 | } |
| 1353 | 979 | ||
| 1354 | /****************************************************************************** | 980 | /****************************************************************************** |
| @@ -1361,16 +987,10 @@ static int cpia2_mmap(struct file *file, struct vm_area_struct *area) | |||
| 1361 | struct camera_data *cam = video_drvdata(file); | 987 | struct camera_data *cam = video_drvdata(file); |
| 1362 | int retval; | 988 | int retval; |
| 1363 | 989 | ||
| 1364 | /* Priority check */ | ||
| 1365 | struct cpia2_fh *fh = file->private_data; | ||
| 1366 | if(fh->prio != V4L2_PRIORITY_RECORD) { | ||
| 1367 | return -EBUSY; | ||
| 1368 | } | ||
| 1369 | |||
| 1370 | retval = cpia2_remap_buffer(cam, area); | 990 | retval = cpia2_remap_buffer(cam, area); |
| 1371 | 991 | ||
| 1372 | if(!retval) | 992 | if(!retval) |
| 1373 | fh->mmapped = 1; | 993 | cam->stream_fh = file->private_data; |
| 1374 | return retval; | 994 | return retval; |
| 1375 | } | 995 | } |
| 1376 | 996 | ||
| @@ -1388,15 +1008,13 @@ static void reset_camera_struct_v4l(struct camera_data *cam) | |||
| 1388 | cam->frame_size = buffer_size; | 1008 | cam->frame_size = buffer_size; |
| 1389 | cam->num_frames = num_buffers; | 1009 | cam->num_frames = num_buffers; |
| 1390 | 1010 | ||
| 1391 | /* FlickerModes */ | 1011 | /* Flicker modes */ |
| 1392 | cam->params.flicker_control.flicker_mode_req = flicker_mode; | 1012 | cam->params.flicker_control.flicker_mode_req = flicker_mode; |
| 1393 | cam->params.flicker_control.mains_frequency = flicker_freq; | ||
| 1394 | 1013 | ||
| 1395 | /* streamMode */ | 1014 | /* stream modes */ |
| 1396 | cam->params.camera_state.stream_mode = alternate; | 1015 | cam->params.camera_state.stream_mode = alternate; |
| 1397 | 1016 | ||
| 1398 | cam->pixelformat = V4L2_PIX_FMT_JPEG; | 1017 | cam->pixelformat = V4L2_PIX_FMT_JPEG; |
| 1399 | v4l2_prio_init(&cam->prio); | ||
| 1400 | } | 1018 | } |
| 1401 | 1019 | ||
| 1402 | static const struct v4l2_ioctl_ops cpia2_ioctl_ops = { | 1020 | static const struct v4l2_ioctl_ops cpia2_ioctl_ops = { |
| @@ -1408,10 +1026,6 @@ static const struct v4l2_ioctl_ops cpia2_ioctl_ops = { | |||
| 1408 | .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap, | 1026 | .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap, |
| 1409 | .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap, | 1027 | .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap, |
| 1410 | .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap, | 1028 | .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap, |
| 1411 | .vidioc_queryctrl = cpia2_queryctrl, | ||
| 1412 | .vidioc_querymenu = cpia2_querymenu, | ||
| 1413 | .vidioc_g_ctrl = cpia2_g_ctrl, | ||
| 1414 | .vidioc_s_ctrl = cpia2_s_ctrl, | ||
| 1415 | .vidioc_g_jpegcomp = cpia2_g_jpegcomp, | 1029 | .vidioc_g_jpegcomp = cpia2_g_jpegcomp, |
| 1416 | .vidioc_s_jpegcomp = cpia2_s_jpegcomp, | 1030 | .vidioc_s_jpegcomp = cpia2_s_jpegcomp, |
| 1417 | .vidioc_cropcap = cpia2_cropcap, | 1031 | .vidioc_cropcap = cpia2_cropcap, |
| @@ -1421,9 +1035,12 @@ static const struct v4l2_ioctl_ops cpia2_ioctl_ops = { | |||
| 1421 | .vidioc_dqbuf = cpia2_dqbuf, | 1035 | .vidioc_dqbuf = cpia2_dqbuf, |
| 1422 | .vidioc_streamon = cpia2_streamon, | 1036 | .vidioc_streamon = cpia2_streamon, |
| 1423 | .vidioc_streamoff = cpia2_streamoff, | 1037 | .vidioc_streamoff = cpia2_streamoff, |
| 1424 | .vidioc_g_priority = cpia2_g_priority, | 1038 | .vidioc_s_parm = cpia2_s_parm, |
| 1425 | .vidioc_s_priority = cpia2_s_priority, | 1039 | .vidioc_g_parm = cpia2_g_parm, |
| 1426 | .vidioc_default = cpia2_default, | 1040 | .vidioc_enum_framesizes = cpia2_enum_framesizes, |
| 1041 | .vidioc_enum_frameintervals = cpia2_enum_frameintervals, | ||
| 1042 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
| 1043 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
| 1427 | }; | 1044 | }; |
| 1428 | 1045 | ||
| 1429 | /*** | 1046 | /*** |
| @@ -1444,7 +1061,21 @@ static struct video_device cpia2_template = { | |||
| 1444 | .name = "CPiA2 Camera", | 1061 | .name = "CPiA2 Camera", |
| 1445 | .fops = &cpia2_fops, | 1062 | .fops = &cpia2_fops, |
| 1446 | .ioctl_ops = &cpia2_ioctl_ops, | 1063 | .ioctl_ops = &cpia2_ioctl_ops, |
| 1447 | .release = video_device_release, | 1064 | .release = video_device_release_empty, |
| 1065 | }; | ||
| 1066 | |||
| 1067 | void cpia2_camera_release(struct v4l2_device *v4l2_dev) | ||
| 1068 | { | ||
| 1069 | struct camera_data *cam = | ||
| 1070 | container_of(v4l2_dev, struct camera_data, v4l2_dev); | ||
| 1071 | |||
| 1072 | v4l2_ctrl_handler_free(&cam->hdl); | ||
| 1073 | v4l2_device_unregister(&cam->v4l2_dev); | ||
| 1074 | kfree(cam); | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | static const struct v4l2_ctrl_ops cpia2_ctrl_ops = { | ||
| 1078 | .s_ctrl = cpia2_s_ctrl, | ||
| 1448 | }; | 1079 | }; |
| 1449 | 1080 | ||
| 1450 | /****************************************************************************** | 1081 | /****************************************************************************** |
| @@ -1454,20 +1085,74 @@ static struct video_device cpia2_template = { | |||
| 1454 | *****************************************************************************/ | 1085 | *****************************************************************************/ |
| 1455 | int cpia2_register_camera(struct camera_data *cam) | 1086 | int cpia2_register_camera(struct camera_data *cam) |
| 1456 | { | 1087 | { |
| 1457 | cam->vdev = video_device_alloc(); | 1088 | struct v4l2_ctrl_handler *hdl = &cam->hdl; |
| 1458 | if(!cam->vdev) | 1089 | struct v4l2_ctrl_config cpia2_usb_alt = { |
| 1459 | return -ENOMEM; | 1090 | .ops = &cpia2_ctrl_ops, |
| 1091 | .id = CPIA2_CID_USB_ALT, | ||
| 1092 | .name = "USB Alternate", | ||
| 1093 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 1094 | .min = USBIF_ISO_1, | ||
| 1095 | .max = USBIF_ISO_6, | ||
| 1096 | .step = 1, | ||
| 1097 | }; | ||
| 1098 | int ret; | ||
| 1099 | |||
| 1100 | v4l2_ctrl_handler_init(hdl, 12); | ||
| 1101 | v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, | ||
| 1102 | V4L2_CID_BRIGHTNESS, | ||
| 1103 | cam->params.pnp_id.device_type == DEVICE_STV_672 ? 1 : 0, | ||
| 1104 | 255, 1, DEFAULT_BRIGHTNESS); | ||
| 1105 | v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, | ||
| 1106 | V4L2_CID_CONTRAST, 0, 255, 1, DEFAULT_CONTRAST); | ||
| 1107 | v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, | ||
| 1108 | V4L2_CID_SATURATION, 0, 255, 1, DEFAULT_SATURATION); | ||
| 1109 | v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, | ||
| 1110 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
| 1111 | v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, | ||
| 1112 | V4L2_CID_JPEG_ACTIVE_MARKER, 0, | ||
| 1113 | V4L2_JPEG_ACTIVE_MARKER_DHT, 0, | ||
| 1114 | V4L2_JPEG_ACTIVE_MARKER_DHT); | ||
| 1115 | v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, | ||
| 1116 | V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, | ||
| 1117 | 100, 1, 100); | ||
| 1118 | cpia2_usb_alt.def = alternate; | ||
| 1119 | cam->usb_alt = v4l2_ctrl_new_custom(hdl, &cpia2_usb_alt, NULL); | ||
| 1120 | /* VP5 Only */ | ||
| 1121 | if (cam->params.pnp_id.device_type != DEVICE_STV_672) | ||
| 1122 | v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, | ||
| 1123 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
| 1124 | /* Flicker control only valid for 672 */ | ||
| 1125 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) | ||
| 1126 | v4l2_ctrl_new_std_menu(hdl, &cpia2_ctrl_ops, | ||
| 1127 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
| 1128 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); | ||
| 1129 | /* Light control only valid for the QX5 Microscope */ | ||
| 1130 | if (cam->params.pnp_id.product == 0x151) { | ||
| 1131 | cam->top_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, | ||
| 1132 | V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0); | ||
| 1133 | cam->bottom_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, | ||
| 1134 | V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0); | ||
| 1135 | v4l2_ctrl_cluster(2, &cam->top_light); | ||
| 1136 | } | ||
| 1460 | 1137 | ||
| 1461 | memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template)); | 1138 | if (hdl->error) { |
| 1462 | video_set_drvdata(cam->vdev, cam); | 1139 | ret = hdl->error; |
| 1463 | cam->vdev->lock = &cam->v4l2_lock; | 1140 | v4l2_ctrl_handler_free(hdl); |
| 1141 | return ret; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | cam->vdev = cpia2_template; | ||
| 1145 | video_set_drvdata(&cam->vdev, cam); | ||
| 1146 | cam->vdev.lock = &cam->v4l2_lock; | ||
| 1147 | cam->vdev.ctrl_handler = hdl; | ||
| 1148 | cam->vdev.v4l2_dev = &cam->v4l2_dev; | ||
| 1149 | set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags); | ||
| 1464 | 1150 | ||
| 1465 | reset_camera_struct_v4l(cam); | 1151 | reset_camera_struct_v4l(cam); |
| 1466 | 1152 | ||
| 1467 | /* register v4l device */ | 1153 | /* register v4l device */ |
| 1468 | if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { | 1154 | if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { |
| 1469 | ERR("video_register_device failed\n"); | 1155 | ERR("video_register_device failed\n"); |
| 1470 | video_device_release(cam->vdev); | ||
| 1471 | return -ENODEV; | 1156 | return -ENODEV; |
| 1472 | } | 1157 | } |
| 1473 | 1158 | ||
| @@ -1481,13 +1166,7 @@ int cpia2_register_camera(struct camera_data *cam) | |||
| 1481 | *****************************************************************************/ | 1166 | *****************************************************************************/ |
| 1482 | void cpia2_unregister_camera(struct camera_data *cam) | 1167 | void cpia2_unregister_camera(struct camera_data *cam) |
| 1483 | { | 1168 | { |
| 1484 | if (!cam->open_count) { | 1169 | video_unregister_device(&cam->vdev); |
| 1485 | video_unregister_device(cam->vdev); | ||
| 1486 | } else { | ||
| 1487 | LOG("%s removed while open, deferring " | ||
| 1488 | "video_unregister_device\n", | ||
| 1489 | video_device_node_name(cam->vdev)); | ||
| 1490 | } | ||
| 1491 | } | 1170 | } |
| 1492 | 1171 | ||
| 1493 | /****************************************************************************** | 1172 | /****************************************************************************** |
| @@ -1524,23 +1203,12 @@ static void __init check_parameters(void) | |||
| 1524 | LOG("alternate specified is invalid, using %d\n", alternate); | 1203 | LOG("alternate specified is invalid, using %d\n", alternate); |
| 1525 | } | 1204 | } |
| 1526 | 1205 | ||
| 1527 | if (flicker_mode != NEVER_FLICKER && flicker_mode != ANTI_FLICKER_ON) { | 1206 | if (flicker_mode != 0 && flicker_mode != FLICKER_50 && flicker_mode != FLICKER_60) { |
| 1528 | flicker_mode = NEVER_FLICKER; | 1207 | flicker_mode = 0; |
| 1529 | LOG("Flicker mode specified is invalid, using %d\n", | 1208 | LOG("Flicker mode specified is invalid, using %d\n", |
| 1530 | flicker_mode); | 1209 | flicker_mode); |
| 1531 | } | 1210 | } |
| 1532 | 1211 | ||
| 1533 | if (flicker_freq != FLICKER_50 && flicker_freq != FLICKER_60) { | ||
| 1534 | flicker_freq = FLICKER_60; | ||
| 1535 | LOG("Flicker mode specified is invalid, using %d\n", | ||
| 1536 | flicker_freq); | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | if(video_nr < -1 || video_nr > 64) { | ||
| 1540 | video_nr = -1; | ||
| 1541 | LOG("invalid video_nr specified, must be -1 to 64\n"); | ||
| 1542 | } | ||
| 1543 | |||
| 1544 | DBG("Using %d buffers, each %d bytes, alternate=%d\n", | 1212 | DBG("Using %d buffers, each %d bytes, alternate=%d\n", |
| 1545 | num_buffers, buffer_size, alternate); | 1213 | num_buffers, buffer_size, alternate); |
| 1546 | } | 1214 | } |
diff --git a/drivers/media/video/cpia2/cpia2dev.h b/drivers/media/video/cpia2/cpia2dev.h deleted file mode 100644 index f66691fe5a3..00000000000 --- a/drivers/media/video/cpia2/cpia2dev.h +++ /dev/null | |||
| @@ -1,50 +0,0 @@ | |||
| 1 | /**************************************************************************** | ||
| 2 | * | ||
| 3 | * Filename: cpia2dev.h | ||
| 4 | * | ||
| 5 | * Copyright 2001, STMicrolectronics, Inc. | ||
| 6 | * | ||
| 7 | * Contact: steve.miller@st.com | ||
| 8 | * | ||
| 9 | * Description: | ||
| 10 | * This file provides definitions for applications wanting to use the | ||
| 11 | * cpia2 driver beyond the generic v4l capabilities. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation; either version 2 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program; if not, write to the Free Software | ||
| 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 26 | * | ||
| 27 | ****************************************************************************/ | ||
| 28 | |||
| 29 | #ifndef CPIA2_DEV_HEADER | ||
| 30 | #define CPIA2_DEV_HEADER | ||
| 31 | |||
| 32 | #include <linux/videodev2.h> | ||
| 33 | |||
| 34 | /*** | ||
| 35 | * The following defines are ioctl numbers based on video4linux private ioctls, | ||
| 36 | * which can range from 192 (BASE_VIDIOCPRIVATE) to 255. All of these take int | ||
| 37 | * args | ||
| 38 | */ | ||
| 39 | #define CPIA2_IOC_SET_GPIO _IOW('v', BASE_VIDIOC_PRIVATE + 17, __u32) | ||
| 40 | |||
| 41 | /* V4L2 driver specific controls */ | ||
| 42 | #define CPIA2_CID_TARGET_KB (V4L2_CID_PRIVATE_BASE+0) | ||
| 43 | #define CPIA2_CID_GPIO (V4L2_CID_PRIVATE_BASE+1) | ||
| 44 | #define CPIA2_CID_FLICKER_MODE (V4L2_CID_PRIVATE_BASE+2) | ||
| 45 | #define CPIA2_CID_FRAMERATE (V4L2_CID_PRIVATE_BASE+3) | ||
| 46 | #define CPIA2_CID_USB_ALT (V4L2_CID_PRIVATE_BASE+4) | ||
| 47 | #define CPIA2_CID_LIGHTS (V4L2_CID_PRIVATE_BASE+5) | ||
| 48 | #define CPIA2_CID_RESET_CAMERA (V4L2_CID_PRIVATE_BASE+6) | ||
| 49 | |||
| 50 | #endif | ||
