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