aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pwc')
-rw-r--r--drivers/media/video/pwc/Kconfig1
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c803
-rw-r--r--drivers/media/video/pwc/pwc-dec1.c28
-rw-r--r--drivers/media/video/pwc/pwc-dec1.h8
-rw-r--r--drivers/media/video/pwc/pwc-dec23.c22
-rw-r--r--drivers/media/video/pwc/pwc-dec23.h10
-rw-r--r--drivers/media/video/pwc/pwc-if.c1259
-rw-r--r--drivers/media/video/pwc/pwc-ioctl.h323
-rw-r--r--drivers/media/video/pwc/pwc-kiara.c1
-rw-r--r--drivers/media/video/pwc/pwc-misc.c4
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.c17
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.h40
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c1257
-rw-r--r--drivers/media/video/pwc/pwc.h409
14 files changed, 1473 insertions, 2709 deletions
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 8da42e4f1ba0..d63d0a850035 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -1,6 +1,7 @@
1config USB_PWC 1config USB_PWC
2 tristate "USB Philips Cameras" 2 tristate "USB Philips Cameras"
3 depends on VIDEO_V4L2 3 depends on VIDEO_V4L2
4 select VIDEOBUF2_VMALLOC
4 ---help--- 5 ---help---
5 Say Y or M here if you want to use one of these Philips & OEM 6 Say Y or M here if you want to use one of these Philips & OEM
6 webcams: 7 webcams:
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 760b4de13adf..3977addf3ba8 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -3,6 +3,7 @@
3 video modes. 3 video modes.
4 (C) 1999-2003 Nemosoft Unv. 4 (C) 1999-2003 Nemosoft Unv.
5 (C) 2004-2006 Luc Saillard (luc@saillard.org) 5 (C) 2004-2006 Luc Saillard (luc@saillard.org)
6 (C) 2011 Hans de Goede <hdegoede@redhat.com>
6 7
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 8 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version. 9 driver and thus may have bugs that are not present in the original version.
@@ -43,61 +44,12 @@
43#include <asm/errno.h> 44#include <asm/errno.h>
44 45
45#include "pwc.h" 46#include "pwc.h"
46#include "pwc-uncompress.h"
47#include "pwc-kiara.h" 47#include "pwc-kiara.h"
48#include "pwc-timon.h" 48#include "pwc-timon.h"
49#include "pwc-dec1.h" 49#include "pwc-dec1.h"
50#include "pwc-dec23.h" 50#include "pwc-dec23.h"
51 51
52/* Request types: video */ 52/* Selectors for status controls used only in this file */
53#define SET_LUM_CTL 0x01
54#define GET_LUM_CTL 0x02
55#define SET_CHROM_CTL 0x03
56#define GET_CHROM_CTL 0x04
57#define SET_STATUS_CTL 0x05
58#define GET_STATUS_CTL 0x06
59#define SET_EP_STREAM_CTL 0x07
60#define GET_EP_STREAM_CTL 0x08
61#define GET_XX_CTL 0x09
62#define SET_XX_CTL 0x0A
63#define GET_XY_CTL 0x0B
64#define SET_XY_CTL 0x0C
65#define SET_MPT_CTL 0x0D
66#define GET_MPT_CTL 0x0E
67
68/* Selectors for the Luminance controls [GS]ET_LUM_CTL */
69#define AGC_MODE_FORMATTER 0x2000
70#define PRESET_AGC_FORMATTER 0x2100
71#define SHUTTER_MODE_FORMATTER 0x2200
72#define PRESET_SHUTTER_FORMATTER 0x2300
73#define PRESET_CONTOUR_FORMATTER 0x2400
74#define AUTO_CONTOUR_FORMATTER 0x2500
75#define BACK_LIGHT_COMPENSATION_FORMATTER 0x2600
76#define CONTRAST_FORMATTER 0x2700
77#define DYNAMIC_NOISE_CONTROL_FORMATTER 0x2800
78#define FLICKERLESS_MODE_FORMATTER 0x2900
79#define AE_CONTROL_SPEED 0x2A00
80#define BRIGHTNESS_FORMATTER 0x2B00
81#define GAMMA_FORMATTER 0x2C00
82
83/* Selectors for the Chrominance controls [GS]ET_CHROM_CTL */
84#define WB_MODE_FORMATTER 0x1000
85#define AWB_CONTROL_SPEED_FORMATTER 0x1100
86#define AWB_CONTROL_DELAY_FORMATTER 0x1200
87#define PRESET_MANUAL_RED_GAIN_FORMATTER 0x1300
88#define PRESET_MANUAL_BLUE_GAIN_FORMATTER 0x1400
89#define COLOUR_MODE_FORMATTER 0x1500
90#define SATURATION_MODE_FORMATTER1 0x1600
91#define SATURATION_MODE_FORMATTER2 0x1700
92
93/* Selectors for the Status controls [GS]ET_STATUS_CTL */
94#define SAVE_USER_DEFAULTS_FORMATTER 0x0200
95#define RESTORE_USER_DEFAULTS_FORMATTER 0x0300
96#define RESTORE_FACTORY_DEFAULTS_FORMATTER 0x0400
97#define READ_AGC_FORMATTER 0x0500
98#define READ_SHUTTER_FORMATTER 0x0600
99#define READ_RED_GAIN_FORMATTER 0x0700
100#define READ_BLUE_GAIN_FORMATTER 0x0800
101#define GET_STATUS_B00 0x0B00 53#define GET_STATUS_B00 0x0B00
102#define SENSOR_TYPE_FORMATTER1 0x0C00 54#define SENSOR_TYPE_FORMATTER1 0x0C00
103#define GET_STATUS_3000 0x3000 55#define GET_STATUS_3000 0x3000
@@ -116,11 +68,6 @@
116/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */ 68/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
117#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100 69#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
118 70
119/* Formatters for the motorized pan & tilt [GS]ET_MPT_CTL */
120#define PT_RELATIVE_CONTROL_FORMATTER 0x01
121#define PT_RESET_CONTROL_FORMATTER 0x02
122#define PT_STATUS_FORMATTER 0x03
123
124static const char *size2name[PSZ_MAX] = 71static const char *size2name[PSZ_MAX] =
125{ 72{
126 "subQCIF", 73 "subQCIF",
@@ -160,7 +107,7 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev);
160/****************************************************************************/ 107/****************************************************************************/
161 108
162static int _send_control_msg(struct pwc_device *pdev, 109static int _send_control_msg(struct pwc_device *pdev,
163 u8 request, u16 value, int index, void *buf, int buflen, int timeout) 110 u8 request, u16 value, int index, void *buf, int buflen)
164{ 111{
165 int rc; 112 int rc;
166 void *kbuf = NULL; 113 void *kbuf = NULL;
@@ -177,7 +124,7 @@ static int _send_control_msg(struct pwc_device *pdev,
177 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 124 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
178 value, 125 value,
179 index, 126 index,
180 kbuf, buflen, timeout); 127 kbuf, buflen, USB_CTRL_SET_TIMEOUT);
181 128
182 kfree(kbuf); 129 kfree(kbuf);
183 return rc; 130 return rc;
@@ -197,9 +144,13 @@ static int recv_control_msg(struct pwc_device *pdev,
197 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 144 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
198 value, 145 value,
199 pdev->vcinterface, 146 pdev->vcinterface,
200 kbuf, buflen, 500); 147 kbuf, buflen, USB_CTRL_GET_TIMEOUT);
201 memcpy(buf, kbuf, buflen); 148 memcpy(buf, kbuf, buflen);
202 kfree(kbuf); 149 kfree(kbuf);
150
151 if (rc < 0)
152 PWC_ERROR("recv_control_msg error %d req %02x val %04x\n",
153 rc, request, value);
203 return rc; 154 return rc;
204} 155}
205 156
@@ -210,18 +161,16 @@ static inline int send_video_command(struct pwc_device *pdev,
210 SET_EP_STREAM_CTL, 161 SET_EP_STREAM_CTL,
211 VIDEO_OUTPUT_CONTROL_FORMATTER, 162 VIDEO_OUTPUT_CONTROL_FORMATTER,
212 index, 163 index,
213 buf, buflen, 1000); 164 buf, buflen);
214} 165}
215 166
216static inline int send_control_msg(struct pwc_device *pdev, 167int send_control_msg(struct pwc_device *pdev,
217 u8 request, u16 value, void *buf, int buflen) 168 u8 request, u16 value, void *buf, int buflen)
218{ 169{
219 return _send_control_msg(pdev, 170 return _send_control_msg(pdev,
220 request, value, pdev->vcinterface, buf, buflen, 500); 171 request, value, pdev->vcinterface, buf, buflen);
221} 172}
222 173
223
224
225static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) 174static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
226{ 175{
227 unsigned char buf[3]; 176 unsigned char buf[3];
@@ -261,8 +210,11 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
261 PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); 210 PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
262 return ret; 211 return ret;
263 } 212 }
264 if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) 213 if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
265 pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); 214 ret = pwc_dec1_init(pdev, pdev->type, pdev->release, buf);
215 if (ret < 0)
216 return ret;
217 }
266 218
267 pdev->cmd_len = 3; 219 pdev->cmd_len = 3;
268 memcpy(pdev->cmd_buf, buf, 3); 220 memcpy(pdev->cmd_buf, buf, 3);
@@ -321,8 +273,11 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, i
321 if (ret < 0) 273 if (ret < 0)
322 return ret; 274 return ret;
323 275
324 if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) 276 if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
325 pwc_dec23_init(pdev, pdev->type, buf); 277 ret = pwc_dec23_init(pdev, pdev->type, buf);
278 if (ret < 0)
279 return ret;
280 }
326 281
327 pdev->cmd_len = 13; 282 pdev->cmd_len = 13;
328 memcpy(pdev->cmd_buf, buf, 13); 283 memcpy(pdev->cmd_buf, buf, 13);
@@ -394,8 +349,11 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i
394 if (ret < 0) 349 if (ret < 0)
395 return ret; 350 return ret;
396 351
397 if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) 352 if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
398 pwc_dec23_init(pdev, pdev->type, buf); 353 ret = pwc_dec23_init(pdev, pdev->type, buf);
354 if (ret < 0)
355 return ret;
356 }
399 357
400 pdev->cmd_len = 12; 358 pdev->cmd_len = 12;
401 memcpy(pdev->cmd_buf, buf, 12); 359 memcpy(pdev->cmd_buf, buf, 12);
@@ -452,6 +410,7 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
452 } 410 }
453 pdev->view.x = width; 411 pdev->view.x = width;
454 pdev->view.y = height; 412 pdev->view.y = height;
413 pdev->vcompression = compression;
455 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; 414 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
456 pwc_set_image_buffer_size(pdev); 415 pwc_set_image_buffer_size(pdev);
457 PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); 416 PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
@@ -511,13 +470,9 @@ unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned i
511 return ret; 470 return ret;
512} 471}
513 472
514#define BLACK_Y 0
515#define BLACK_U 128
516#define BLACK_V 128
517
518static void pwc_set_image_buffer_size(struct pwc_device *pdev) 473static void pwc_set_image_buffer_size(struct pwc_device *pdev)
519{ 474{
520 int i, factor = 0; 475 int factor = 0;
521 476
522 /* for V4L2_PIX_FMT_YUV420 */ 477 /* for V4L2_PIX_FMT_YUV420 */
523 switch (pdev->pixfmt) { 478 switch (pdev->pixfmt) {
@@ -541,442 +496,108 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev)
541 */ 496 */
542 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; 497 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
543 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; 498 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
544
545 /* Fill buffers with black colors */
546 for (i = 0; i < pwc_mbufs; i++) {
547 unsigned char *p = pdev->image_data + pdev->images[i].offset;
548 memset(p, BLACK_Y, pdev->view.x * pdev->view.y);
549 p += pdev->view.x * pdev->view.y;
550 memset(p, BLACK_U, pdev->view.x * pdev->view.y/4);
551 p += pdev->view.x * pdev->view.y/4;
552 memset(p, BLACK_V, pdev->view.x * pdev->view.y/4);
553 }
554} 499}
555 500
556 501int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
557
558/* BRIGHTNESS */
559
560int pwc_get_brightness(struct pwc_device *pdev)
561{ 502{
562 char buf;
563 int ret; 503 int ret;
504 u8 buf;
564 505
565 ret = recv_control_msg(pdev, 506 ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
566 GET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
567 if (ret < 0) 507 if (ret < 0)
568 return ret; 508 return ret;
569 return buf;
570}
571 509
572int pwc_set_brightness(struct pwc_device *pdev, int value) 510 *data = buf;
573{ 511 return 0;
574 char buf;
575
576 if (value < 0)
577 value = 0;
578 if (value > 0xffff)
579 value = 0xffff;
580 buf = (value >> 9) & 0x7f;
581 return send_control_msg(pdev,
582 SET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
583} 512}
584 513
585/* CONTRAST */ 514int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
586
587int pwc_get_contrast(struct pwc_device *pdev)
588{ 515{
589 char buf;
590 int ret; 516 int ret;
591 517
592 ret = recv_control_msg(pdev, 518 ret = send_control_msg(pdev, request, value, &data, sizeof(data));
593 GET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
594 if (ret < 0) 519 if (ret < 0)
595 return ret; 520 return ret;
596 return buf;
597}
598 521
599int pwc_set_contrast(struct pwc_device *pdev, int value) 522 return 0;
600{
601 char buf;
602
603 if (value < 0)
604 value = 0;
605 if (value > 0xffff)
606 value = 0xffff;
607 buf = (value >> 10) & 0x3f;
608 return send_control_msg(pdev,
609 SET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
610} 523}
611 524
612/* GAMMA */ 525int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
613
614int pwc_get_gamma(struct pwc_device *pdev)
615{ 526{
616 char buf;
617 int ret; 527 int ret;
528 s8 buf;
618 529
619 ret = recv_control_msg(pdev, 530 ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
620 GET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
621 if (ret < 0) 531 if (ret < 0)
622 return ret; 532 return ret;
623 return buf;
624}
625
626int pwc_set_gamma(struct pwc_device *pdev, int value)
627{
628 char buf;
629 533
630 if (value < 0) 534 *data = buf;
631 value = 0;
632 if (value > 0xffff)
633 value = 0xffff;
634 buf = (value >> 11) & 0x1f;
635 return send_control_msg(pdev,
636 SET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
637}
638
639
640/* SATURATION */
641
642/* return a value between [-100 , 100] */
643int pwc_get_saturation(struct pwc_device *pdev, int *value)
644{
645 char buf;
646 int ret, saturation_register;
647
648 if (pdev->type < 675)
649 return -EINVAL;
650 if (pdev->type < 730)
651 saturation_register = SATURATION_MODE_FORMATTER2;
652 else
653 saturation_register = SATURATION_MODE_FORMATTER1;
654 ret = recv_control_msg(pdev,
655 GET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
656 if (ret < 0)
657 return ret;
658 *value = (signed)buf;
659 return 0; 535 return 0;
660} 536}
661 537
662/* @param value saturation color between [-100 , 100] */ 538int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
663int pwc_set_saturation(struct pwc_device *pdev, int value)
664{ 539{
665 char buf;
666 int saturation_register;
667
668 if (pdev->type < 675)
669 return -EINVAL;
670 if (value < -100)
671 value = -100;
672 if (value > 100)
673 value = 100;
674 if (pdev->type < 730)
675 saturation_register = SATURATION_MODE_FORMATTER2;
676 else
677 saturation_register = SATURATION_MODE_FORMATTER1;
678 return send_control_msg(pdev,
679 SET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
680}
681
682/* AGC */
683
684int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
685{
686 char buf;
687 int ret; 540 int ret;
541 u8 buf[2];
688 542
689 if (mode) 543 ret = recv_control_msg(pdev, request, value, buf, sizeof(buf));
690 buf = 0x0; /* auto */
691 else
692 buf = 0xff; /* fixed */
693
694 ret = send_control_msg(pdev,
695 SET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf));
696
697 if (!mode && ret >= 0) {
698 if (value < 0)
699 value = 0;
700 if (value > 0xffff)
701 value = 0xffff;
702 buf = (value >> 10) & 0x3F;
703 ret = send_control_msg(pdev,
704 SET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
705 }
706 if (ret < 0) 544 if (ret < 0)
707 return ret; 545 return ret;
546
547 *data = (buf[1] << 8) | buf[0];
708 return 0; 548 return 0;
709} 549}
710 550
711int pwc_get_agc(struct pwc_device *pdev, int *value) 551int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data)
712{ 552{
713 unsigned char buf;
714 int ret; 553 int ret;
554 u8 buf[2];
715 555
716 ret = recv_control_msg(pdev, 556 buf[0] = data & 0xff;
717 GET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf)); 557 buf[1] = data >> 8;
558 ret = send_control_msg(pdev, request, value, buf, sizeof(buf));
718 if (ret < 0) 559 if (ret < 0)
719 return ret; 560 return ret;
720 561
721 if (buf != 0) { /* fixed */
722 ret = recv_control_msg(pdev,
723 GET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
724 if (ret < 0)
725 return ret;
726 if (buf > 0x3F)
727 buf = 0x3F;
728 *value = (buf << 10);
729 }
730 else { /* auto */
731 ret = recv_control_msg(pdev,
732 GET_STATUS_CTL, READ_AGC_FORMATTER, &buf, sizeof(buf));
733 if (ret < 0)
734 return ret;
735 /* Gah... this value ranges from 0x00 ... 0x9F */
736 if (buf > 0x9F)
737 buf = 0x9F;
738 *value = -(48 + buf * 409);
739 }
740
741 return 0; 562 return 0;
742} 563}
743 564
744int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) 565int pwc_button_ctrl(struct pwc_device *pdev, u16 value)
745{
746 char buf[2];
747 int speed, ret;
748
749
750 if (mode)
751 buf[0] = 0x0; /* auto */
752 else
753 buf[0] = 0xff; /* fixed */
754
755 ret = send_control_msg(pdev,
756 SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, 1);
757
758 if (!mode && ret >= 0) {
759 if (value < 0)
760 value = 0;
761 if (value > 0xffff)
762 value = 0xffff;
763
764 if (DEVICE_USE_CODEC2(pdev->type)) {
765 /* speed ranges from 0x0 to 0x290 (656) */
766 speed = (value / 100);
767 buf[1] = speed >> 8;
768 buf[0] = speed & 0xff;
769 } else if (DEVICE_USE_CODEC3(pdev->type)) {
770 /* speed seems to range from 0x0 to 0xff */
771 buf[1] = 0;
772 buf[0] = value >> 8;
773 }
774
775 ret = send_control_msg(pdev,
776 SET_LUM_CTL, PRESET_SHUTTER_FORMATTER,
777 &buf, sizeof(buf));
778 }
779 return ret;
780}
781
782/* This function is not exported to v4l1, so output values between 0 -> 256 */
783int pwc_get_shutter_speed(struct pwc_device *pdev, int *value)
784{ 566{
785 unsigned char buf[2];
786 int ret; 567 int ret;
787 568
788 ret = recv_control_msg(pdev, 569 ret = send_control_msg(pdev, SET_STATUS_CTL, value, NULL, 0);
789 GET_STATUS_CTL, READ_SHUTTER_FORMATTER, &buf, sizeof(buf));
790 if (ret < 0) 570 if (ret < 0)
791 return ret; 571 return ret;
792 *value = buf[0] + (buf[1] << 8); 572
793 if (DEVICE_USE_CODEC2(pdev->type)) {
794 /* speed ranges from 0x0 to 0x290 (656) */
795 *value *= 256/656;
796 } else if (DEVICE_USE_CODEC3(pdev->type)) {
797 /* speed seems to range from 0x0 to 0xff */
798 }
799 return 0; 573 return 0;
800} 574}
801 575
802
803/* POWER */ 576/* POWER */
804 577void pwc_camera_power(struct pwc_device *pdev, int power)
805int pwc_camera_power(struct pwc_device *pdev, int power)
806{ 578{
807 char buf; 579 char buf;
580 int r;
581
582 if (!pdev->power_save)
583 return;
808 584
809 if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6)) 585 if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
810 return 0; /* Not supported by Nala or Timon < release 6 */ 586 return; /* Not supported by Nala or Timon < release 6 */
811 587
812 if (power) 588 if (power)
813 buf = 0x00; /* active */ 589 buf = 0x00; /* active */
814 else 590 else
815 buf = 0xFF; /* power save */ 591 buf = 0xFF; /* power save */
816 return send_control_msg(pdev, 592 r = send_control_msg(pdev,
817 SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 593 SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER,
818 &buf, sizeof(buf)); 594 &buf, sizeof(buf));
819}
820
821
822
823/* private calls */
824
825int pwc_restore_user(struct pwc_device *pdev)
826{
827 return send_control_msg(pdev,
828 SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, NULL, 0);
829}
830
831int pwc_save_user(struct pwc_device *pdev)
832{
833 return send_control_msg(pdev,
834 SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, NULL, 0);
835}
836
837int pwc_restore_factory(struct pwc_device *pdev)
838{
839 return send_control_msg(pdev,
840 SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, NULL, 0);
841}
842
843 /* ************************************************* */
844 /* Patch by Alvarado: (not in the original version */
845
846 /*
847 * the camera recognizes modes from 0 to 4:
848 *
849 * 00: indoor (incandescant lighting)
850 * 01: outdoor (sunlight)
851 * 02: fluorescent lighting
852 * 03: manual
853 * 04: auto
854 */
855int pwc_set_awb(struct pwc_device *pdev, int mode)
856{
857 char buf;
858 int ret;
859
860 if (mode < 0)
861 mode = 0;
862
863 if (mode > 4)
864 mode = 4;
865
866 buf = mode & 0x07; /* just the lowest three bits */
867
868 ret = send_control_msg(pdev,
869 SET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
870
871 if (ret < 0)
872 return ret;
873 return 0;
874}
875
876int pwc_get_awb(struct pwc_device *pdev)
877{
878 unsigned char buf;
879 int ret;
880
881 ret = recv_control_msg(pdev,
882 GET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
883
884 if (ret < 0)
885 return ret;
886 return buf;
887}
888
889int pwc_set_red_gain(struct pwc_device *pdev, int value)
890{
891 unsigned char buf;
892
893 if (value < 0)
894 value = 0;
895 if (value > 0xffff)
896 value = 0xffff;
897 /* only the msb is considered */
898 buf = value >> 8;
899 return send_control_msg(pdev,
900 SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
901 &buf, sizeof(buf));
902}
903
904int pwc_get_red_gain(struct pwc_device *pdev, int *value)
905{
906 unsigned char buf;
907 int ret;
908
909 ret = recv_control_msg(pdev,
910 GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
911 &buf, sizeof(buf));
912 if (ret < 0)
913 return ret;
914 *value = buf << 8;
915 return 0;
916}
917
918
919int pwc_set_blue_gain(struct pwc_device *pdev, int value)
920{
921 unsigned char buf;
922
923 if (value < 0)
924 value = 0;
925 if (value > 0xffff)
926 value = 0xffff;
927 /* only the msb is considered */
928 buf = value >> 8;
929 return send_control_msg(pdev,
930 SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
931 &buf, sizeof(buf));
932}
933
934int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
935{
936 unsigned char buf;
937 int ret;
938
939 ret = recv_control_msg(pdev,
940 GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
941 &buf, sizeof(buf));
942 if (ret < 0)
943 return ret;
944 *value = buf << 8;
945 return 0;
946}
947
948 595
949/* The following two functions are different, since they only read the 596 if (r < 0)
950 internal red/blue gains, which may be different from the manual 597 PWC_ERROR("Failed to power %s camera (%d)\n",
951 gains set or read above. 598 power ? "on" : "off", r);
952 */
953static int pwc_read_red_gain(struct pwc_device *pdev, int *value)
954{
955 unsigned char buf;
956 int ret;
957
958 ret = recv_control_msg(pdev,
959 GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, &buf, sizeof(buf));
960 if (ret < 0)
961 return ret;
962 *value = buf << 8;
963 return 0;
964} 599}
965 600
966static int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
967{
968 unsigned char buf;
969 int ret;
970
971 ret = recv_control_msg(pdev,
972 GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, &buf, sizeof(buf));
973 if (ret < 0)
974 return ret;
975 *value = buf << 8;
976 return 0;
977}
978
979
980static int pwc_set_wb_speed(struct pwc_device *pdev, int speed) 601static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
981{ 602{
982 unsigned char buf; 603 unsigned char buf;
@@ -1028,6 +649,7 @@ static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
1028int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) 649int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
1029{ 650{
1030 unsigned char buf[2]; 651 unsigned char buf[2];
652 int r;
1031 653
1032 if (pdev->type < 730) 654 if (pdev->type < 730)
1033 return 0; 655 return 0;
@@ -1045,8 +667,12 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
1045 buf[0] = on_value; 667 buf[0] = on_value;
1046 buf[1] = off_value; 668 buf[1] = off_value;
1047 669
1048 return send_control_msg(pdev, 670 r = send_control_msg(pdev,
1049 SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf)); 671 SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
672 if (r < 0)
673 PWC_ERROR("Failed to set LED on/off time (%d)\n", r);
674
675 return r;
1050} 676}
1051 677
1052static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value) 678static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
@@ -1069,164 +695,6 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
1069 return 0; 695 return 0;
1070} 696}
1071 697
1072int pwc_set_contour(struct pwc_device *pdev, int contour)
1073{
1074 unsigned char buf;
1075 int ret;
1076
1077 if (contour < 0)
1078 buf = 0xff; /* auto contour on */
1079 else
1080 buf = 0x0; /* auto contour off */
1081 ret = send_control_msg(pdev,
1082 SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
1083 if (ret < 0)
1084 return ret;
1085
1086 if (contour < 0)
1087 return 0;
1088 if (contour > 0xffff)
1089 contour = 0xffff;
1090
1091 buf = (contour >> 10); /* contour preset is [0..3f] */
1092 ret = send_control_msg(pdev,
1093 SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &buf, sizeof(buf));
1094 if (ret < 0)
1095 return ret;
1096 return 0;
1097}
1098
1099int pwc_get_contour(struct pwc_device *pdev, int *contour)
1100{
1101 unsigned char buf;
1102 int ret;
1103
1104 ret = recv_control_msg(pdev,
1105 GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
1106 if (ret < 0)
1107 return ret;
1108
1109 if (buf == 0) {
1110 /* auto mode off, query current preset value */
1111 ret = recv_control_msg(pdev,
1112 GET_LUM_CTL, PRESET_CONTOUR_FORMATTER,
1113 &buf, sizeof(buf));
1114 if (ret < 0)
1115 return ret;
1116 *contour = buf << 10;
1117 }
1118 else
1119 *contour = -1;
1120 return 0;
1121}
1122
1123
1124int pwc_set_backlight(struct pwc_device *pdev, int backlight)
1125{
1126 unsigned char buf;
1127
1128 if (backlight)
1129 buf = 0xff;
1130 else
1131 buf = 0x0;
1132 return send_control_msg(pdev,
1133 SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
1134 &buf, sizeof(buf));
1135}
1136
1137int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
1138{
1139 int ret;
1140 unsigned char buf;
1141
1142 ret = recv_control_msg(pdev,
1143 GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
1144 &buf, sizeof(buf));
1145 if (ret < 0)
1146 return ret;
1147 *backlight = !!buf;
1148 return 0;
1149}
1150
1151int pwc_set_colour_mode(struct pwc_device *pdev, int colour)
1152{
1153 unsigned char buf;
1154
1155 if (colour)
1156 buf = 0xff;
1157 else
1158 buf = 0x0;
1159 return send_control_msg(pdev,
1160 SET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
1161}
1162
1163int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
1164{
1165 int ret;
1166 unsigned char buf;
1167
1168 ret = recv_control_msg(pdev,
1169 GET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
1170 if (ret < 0)
1171 return ret;
1172 *colour = !!buf;
1173 return 0;
1174}
1175
1176
1177int pwc_set_flicker(struct pwc_device *pdev, int flicker)
1178{
1179 unsigned char buf;
1180
1181 if (flicker)
1182 buf = 0xff;
1183 else
1184 buf = 0x0;
1185 return send_control_msg(pdev,
1186 SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
1187}
1188
1189int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
1190{
1191 int ret;
1192 unsigned char buf;
1193
1194 ret = recv_control_msg(pdev,
1195 GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
1196 if (ret < 0)
1197 return ret;
1198 *flicker = !!buf;
1199 return 0;
1200}
1201
1202int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1203{
1204 unsigned char buf;
1205
1206 if (noise < 0)
1207 noise = 0;
1208 if (noise > 3)
1209 noise = 3;
1210 buf = noise;
1211 return send_control_msg(pdev,
1212 SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
1213 &buf, sizeof(buf));
1214}
1215
1216int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
1217{
1218 int ret;
1219 unsigned char buf;
1220
1221 ret = recv_control_msg(pdev,
1222 GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
1223 &buf, sizeof(buf));
1224 if (ret < 0)
1225 return ret;
1226 *noise = buf;
1227 return 0;
1228}
1229
1230static int _pwc_mpt_reset(struct pwc_device *pdev, int flags) 698static int _pwc_mpt_reset(struct pwc_device *pdev, int flags)
1231{ 699{
1232 unsigned char buf; 700 unsigned char buf;
@@ -1309,7 +777,7 @@ static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *st
1309 return 0; 777 return 0;
1310} 778}
1311 779
1312 780#ifdef CONFIG_USB_PWC_DEBUG
1313int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) 781int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1314{ 782{
1315 unsigned char buf; 783 unsigned char buf;
@@ -1332,7 +800,7 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1332 *sensor = buf; 800 *sensor = buf;
1333 return 0; 801 return 0;
1334} 802}
1335 803#endif
1336 804
1337 /* End of Add-Ons */ 805 /* End of Add-Ons */
1338 /* ************************************************* */ 806 /* ************************************************* */
@@ -1356,37 +824,41 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1356/* copy local variable to arg */ 824/* copy local variable to arg */
1357#define ARG_OUT(ARG_name) /* nothing */ 825#define ARG_OUT(ARG_name) /* nothing */
1358 826
827/*
828 * Our ctrls use native values, but the old custom pwc ioctl interface expects
829 * values from 0 - 65535, define 2 helper functions to scale things. */
830static int pwc_ioctl_g_ctrl(struct v4l2_ctrl *ctrl)
831{
832 return v4l2_ctrl_g_ctrl(ctrl) * 65535 / ctrl->maximum;
833}
834
835static int pwc_ioctl_s_ctrl(struct v4l2_ctrl *ctrl, int val)
836{
837 return v4l2_ctrl_s_ctrl(ctrl, val * ctrl->maximum / 65535);
838}
839
1359long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) 840long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1360{ 841{
1361 long ret = 0; 842 long ret = 0;
1362 843
1363 switch(cmd) { 844 switch(cmd) {
1364 case VIDIOCPWCRUSER: 845 case VIDIOCPWCRUSER:
1365 { 846 ret = pwc_button_ctrl(pdev, RESTORE_USER_DEFAULTS_FORMATTER);
1366 if (pwc_restore_user(pdev))
1367 ret = -EINVAL;
1368 break; 847 break;
1369 }
1370 848
1371 case VIDIOCPWCSUSER: 849 case VIDIOCPWCSUSER:
1372 { 850 ret = pwc_button_ctrl(pdev, SAVE_USER_DEFAULTS_FORMATTER);
1373 if (pwc_save_user(pdev))
1374 ret = -EINVAL;
1375 break; 851 break;
1376 }
1377 852
1378 case VIDIOCPWCFACTORY: 853 case VIDIOCPWCFACTORY:
1379 { 854 ret = pwc_button_ctrl(pdev, RESTORE_FACTORY_DEFAULTS_FORMATTER);
1380 if (pwc_restore_factory(pdev))
1381 ret = -EINVAL;
1382 break; 855 break;
1383 }
1384 856
1385 case VIDIOCPWCSCQUAL: 857 case VIDIOCPWCSCQUAL:
1386 { 858 {
1387 ARG_DEF(int, qual) 859 ARG_DEF(int, qual)
1388 860
1389 if (pdev->iso_init) { 861 if (vb2_is_streaming(&pdev->vb_queue)) {
1390 ret = -EBUSY; 862 ret = -EBUSY;
1391 break; 863 break;
1392 } 864 }
@@ -1396,8 +868,6 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1396 ret = -EINVAL; 868 ret = -EINVAL;
1397 else 869 else
1398 ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); 870 ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
1399 if (ret >= 0)
1400 pdev->vcompression = ARGR(qual);
1401 break; 871 break;
1402 } 872 }
1403 873
@@ -1432,71 +902,59 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1432 case VIDIOCPWCSAGC: 902 case VIDIOCPWCSAGC:
1433 { 903 {
1434 ARG_DEF(int, agc) 904 ARG_DEF(int, agc)
1435
1436 ARG_IN(agc) 905 ARG_IN(agc)
1437 if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc))) 906 ret = v4l2_ctrl_s_ctrl(pdev->autogain, ARGR(agc) < 0);
1438 ret = -EINVAL; 907 if (ret == 0 && ARGR(agc) >= 0)
908 ret = pwc_ioctl_s_ctrl(pdev->gain, ARGR(agc));
1439 break; 909 break;
1440 } 910 }
1441 911
1442 case VIDIOCPWCGAGC: 912 case VIDIOCPWCGAGC:
1443 { 913 {
1444 ARG_DEF(int, agc) 914 ARG_DEF(int, agc)
1445 915 if (v4l2_ctrl_g_ctrl(pdev->autogain))
1446 if (pwc_get_agc(pdev, ARGA(agc))) 916 ARGR(agc) = -1;
1447 ret = -EINVAL; 917 else
918 ARGR(agc) = pwc_ioctl_g_ctrl(pdev->gain);
1448 ARG_OUT(agc) 919 ARG_OUT(agc)
1449 break; 920 break;
1450 } 921 }
1451 922
1452 case VIDIOCPWCSSHUTTER: 923 case VIDIOCPWCSSHUTTER:
1453 { 924 {
1454 ARG_DEF(int, shutter_speed) 925 ARG_DEF(int, shutter)
1455 926 ARG_IN(shutter)
1456 ARG_IN(shutter_speed) 927 ret = v4l2_ctrl_s_ctrl(pdev->exposure_auto,
1457 ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed)); 928 /* Menu idx 0 = auto, idx 1 = manual */
929 ARGR(shutter) >= 0);
930 if (ret == 0 && ARGR(shutter) >= 0)
931 ret = pwc_ioctl_s_ctrl(pdev->exposure, ARGR(shutter));
1458 break; 932 break;
1459 } 933 }
1460 934
1461 case VIDIOCPWCSAWB: 935 case VIDIOCPWCSAWB:
1462 { 936 {
1463 ARG_DEF(struct pwc_whitebalance, wb) 937 ARG_DEF(struct pwc_whitebalance, wb)
1464
1465 ARG_IN(wb) 938 ARG_IN(wb)
1466 ret = pwc_set_awb(pdev, ARGR(wb).mode); 939 ret = v4l2_ctrl_s_ctrl(pdev->auto_white_balance,
1467 if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) { 940 ARGR(wb).mode);
1468 pwc_set_red_gain(pdev, ARGR(wb).manual_red); 941 if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL)
1469 pwc_set_blue_gain(pdev, ARGR(wb).manual_blue); 942 ret = pwc_ioctl_s_ctrl(pdev->red_balance,
1470 } 943 ARGR(wb).manual_red);
944 if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL)
945 ret = pwc_ioctl_s_ctrl(pdev->blue_balance,
946 ARGR(wb).manual_blue);
1471 break; 947 break;
1472 } 948 }
1473 949
1474 case VIDIOCPWCGAWB: 950 case VIDIOCPWCGAWB:
1475 { 951 {
1476 ARG_DEF(struct pwc_whitebalance, wb) 952 ARG_DEF(struct pwc_whitebalance, wb)
1477 953 ARGR(wb).mode = v4l2_ctrl_g_ctrl(pdev->auto_white_balance);
1478 memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance)); 954 ARGR(wb).manual_red = ARGR(wb).read_red =
1479 ARGR(wb).mode = pwc_get_awb(pdev); 955 pwc_ioctl_g_ctrl(pdev->red_balance);
1480 if (ARGR(wb).mode < 0) 956 ARGR(wb).manual_blue = ARGR(wb).read_blue =
1481 ret = -EINVAL; 957 pwc_ioctl_g_ctrl(pdev->blue_balance);
1482 else {
1483 if (ARGR(wb).mode == PWC_WB_MANUAL) {
1484 ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red);
1485 if (ret < 0)
1486 break;
1487 ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue);
1488 if (ret < 0)
1489 break;
1490 }
1491 if (ARGR(wb).mode == PWC_WB_AUTO) {
1492 ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
1493 if (ret < 0)
1494 break;
1495 ret = pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
1496 if (ret < 0)
1497 break;
1498 }
1499 }
1500 ARG_OUT(wb) 958 ARG_OUT(wb)
1501 break; 959 break;
1502 } 960 }
@@ -1550,17 +1008,20 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1550 case VIDIOCPWCSCONTOUR: 1008 case VIDIOCPWCSCONTOUR:
1551 { 1009 {
1552 ARG_DEF(int, contour) 1010 ARG_DEF(int, contour)
1553
1554 ARG_IN(contour) 1011 ARG_IN(contour)
1555 ret = pwc_set_contour(pdev, ARGR(contour)); 1012 ret = v4l2_ctrl_s_ctrl(pdev->autocontour, ARGR(contour) < 0);
1013 if (ret == 0 && ARGR(contour) >= 0)
1014 ret = pwc_ioctl_s_ctrl(pdev->contour, ARGR(contour));
1556 break; 1015 break;
1557 } 1016 }
1558 1017
1559 case VIDIOCPWCGCONTOUR: 1018 case VIDIOCPWCGCONTOUR:
1560 { 1019 {
1561 ARG_DEF(int, contour) 1020 ARG_DEF(int, contour)
1562 1021 if (v4l2_ctrl_g_ctrl(pdev->autocontour))
1563 ret = pwc_get_contour(pdev, ARGA(contour)); 1022 ARGR(contour) = -1;
1023 else
1024 ARGR(contour) = pwc_ioctl_g_ctrl(pdev->contour);
1564 ARG_OUT(contour) 1025 ARG_OUT(contour)
1565 break; 1026 break;
1566 } 1027 }
@@ -1568,17 +1029,15 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1568 case VIDIOCPWCSBACKLIGHT: 1029 case VIDIOCPWCSBACKLIGHT:
1569 { 1030 {
1570 ARG_DEF(int, backlight) 1031 ARG_DEF(int, backlight)
1571
1572 ARG_IN(backlight) 1032 ARG_IN(backlight)
1573 ret = pwc_set_backlight(pdev, ARGR(backlight)); 1033 ret = v4l2_ctrl_s_ctrl(pdev->backlight, ARGR(backlight));
1574 break; 1034 break;
1575 } 1035 }
1576 1036
1577 case VIDIOCPWCGBACKLIGHT: 1037 case VIDIOCPWCGBACKLIGHT:
1578 { 1038 {
1579 ARG_DEF(int, backlight) 1039 ARG_DEF(int, backlight)
1580 1040 ARGR(backlight) = v4l2_ctrl_g_ctrl(pdev->backlight);
1581 ret = pwc_get_backlight(pdev, ARGA(backlight));
1582 ARG_OUT(backlight) 1041 ARG_OUT(backlight)
1583 break; 1042 break;
1584 } 1043 }
@@ -1586,17 +1045,15 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1586 case VIDIOCPWCSFLICKER: 1045 case VIDIOCPWCSFLICKER:
1587 { 1046 {
1588 ARG_DEF(int, flicker) 1047 ARG_DEF(int, flicker)
1589
1590 ARG_IN(flicker) 1048 ARG_IN(flicker)
1591 ret = pwc_set_flicker(pdev, ARGR(flicker)); 1049 ret = v4l2_ctrl_s_ctrl(pdev->flicker, ARGR(flicker));
1592 break; 1050 break;
1593 } 1051 }
1594 1052
1595 case VIDIOCPWCGFLICKER: 1053 case VIDIOCPWCGFLICKER:
1596 { 1054 {
1597 ARG_DEF(int, flicker) 1055 ARG_DEF(int, flicker)
1598 1056 ARGR(flicker) = v4l2_ctrl_g_ctrl(pdev->flicker);
1599 ret = pwc_get_flicker(pdev, ARGA(flicker));
1600 ARG_OUT(flicker) 1057 ARG_OUT(flicker)
1601 break; 1058 break;
1602 } 1059 }
@@ -1604,17 +1061,15 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1604 case VIDIOCPWCSDYNNOISE: 1061 case VIDIOCPWCSDYNNOISE:
1605 { 1062 {
1606 ARG_DEF(int, dynnoise) 1063 ARG_DEF(int, dynnoise)
1607
1608 ARG_IN(dynnoise) 1064 ARG_IN(dynnoise)
1609 ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise)); 1065 ret = v4l2_ctrl_s_ctrl(pdev->noise_reduction, ARGR(dynnoise));
1610 break; 1066 break;
1611 } 1067 }
1612 1068
1613 case VIDIOCPWCGDYNNOISE: 1069 case VIDIOCPWCGDYNNOISE:
1614 { 1070 {
1615 ARG_DEF(int, dynnoise) 1071 ARG_DEF(int, dynnoise)
1616 1072 ARGR(dynnoise) = v4l2_ctrl_g_ctrl(pdev->noise_reduction);
1617 ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise));
1618 ARG_OUT(dynnoise); 1073 ARG_OUT(dynnoise);
1619 break; 1074 break;
1620 } 1075 }
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/video/pwc/pwc-dec1.c
index c29593f589eb..be0e02cb487f 100644
--- a/drivers/media/video/pwc/pwc-dec1.c
+++ b/drivers/media/video/pwc/pwc-dec1.c
@@ -22,29 +22,19 @@
22 along with this program; if not, write to the Free Software 22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24*/ 24*/
25
26
27
28#include "pwc-dec1.h" 25#include "pwc-dec1.h"
29 26
30 27int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer)
31void pwc_dec1_init(int type, int release, void *buffer, void *table)
32{ 28{
29 struct pwc_dec1_private *pdec;
33 30
34} 31 if (pwc->decompress_data == NULL) {
35 32 pdec = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL);
36void pwc_dec1_exit(void) 33 if (pdec == NULL)
37{ 34 return -ENOMEM;
35 pwc->decompress_data = pdec;
36 }
37 pdec = pwc->decompress_data;
38 38
39
40
41}
42
43int pwc_dec1_alloc(struct pwc_device *pwc)
44{
45 pwc->decompress_data = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL);
46 if (pwc->decompress_data == NULL)
47 return -ENOMEM;
48 return 0; 39 return 0;
49} 40}
50
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h
index 8b62ddcc5c7e..a57d8601080b 100644
--- a/drivers/media/video/pwc/pwc-dec1.h
+++ b/drivers/media/video/pwc/pwc-dec1.h
@@ -22,8 +22,6 @@
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/ 23*/
24 24
25
26
27#ifndef PWC_DEC1_H 25#ifndef PWC_DEC1_H
28#define PWC_DEC1_H 26#define PWC_DEC1_H
29 27
@@ -32,12 +30,8 @@
32struct pwc_dec1_private 30struct pwc_dec1_private
33{ 31{
34 int version; 32 int version;
35
36}; 33};
37 34
38int pwc_dec1_alloc(struct pwc_device *pwc); 35int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer);
39void pwc_dec1_init(int type, int release, void *buffer, void *private_data);
40void pwc_dec1_exit(void);
41 36
42#endif 37#endif
43
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
index 0c801b8f3eca..06a4e877ba40 100644
--- a/drivers/media/video/pwc/pwc-dec23.c
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -916,27 +916,5 @@ void pwc_dec23_decompress(const struct pwc_device *pwc,
916 pout_planar_v += pwc->view.x; 916 pout_planar_v += pwc->view.x;
917 917
918 } 918 }
919
920 } 919 }
921
922} 920}
923
924void pwc_dec23_exit(void)
925{
926 /* Do nothing */
927
928}
929
930/**
931 * Allocate a private structure used by lookup table.
932 * You must call kfree() to free the memory allocated.
933 */
934int pwc_dec23_alloc(struct pwc_device *pwc)
935{
936 pwc->decompress_data = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
937 if (pwc->decompress_data == NULL)
938 return -ENOMEM;
939 return 0;
940}
941
942/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h
index 1c55298ad153..a0ac4f3dff81 100644
--- a/drivers/media/video/pwc/pwc-dec23.h
+++ b/drivers/media/video/pwc/pwc-dec23.h
@@ -49,19 +49,9 @@ struct pwc_dec23_private
49 49
50}; 50};
51 51
52
53int pwc_dec23_alloc(struct pwc_device *pwc);
54int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd); 52int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd);
55void pwc_dec23_exit(void);
56void pwc_dec23_decompress(const struct pwc_device *pwc, 53void pwc_dec23_decompress(const struct pwc_device *pwc,
57 const void *src, 54 const void *src,
58 void *dst, 55 void *dst,
59 int flags); 56 int flags);
60
61
62
63#endif 57#endif
64
65
66/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
67
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index b0bde5a87c8a..51ca3589b1b5 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -2,6 +2,7 @@
2 USB and Video4Linux interface part. 2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv. 3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004-2006 Luc Saillard (luc@saillard.org) 4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 (C) 2011 Hans de Goede <hdegoede@redhat.com>
5 6
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version. 8 driver and thus may have bugs that are not present in the original version.
@@ -74,7 +75,6 @@
74#include "pwc-timon.h" 75#include "pwc-timon.h"
75#include "pwc-dec23.h" 76#include "pwc-dec23.h"
76#include "pwc-dec1.h" 77#include "pwc-dec1.h"
77#include "pwc-uncompress.h"
78 78
79/* Function prototypes and driver templates */ 79/* Function prototypes and driver templates */
80 80
@@ -116,6 +116,7 @@ MODULE_DEVICE_TABLE(usb, pwc_device_table);
116 116
117static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id); 117static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
118static void usb_pwc_disconnect(struct usb_interface *intf); 118static void usb_pwc_disconnect(struct usb_interface *intf);
119static void pwc_isoc_cleanup(struct pwc_device *pdev);
119 120
120static struct usb_driver pwc_driver = { 121static struct usb_driver pwc_driver = {
121 .name = "Philips webcam", /* name */ 122 .name = "Philips webcam", /* name */
@@ -127,14 +128,11 @@ static struct usb_driver pwc_driver = {
127#define MAX_DEV_HINTS 20 128#define MAX_DEV_HINTS 20
128#define MAX_ISOC_ERRORS 20 129#define MAX_ISOC_ERRORS 20
129 130
130static int default_size = PSZ_QCIF;
131static int default_fps = 10; 131static int default_fps = 10;
132static int default_fbufs = 3; /* Default number of frame buffers */
133 int pwc_mbufs = 2; /* Default number of mmap() buffers */
134#ifdef CONFIG_USB_PWC_DEBUG 132#ifdef CONFIG_USB_PWC_DEBUG
135 int pwc_trace = PWC_DEBUG_LEVEL; 133 int pwc_trace = PWC_DEBUG_LEVEL;
136#endif 134#endif
137static int power_save; 135static int power_save = -1;
138static int led_on = 100, led_off; /* defaults to LED that is on while in use */ 136static int led_on = 100, led_off; /* defaults to LED that is on while in use */
139static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */ 137static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */
140static struct { 138static struct {
@@ -173,389 +171,20 @@ static struct video_device pwc_template = {
173/***************************************************************************/ 171/***************************************************************************/
174/* Private functions */ 172/* Private functions */
175 173
176/* Here we want the physical address of the memory. 174struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev)
177 * This is used when initializing the contents of the area.
178 */
179
180
181
182static void *pwc_rvmalloc(unsigned long size)
183{
184 void * mem;
185 unsigned long adr;
186
187 mem=vmalloc_32(size);
188 if (!mem)
189 return NULL;
190
191 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
192 adr=(unsigned long) mem;
193 while (size > 0)
194 {
195 SetPageReserved(vmalloc_to_page((void *)adr));
196 adr += PAGE_SIZE;
197 size -= PAGE_SIZE;
198 }
199 return mem;
200}
201
202static void pwc_rvfree(void * mem, unsigned long size)
203{
204 unsigned long adr;
205
206 if (!mem)
207 return;
208
209 adr=(unsigned long) mem;
210 while ((long) size > 0)
211 {
212 ClearPageReserved(vmalloc_to_page((void *)adr));
213 adr += PAGE_SIZE;
214 size -= PAGE_SIZE;
215 }
216 vfree(mem);
217}
218
219
220
221
222static int pwc_allocate_buffers(struct pwc_device *pdev)
223{
224 int i, err;
225 void *kbuf;
226
227 PWC_DEBUG_MEMORY(">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev);
228
229 if (pdev == NULL)
230 return -ENXIO;
231
232 /* Allocate Isochronuous pipe buffers */
233 for (i = 0; i < MAX_ISO_BUFS; i++) {
234 if (pdev->sbuf[i].data == NULL) {
235 kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
236 if (kbuf == NULL) {
237 PWC_ERROR("Failed to allocate iso buffer %d.\n", i);
238 return -ENOMEM;
239 }
240 PWC_DEBUG_MEMORY("Allocated iso buffer at %p.\n", kbuf);
241 pdev->sbuf[i].data = kbuf;
242 }
243 }
244
245 /* Allocate frame buffer structure */
246 if (pdev->fbuf == NULL) {
247 kbuf = kzalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL);
248 if (kbuf == NULL) {
249 PWC_ERROR("Failed to allocate frame buffer structure.\n");
250 return -ENOMEM;
251 }
252 PWC_DEBUG_MEMORY("Allocated frame buffer structure at %p.\n", kbuf);
253 pdev->fbuf = kbuf;
254 }
255
256 /* create frame buffers, and make circular ring */
257 for (i = 0; i < default_fbufs; i++) {
258 if (pdev->fbuf[i].data == NULL) {
259 kbuf = vzalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
260 if (kbuf == NULL) {
261 PWC_ERROR("Failed to allocate frame buffer %d.\n", i);
262 return -ENOMEM;
263 }
264 PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf);
265 pdev->fbuf[i].data = kbuf;
266 }
267 }
268
269 /* Allocate decompressor table space */
270 if (DEVICE_USE_CODEC1(pdev->type))
271 err = pwc_dec1_alloc(pdev);
272 else
273 err = pwc_dec23_alloc(pdev);
274
275 if (err) {
276 PWC_ERROR("Failed to allocate decompress table.\n");
277 return err;
278 }
279
280 /* Allocate image buffer; double buffer for mmap() */
281 kbuf = pwc_rvmalloc(pwc_mbufs * pdev->len_per_image);
282 if (kbuf == NULL) {
283 PWC_ERROR("Failed to allocate image buffer(s). needed (%d)\n",
284 pwc_mbufs * pdev->len_per_image);
285 return -ENOMEM;
286 }
287 PWC_DEBUG_MEMORY("Allocated image buffer at %p.\n", kbuf);
288 pdev->image_data = kbuf;
289 for (i = 0; i < pwc_mbufs; i++) {
290 pdev->images[i].offset = i * pdev->len_per_image;
291 pdev->images[i].vma_use_count = 0;
292 }
293 for (; i < MAX_IMAGES; i++) {
294 pdev->images[i].offset = 0;
295 }
296
297 kbuf = NULL;
298
299 PWC_DEBUG_MEMORY("<< pwc_allocate_buffers()\n");
300 return 0;
301}
302
303static void pwc_free_buffers(struct pwc_device *pdev)
304{
305 int i;
306
307 PWC_DEBUG_MEMORY("Entering free_buffers(%p).\n", pdev);
308
309 if (pdev == NULL)
310 return;
311 /* Release Iso-pipe buffers */
312 for (i = 0; i < MAX_ISO_BUFS; i++)
313 if (pdev->sbuf[i].data != NULL) {
314 PWC_DEBUG_MEMORY("Freeing ISO buffer at %p.\n", pdev->sbuf[i].data);
315 kfree(pdev->sbuf[i].data);
316 pdev->sbuf[i].data = NULL;
317 }
318
319 /* The same for frame buffers */
320 if (pdev->fbuf != NULL) {
321 for (i = 0; i < default_fbufs; i++) {
322 if (pdev->fbuf[i].data != NULL) {
323 PWC_DEBUG_MEMORY("Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data);
324 vfree(pdev->fbuf[i].data);
325 pdev->fbuf[i].data = NULL;
326 }
327 }
328 kfree(pdev->fbuf);
329 pdev->fbuf = NULL;
330 }
331
332 /* Intermediate decompression buffer & tables */
333 if (pdev->decompress_data != NULL) {
334 PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n", pdev->decompress_data);
335 kfree(pdev->decompress_data);
336 pdev->decompress_data = NULL;
337 }
338
339 /* Release image buffers */
340 if (pdev->image_data != NULL) {
341 PWC_DEBUG_MEMORY("Freeing image buffer at %p.\n", pdev->image_data);
342 pwc_rvfree(pdev->image_data, pwc_mbufs * pdev->len_per_image);
343 }
344 pdev->image_data = NULL;
345
346 PWC_DEBUG_MEMORY("Leaving free_buffers().\n");
347}
348
349/* The frame & image buffer mess.
350
351 Yes, this is a mess. Well, it used to be simple, but alas... In this
352 module, 3 buffers schemes are used to get the data from the USB bus to
353 the user program. The first scheme involves the ISO buffers (called thus
354 since they transport ISO data from the USB controller), and not really
355 interesting. Suffices to say the data from this buffer is quickly
356 gathered in an interrupt handler (pwc_isoc_handler) and placed into the
357 frame buffer.
358
359 The frame buffer is the second scheme, and is the central element here.
360 It collects the data from a single frame from the camera (hence, the
361 name). Frames are delimited by the USB camera with a short USB packet,
362 so that's easy to detect. The frame buffers form a list that is filled
363 by the camera+USB controller and drained by the user process through
364 either read() or mmap().
365
366 The image buffer is the third scheme, in which frames are decompressed
367 and converted into planar format. For mmap() there is more than
368 one image buffer available.
369
370 The frame buffers provide the image buffering. In case the user process
371 is a bit slow, this introduces lag and some undesired side-effects.
372 The problem arises when the frame buffer is full. I used to drop the last
373 frame, which makes the data in the queue stale very quickly. But dropping
374 the frame at the head of the queue proved to be a litte bit more difficult.
375 I tried a circular linked scheme, but this introduced more problems than
376 it solved.
377
378 Because filling and draining are completely asynchronous processes, this
379 requires some fiddling with pointers and mutexes.
380
381 Eventually, I came up with a system with 2 lists: an 'empty' frame list
382 and a 'full' frame list:
383 * Initially, all frame buffers but one are on the 'empty' list; the one
384 remaining buffer is our initial fill frame.
385 * If a frame is needed for filling, we try to take it from the 'empty'
386 list, unless that list is empty, in which case we take the buffer at
387 the head of the 'full' list.
388 * When our fill buffer has been filled, it is appended to the 'full'
389 list.
390 * If a frame is needed by read() or mmap(), it is taken from the head of
391 the 'full' list, handled, and then appended to the 'empty' list. If no
392 buffer is present on the 'full' list, we wait.
393 The advantage is that the buffer that is currently being decompressed/
394 converted, is on neither list, and thus not in our way (any other scheme
395 I tried had the problem of old data lingering in the queue).
396
397 Whatever strategy you choose, it always remains a tradeoff: with more
398 frame buffers the chances of a missed frame are reduced. On the other
399 hand, on slower machines it introduces lag because the queue will
400 always be full.
401 */
402
403/**
404 \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first.
405 */
406static int pwc_next_fill_frame(struct pwc_device *pdev)
407{
408 int ret;
409 unsigned long flags;
410
411 ret = 0;
412 spin_lock_irqsave(&pdev->ptrlock, flags);
413 if (pdev->fill_frame != NULL) {
414 /* append to 'full' list */
415 if (pdev->full_frames == NULL) {
416 pdev->full_frames = pdev->fill_frame;
417 pdev->full_frames_tail = pdev->full_frames;
418 }
419 else {
420 pdev->full_frames_tail->next = pdev->fill_frame;
421 pdev->full_frames_tail = pdev->fill_frame;
422 }
423 }
424 if (pdev->empty_frames != NULL) {
425 /* We have empty frames available. That's easy */
426 pdev->fill_frame = pdev->empty_frames;
427 pdev->empty_frames = pdev->empty_frames->next;
428 }
429 else {
430 /* Hmm. Take it from the full list */
431 /* sanity check */
432 if (pdev->full_frames == NULL) {
433 PWC_ERROR("Neither empty or full frames available!\n");
434 spin_unlock_irqrestore(&pdev->ptrlock, flags);
435 return -EINVAL;
436 }
437 pdev->fill_frame = pdev->full_frames;
438 pdev->full_frames = pdev->full_frames->next;
439 ret = 1;
440 }
441 pdev->fill_frame->next = NULL;
442 spin_unlock_irqrestore(&pdev->ptrlock, flags);
443 return ret;
444}
445
446
447/**
448 \brief Reset all buffers, pointers and lists, except for the image_used[] buffer.
449
450 If the image_used[] buffer is cleared too, mmap()/VIDIOCSYNC will run into trouble.
451 */
452static void pwc_reset_buffers(struct pwc_device *pdev)
453{
454 int i;
455 unsigned long flags;
456
457 PWC_DEBUG_MEMORY(">> %s __enter__\n", __func__);
458
459 spin_lock_irqsave(&pdev->ptrlock, flags);
460 pdev->full_frames = NULL;
461 pdev->full_frames_tail = NULL;
462 for (i = 0; i < default_fbufs; i++) {
463 pdev->fbuf[i].filled = 0;
464 if (i > 0)
465 pdev->fbuf[i].next = &pdev->fbuf[i - 1];
466 else
467 pdev->fbuf->next = NULL;
468 }
469 pdev->empty_frames = &pdev->fbuf[default_fbufs - 1];
470 pdev->empty_frames_tail = pdev->fbuf;
471 pdev->read_frame = NULL;
472 pdev->fill_frame = pdev->empty_frames;
473 pdev->empty_frames = pdev->empty_frames->next;
474
475 pdev->image_read_pos = 0;
476 pdev->fill_image = 0;
477 spin_unlock_irqrestore(&pdev->ptrlock, flags);
478
479 PWC_DEBUG_MEMORY("<< %s __leaving__\n", __func__);
480}
481
482
483/**
484 \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers.
485 */
486int pwc_handle_frame(struct pwc_device *pdev)
487{ 175{
488 int ret = 0; 176 unsigned long flags = 0;
489 unsigned long flags; 177 struct pwc_frame_buf *buf = NULL;
490 178
491 spin_lock_irqsave(&pdev->ptrlock, flags); 179 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
492 /* First grab our read_frame; this is removed from all lists, so 180 if (list_empty(&pdev->queued_bufs))
493 we can release the lock after this without problems */ 181 goto leave;
494 if (pdev->read_frame != NULL) { 182
495 /* This can't theoretically happen */ 183 buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, list);
496 PWC_ERROR("Huh? Read frame still in use?\n"); 184 list_del(&buf->list);
497 spin_unlock_irqrestore(&pdev->ptrlock, flags); 185leave:
498 return ret; 186 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
499 } 187 return buf;
500
501
502 if (pdev->full_frames == NULL) {
503 PWC_ERROR("Woops. No frames ready.\n");
504 }
505 else {
506 pdev->read_frame = pdev->full_frames;
507 pdev->full_frames = pdev->full_frames->next;
508 pdev->read_frame->next = NULL;
509 }
510
511 if (pdev->read_frame != NULL) {
512 /* Decompression is a lengthy process, so it's outside of the lock.
513 This gives the isoc_handler the opportunity to fill more frames
514 in the mean time.
515 */
516 spin_unlock_irqrestore(&pdev->ptrlock, flags);
517 ret = pwc_decompress(pdev);
518 spin_lock_irqsave(&pdev->ptrlock, flags);
519
520 /* We're done with read_buffer, tack it to the end of the empty buffer list */
521 if (pdev->empty_frames == NULL) {
522 pdev->empty_frames = pdev->read_frame;
523 pdev->empty_frames_tail = pdev->empty_frames;
524 }
525 else {
526 pdev->empty_frames_tail->next = pdev->read_frame;
527 pdev->empty_frames_tail = pdev->read_frame;
528 }
529 pdev->read_frame = NULL;
530 }
531 spin_unlock_irqrestore(&pdev->ptrlock, flags);
532 return ret;
533}
534
535/**
536 \brief Advance pointers of image buffer (after each user request)
537*/
538void pwc_next_image(struct pwc_device *pdev)
539{
540 pdev->image_used[pdev->fill_image] = 0;
541 pdev->fill_image = (pdev->fill_image + 1) % pwc_mbufs;
542}
543
544/**
545 * Print debug information when a frame is discarded because all of our buffer
546 * is full
547 */
548static void pwc_frame_dumped(struct pwc_device *pdev)
549{
550 pdev->vframes_dumped++;
551 if (pdev->vframe_count < FRAME_LOWMARK)
552 return;
553
554 if (pdev->vframes_dumped < 20)
555 PWC_DEBUG_FLOW("Dumping frame %d\n", pdev->vframe_count);
556 else if (pdev->vframes_dumped == 20)
557 PWC_DEBUG_FLOW("Dumping frame %d (last message)\n",
558 pdev->vframe_count);
559} 188}
560 189
561static void pwc_snapshot_button(struct pwc_device *pdev, int down) 190static void pwc_snapshot_button(struct pwc_device *pdev, int down)
@@ -575,9 +204,9 @@ static void pwc_snapshot_button(struct pwc_device *pdev, int down)
575#endif 204#endif
576} 205}
577 206
578static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf) 207static void pwc_frame_complete(struct pwc_device *pdev)
579{ 208{
580 int awake = 0; 209 struct pwc_frame_buf *fbuf = pdev->fill_buf;
581 210
582 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus 211 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
583 frames on the USB wire after an exposure change. This conditition is 212 frames on the USB wire after an exposure change. This conditition is
@@ -589,7 +218,6 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
589 if (ptr[1] == 1 && ptr[0] & 0x10) { 218 if (ptr[1] == 1 && ptr[0] & 0x10) {
590 PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n"); 219 PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n");
591 pdev->drop_frames += 2; 220 pdev->drop_frames += 2;
592 pdev->vframes_error++;
593 } 221 }
594 if ((ptr[0] ^ pdev->vmirror) & 0x01) { 222 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
595 pwc_snapshot_button(pdev, ptr[0] & 0x01); 223 pwc_snapshot_button(pdev, ptr[0] & 0x01);
@@ -612,8 +240,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
612 */ 240 */
613 if (fbuf->filled == 4) 241 if (fbuf->filled == 4)
614 pdev->drop_frames++; 242 pdev->drop_frames++;
615 } 243 } else if (pdev->type == 740 || pdev->type == 720) {
616 else if (pdev->type == 740 || pdev->type == 720) {
617 unsigned char *ptr = (unsigned char *)fbuf->data; 244 unsigned char *ptr = (unsigned char *)fbuf->data;
618 if ((ptr[0] ^ pdev->vmirror) & 0x01) { 245 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
619 pwc_snapshot_button(pdev, ptr[0] & 0x01); 246 pwc_snapshot_button(pdev, ptr[0] & 0x01);
@@ -621,33 +248,23 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
621 pdev->vmirror = ptr[0] & 0x03; 248 pdev->vmirror = ptr[0] & 0x03;
622 } 249 }
623 250
624 /* In case we were instructed to drop the frame, do so silently. 251 /* In case we were instructed to drop the frame, do so silently. */
625 The buffer pointers are not updated either (but the counters are reset below). 252 if (pdev->drop_frames > 0) {
626 */
627 if (pdev->drop_frames > 0)
628 pdev->drop_frames--; 253 pdev->drop_frames--;
629 else { 254 } else {
630 /* Check for underflow first */ 255 /* Check for underflow first */
631 if (fbuf->filled < pdev->frame_total_size) { 256 if (fbuf->filled < pdev->frame_total_size) {
632 PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);" 257 PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);"
633 " discarded.\n", fbuf->filled); 258 " discarded.\n", fbuf->filled);
634 pdev->vframes_error++; 259 } else {
635 } 260 fbuf->vb.v4l2_buf.field = V4L2_FIELD_NONE;
636 else { 261 fbuf->vb.v4l2_buf.sequence = pdev->vframe_count;
637 /* Send only once per EOF */ 262 vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
638 awake = 1; /* delay wake_ups */ 263 pdev->fill_buf = NULL;
639 264 pdev->vsync = 0;
640 /* Find our next frame to fill. This will always succeed, since we
641 * nick a frame from either empty or full list, but if we had to
642 * take it from the full list, it means a frame got dropped.
643 */
644 if (pwc_next_fill_frame(pdev))
645 pwc_frame_dumped(pdev);
646
647 } 265 }
648 } /* !drop_frames */ 266 } /* !drop_frames */
649 pdev->vframe_count++; 267 pdev->vframe_count++;
650 return awake;
651} 268}
652 269
653/* This gets called for the Isochronous pipe (video). This is done in 270/* This gets called for the Isochronous pipe (video). This is done in
@@ -655,24 +272,20 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
655 */ 272 */
656static void pwc_isoc_handler(struct urb *urb) 273static void pwc_isoc_handler(struct urb *urb)
657{ 274{
658 struct pwc_device *pdev; 275 struct pwc_device *pdev = (struct pwc_device *)urb->context;
659 int i, fst, flen; 276 int i, fst, flen;
660 int awake; 277 unsigned char *iso_buf = NULL;
661 struct pwc_frame_buf *fbuf;
662 unsigned char *fillptr = NULL, *iso_buf = NULL;
663 278
664 awake = 0; 279 if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
665 pdev = (struct pwc_device *)urb->context; 280 urb->status == -ESHUTDOWN) {
666 if (pdev == NULL) {
667 PWC_ERROR("isoc_handler() called with NULL device?!\n");
668 return;
669 }
670
671 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
672 PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); 281 PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
673 return; 282 return;
674 } 283 }
675 if (urb->status != -EINPROGRESS && urb->status != 0) { 284
285 if (pdev->fill_buf == NULL)
286 pdev->fill_buf = pwc_get_next_fill_buf(pdev);
287
288 if (urb->status != 0) {
676 const char *errmsg; 289 const char *errmsg;
677 290
678 errmsg = "Unknown"; 291 errmsg = "Unknown";
@@ -684,29 +297,21 @@ static void pwc_isoc_handler(struct urb *urb)
684 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; 297 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
685 case -ETIME: errmsg = "Device does not respond"; break; 298 case -ETIME: errmsg = "Device does not respond"; break;
686 } 299 }
687 PWC_DEBUG_FLOW("pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); 300 PWC_ERROR("pwc_isoc_handler() called with status %d [%s].\n",
688 /* Give up after a number of contiguous errors on the USB bus. 301 urb->status, errmsg);
689 Appearantly something is wrong so we simulate an unplug event. 302 /* Give up after a number of contiguous errors */
690 */
691 if (++pdev->visoc_errors > MAX_ISOC_ERRORS) 303 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
692 { 304 {
693 PWC_INFO("Too many ISOC errors, bailing out.\n"); 305 PWC_ERROR("Too many ISOC errors, bailing out.\n");
694 pdev->error_status = EIO; 306 if (pdev->fill_buf) {
695 awake = 1; 307 vb2_buffer_done(&pdev->fill_buf->vb,
696 wake_up_interruptible(&pdev->frameq); 308 VB2_BUF_STATE_ERROR);
309 pdev->fill_buf = NULL;
310 }
697 } 311 }
698 goto handler_end; // ugly, but practical 312 pdev->vsync = 0; /* Drop the current frame */
699 }
700
701 fbuf = pdev->fill_frame;
702 if (fbuf == NULL) {
703 PWC_ERROR("pwc_isoc_handler without valid fill frame.\n");
704 awake = 1;
705 goto handler_end; 313 goto handler_end;
706 } 314 }
707 else {
708 fillptr = fbuf->data + fbuf->filled;
709 }
710 315
711 /* Reset ISOC error counter. We did get here, after all. */ 316 /* Reset ISOC error counter. We did get here, after all. */
712 pdev->visoc_errors = 0; 317 pdev->visoc_errors = 0;
@@ -720,89 +325,73 @@ static void pwc_isoc_handler(struct urb *urb)
720 fst = urb->iso_frame_desc[i].status; 325 fst = urb->iso_frame_desc[i].status;
721 flen = urb->iso_frame_desc[i].actual_length; 326 flen = urb->iso_frame_desc[i].actual_length;
722 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset; 327 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
723 if (fst == 0) { 328 if (fst != 0) {
724 if (flen > 0) { /* if valid data... */ 329 PWC_ERROR("Iso frame %d has error %d\n", i, fst);
725 if (pdev->vsync > 0) { /* ...and we are not sync-hunting... */ 330 continue;
726 pdev->vsync = 2; 331 }
727 332 if (flen > 0 && pdev->vsync) {
728 /* ...copy data to frame buffer, if possible */ 333 struct pwc_frame_buf *fbuf = pdev->fill_buf;
729 if (flen + fbuf->filled > pdev->frame_total_size) { 334
730 PWC_DEBUG_FLOW("Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); 335 if (pdev->vsync == 1) {
731 pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */ 336 do_gettimeofday(&fbuf->vb.v4l2_buf.timestamp);
732 pdev->vframes_error++; 337 pdev->vsync = 2;
733 } 338 }
734 else { 339
735 memmove(fillptr, iso_buf, flen); 340 if (flen + fbuf->filled > pdev->frame_total_size) {
736 fillptr += flen; 341 PWC_ERROR("Frame overflow (%d > %d)\n",
737 } 342 flen + fbuf->filled,
738 } 343 pdev->frame_total_size);
344 pdev->vsync = 0; /* Let's wait for an EOF */
345 } else {
346 memcpy(fbuf->data + fbuf->filled, iso_buf,
347 flen);
739 fbuf->filled += flen; 348 fbuf->filled += flen;
740 } /* ..flen > 0 */ 349 }
741 350 }
742 if (flen < pdev->vlast_packet_size) { 351 if (flen < pdev->vlast_packet_size) {
743 /* Shorter packet... We probably have the end of an image-frame; 352 /* Shorter packet... end of frame */
744 wake up read() process and let select()/poll() do something. 353 if (pdev->vsync == 2)
745 Decompression is done in user time over there. 354 pwc_frame_complete(pdev);
746 */ 355 if (pdev->fill_buf == NULL)
747 if (pdev->vsync == 2) { 356 pdev->fill_buf = pwc_get_next_fill_buf(pdev);
748 if (pwc_rcv_short_packet(pdev, fbuf)) { 357 if (pdev->fill_buf) {
749 awake = 1; 358 pdev->fill_buf->filled = 0;
750 fbuf = pdev->fill_frame;
751 }
752 }
753 fbuf->filled = 0;
754 fillptr = fbuf->data;
755 pdev->vsync = 1; 359 pdev->vsync = 1;
756 } 360 }
757
758 pdev->vlast_packet_size = flen;
759 } /* ..status == 0 */
760 else {
761 /* This is normally not interesting to the user, unless
762 * you are really debugging something, default = 0 */
763 static int iso_error;
764 iso_error++;
765 if (iso_error < 20)
766 PWC_DEBUG_FLOW("Iso frame %d of USB has error %d\n", i, fst);
767 } 361 }
362 pdev->vlast_packet_size = flen;
768 } 363 }
769 364
770handler_end: 365handler_end:
771 if (awake)
772 wake_up_interruptible(&pdev->frameq);
773
774 urb->dev = pdev->udev;
775 i = usb_submit_urb(urb, GFP_ATOMIC); 366 i = usb_submit_urb(urb, GFP_ATOMIC);
776 if (i != 0) 367 if (i != 0)
777 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); 368 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
778} 369}
779 370
780 371static int pwc_isoc_init(struct pwc_device *pdev)
781int pwc_isoc_init(struct pwc_device *pdev)
782{ 372{
783 struct usb_device *udev; 373 struct usb_device *udev;
784 struct urb *urb; 374 struct urb *urb;
785 int i, j, ret; 375 int i, j, ret;
786
787 struct usb_interface *intf; 376 struct usb_interface *intf;
788 struct usb_host_interface *idesc = NULL; 377 struct usb_host_interface *idesc = NULL;
789 378
790 if (pdev == NULL)
791 return -EFAULT;
792 if (pdev->iso_init) 379 if (pdev->iso_init)
793 return 0; 380 return 0;
381
794 pdev->vsync = 0; 382 pdev->vsync = 0;
383 pdev->vlast_packet_size = 0;
384 pdev->fill_buf = NULL;
385 pdev->vframe_count = 0;
386 pdev->visoc_errors = 0;
795 udev = pdev->udev; 387 udev = pdev->udev;
796 388
797 /* Get the current alternate interface, adjust packet size */ 389 /* Get the current alternate interface, adjust packet size */
798 if (!udev->actconfig)
799 return -EFAULT;
800 intf = usb_ifnum_to_if(udev, 0); 390 intf = usb_ifnum_to_if(udev, 0);
801 if (intf) 391 if (intf)
802 idesc = usb_altnum_to_altsetting(intf, pdev->valternate); 392 idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
803
804 if (!idesc) 393 if (!idesc)
805 return -EFAULT; 394 return -EIO;
806 395
807 /* Search video endpoint */ 396 /* Search video endpoint */
808 pdev->vmax_packet_size = -1; 397 pdev->vmax_packet_size = -1;
@@ -825,34 +414,32 @@ int pwc_isoc_init(struct pwc_device *pdev)
825 if (ret < 0) 414 if (ret < 0)
826 return ret; 415 return ret;
827 416
417 /* Allocate and init Isochronuous urbs */
828 for (i = 0; i < MAX_ISO_BUFS; i++) { 418 for (i = 0; i < MAX_ISO_BUFS; i++) {
829 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); 419 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
830 if (urb == NULL) { 420 if (urb == NULL) {
831 PWC_ERROR("Failed to allocate urb %d\n", i); 421 PWC_ERROR("Failed to allocate urb %d\n", i);
832 ret = -ENOMEM; 422 pdev->iso_init = 1;
833 break; 423 pwc_isoc_cleanup(pdev);
424 return -ENOMEM;
834 } 425 }
835 pdev->sbuf[i].urb = urb; 426 pdev->urbs[i] = urb;
836 PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb); 427 PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb);
837 }
838 if (ret) {
839 /* De-allocate in reverse order */
840 while (i--) {
841 usb_free_urb(pdev->sbuf[i].urb);
842 pdev->sbuf[i].urb = NULL;
843 }
844 return ret;
845 }
846
847 /* init URB structure */
848 for (i = 0; i < MAX_ISO_BUFS; i++) {
849 urb = pdev->sbuf[i].urb;
850 428
851 urb->interval = 1; // devik 429 urb->interval = 1; // devik
852 urb->dev = udev; 430 urb->dev = udev;
853 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint); 431 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
854 urb->transfer_flags = URB_ISO_ASAP; 432 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
855 urb->transfer_buffer = pdev->sbuf[i].data; 433 urb->transfer_buffer = usb_alloc_coherent(udev,
434 ISO_BUFFER_SIZE,
435 GFP_KERNEL,
436 &urb->transfer_dma);
437 if (urb->transfer_buffer == NULL) {
438 PWC_ERROR("Failed to allocate urb buffer %d\n", i);
439 pdev->iso_init = 1;
440 pwc_isoc_cleanup(pdev);
441 return -ENOMEM;
442 }
856 urb->transfer_buffer_length = ISO_BUFFER_SIZE; 443 urb->transfer_buffer_length = ISO_BUFFER_SIZE;
857 urb->complete = pwc_isoc_handler; 444 urb->complete = pwc_isoc_handler;
858 urb->context = pdev; 445 urb->context = pdev;
@@ -866,14 +453,14 @@ int pwc_isoc_init(struct pwc_device *pdev)
866 453
867 /* link */ 454 /* link */
868 for (i = 0; i < MAX_ISO_BUFS; i++) { 455 for (i = 0; i < MAX_ISO_BUFS; i++) {
869 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); 456 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL);
870 if (ret) { 457 if (ret) {
871 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); 458 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
872 pdev->iso_init = 1; 459 pdev->iso_init = 1;
873 pwc_isoc_cleanup(pdev); 460 pwc_isoc_cleanup(pdev);
874 return ret; 461 return ret;
875 } 462 }
876 PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb); 463 PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->urbs[i]);
877 } 464 }
878 465
879 /* All is done... */ 466 /* All is done... */
@@ -888,12 +475,9 @@ static void pwc_iso_stop(struct pwc_device *pdev)
888 475
889 /* Unlinking ISOC buffers one by one */ 476 /* Unlinking ISOC buffers one by one */
890 for (i = 0; i < MAX_ISO_BUFS; i++) { 477 for (i = 0; i < MAX_ISO_BUFS; i++) {
891 struct urb *urb; 478 if (pdev->urbs[i]) {
892 479 PWC_DEBUG_MEMORY("Unlinking URB %p\n", pdev->urbs[i]);
893 urb = pdev->sbuf[i].urb; 480 usb_kill_urb(pdev->urbs[i]);
894 if (urb) {
895 PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb);
896 usb_kill_urb(urb);
897 } 481 }
898 } 482 }
899} 483}
@@ -904,40 +488,51 @@ static void pwc_iso_free(struct pwc_device *pdev)
904 488
905 /* Freeing ISOC buffers one by one */ 489 /* Freeing ISOC buffers one by one */
906 for (i = 0; i < MAX_ISO_BUFS; i++) { 490 for (i = 0; i < MAX_ISO_BUFS; i++) {
907 struct urb *urb; 491 if (pdev->urbs[i]) {
908
909 urb = pdev->sbuf[i].urb;
910 if (urb) {
911 PWC_DEBUG_MEMORY("Freeing URB\n"); 492 PWC_DEBUG_MEMORY("Freeing URB\n");
912 usb_free_urb(urb); 493 if (pdev->urbs[i]->transfer_buffer) {
913 pdev->sbuf[i].urb = NULL; 494 usb_free_coherent(pdev->udev,
495 pdev->urbs[i]->transfer_buffer_length,
496 pdev->urbs[i]->transfer_buffer,
497 pdev->urbs[i]->transfer_dma);
498 }
499 usb_free_urb(pdev->urbs[i]);
500 pdev->urbs[i] = NULL;
914 } 501 }
915 } 502 }
916} 503}
917 504
918void pwc_isoc_cleanup(struct pwc_device *pdev) 505static void pwc_isoc_cleanup(struct pwc_device *pdev)
919{ 506{
920 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n"); 507 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
921 if (pdev == NULL) 508
922 return;
923 if (pdev->iso_init == 0) 509 if (pdev->iso_init == 0)
924 return; 510 return;
925 511
926 pwc_iso_stop(pdev); 512 pwc_iso_stop(pdev);
927 pwc_iso_free(pdev); 513 pwc_iso_free(pdev);
928 514 usb_set_interface(pdev->udev, 0, 0);
929 /* Stop camera, but only if we are sure the camera is still there (unplug
930 is signalled by EPIPE)
931 */
932 if (pdev->error_status != EPIPE) {
933 PWC_DEBUG_OPEN("Setting alternate interface 0.\n");
934 usb_set_interface(pdev->udev, 0, 0);
935 }
936 515
937 pdev->iso_init = 0; 516 pdev->iso_init = 0;
938 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); 517 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
939} 518}
940 519
520/*
521 * Release all queued buffers, no need to take queued_bufs_lock, since all
522 * iso urbs have been killed when we're called so pwc_isoc_handler won't run.
523 */
524static void pwc_cleanup_queued_bufs(struct pwc_device *pdev)
525{
526 while (!list_empty(&pdev->queued_bufs)) {
527 struct pwc_frame_buf *buf;
528
529 buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf,
530 list);
531 list_del(&buf->list);
532 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
533 }
534}
535
941/********* 536/*********
942 * sysfs 537 * sysfs
943 *********/ 538 *********/
@@ -1051,98 +646,15 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
1051 646
1052static int pwc_video_open(struct file *file) 647static int pwc_video_open(struct file *file)
1053{ 648{
1054 int i, ret;
1055 struct video_device *vdev = video_devdata(file); 649 struct video_device *vdev = video_devdata(file);
1056 struct pwc_device *pdev; 650 struct pwc_device *pdev;
1057 651
1058 PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev); 652 PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev);
1059 653
1060 pdev = video_get_drvdata(vdev); 654 pdev = video_get_drvdata(vdev);
1061 BUG_ON(!pdev); 655 if (!pdev->udev)
1062 if (pdev->vopen) { 656 return -ENODEV;
1063 PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n");
1064 return -EBUSY;
1065 }
1066
1067 pwc_construct(pdev); /* set min/max sizes correct */
1068 if (!pdev->usb_init) {
1069 PWC_DEBUG_OPEN("Doing first time initialization.\n");
1070 pdev->usb_init = 1;
1071
1072 /* Query sensor type */
1073 ret = pwc_get_cmos_sensor(pdev, &i);
1074 if (ret >= 0)
1075 {
1076 PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
1077 pdev->vdev.name,
1078 pwc_sensor_type_to_string(i), i);
1079 }
1080 }
1081
1082 /* Turn on camera */
1083 if (power_save) {
1084 i = pwc_camera_power(pdev, 1);
1085 if (i < 0)
1086 PWC_DEBUG_OPEN("Failed to restore power to the camera! (%d)\n", i);
1087 }
1088 /* Set LED on/off time */
1089 if (pwc_set_leds(pdev, led_on, led_off) < 0)
1090 PWC_DEBUG_OPEN("Failed to set LED on/off time.\n");
1091
1092
1093 /* So far, so good. Allocate memory. */
1094 i = pwc_allocate_buffers(pdev);
1095 if (i < 0) {
1096 PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n");
1097 pwc_free_buffers(pdev);
1098 return i;
1099 }
1100
1101 /* Reset buffers & parameters */
1102 pwc_reset_buffers(pdev);
1103 for (i = 0; i < pwc_mbufs; i++)
1104 pdev->image_used[i] = 0;
1105 pdev->vframe_count = 0;
1106 pdev->vframes_dumped = 0;
1107 pdev->vframes_error = 0;
1108 pdev->visoc_errors = 0;
1109 pdev->error_status = 0;
1110 pwc_construct(pdev); /* set min/max sizes correct */
1111
1112 /* Set some defaults */
1113 pdev->vsnapshot = 0;
1114
1115 /* Set video size, first try the last used video size
1116 (or the default one); if that fails try QCIF/10 or QSIF/10;
1117 it that fails too, give up.
1118 */
1119 i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0);
1120 if (i) {
1121 unsigned int default_resolution;
1122 PWC_DEBUG_OPEN("First attempt at set_video_mode failed.\n");
1123 if (pdev->type>= 730)
1124 default_resolution = PSZ_QSIF;
1125 else
1126 default_resolution = PSZ_QCIF;
1127
1128 i = pwc_set_video_mode(pdev,
1129 pwc_image_sizes[default_resolution].x,
1130 pwc_image_sizes[default_resolution].y,
1131 10,
1132 pdev->vcompression,
1133 0);
1134 }
1135 if (i) {
1136 PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n");
1137 pwc_free_buffers(pdev);
1138 return i;
1139 }
1140
1141 /* Initialize the webcam to sane value */
1142 pwc_set_brightness(pdev, 0x7fff);
1143 pwc_set_agc(pdev, 1, 0);
1144 657
1145 pdev->vopen++;
1146 file->private_data = vdev; 658 file->private_data = vdev;
1147 PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); 659 PWC_DEBUG_OPEN("<< video_open() returns 0.\n");
1148 return 0; 660 return 0;
@@ -1158,239 +670,211 @@ static void pwc_video_release(struct video_device *vfd)
1158 if (device_hint[hint].pdev == pdev) 670 if (device_hint[hint].pdev == pdev)
1159 device_hint[hint].pdev = NULL; 671 device_hint[hint].pdev = NULL;
1160 672
673 /* Free intermediate decompression buffer & tables */
674 if (pdev->decompress_data != NULL) {
675 PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n",
676 pdev->decompress_data);
677 kfree(pdev->decompress_data);
678 pdev->decompress_data = NULL;
679 }
680
681 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
682
1161 kfree(pdev); 683 kfree(pdev);
1162} 684}
1163 685
1164/* Note that all cleanup is done in the reverse order as in _open */
1165static int pwc_video_close(struct file *file) 686static int pwc_video_close(struct file *file)
1166{ 687{
1167 struct video_device *vdev = file->private_data; 688 struct video_device *vdev = file->private_data;
1168 struct pwc_device *pdev; 689 struct pwc_device *pdev;
1169 int i;
1170 690
1171 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); 691 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
1172 692
1173 pdev = video_get_drvdata(vdev); 693 pdev = video_get_drvdata(vdev);
1174 if (pdev->vopen == 0) 694 if (pdev->capt_file == file) {
1175 PWC_DEBUG_MODULE("video_close() called on closed device?\n"); 695 vb2_queue_release(&pdev->vb_queue);
1176 696 pdev->capt_file = NULL;
1177 /* Dump statistics, but only if a reasonable amount of frames were
1178 processed (to prevent endless log-entries in case of snap-shot
1179 programs)
1180 */
1181 if (pdev->vframe_count > 20)
1182 PWC_DEBUG_MODULE("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error);
1183
1184 if (DEVICE_USE_CODEC1(pdev->type))
1185 pwc_dec1_exit();
1186 else
1187 pwc_dec23_exit();
1188
1189 pwc_isoc_cleanup(pdev);
1190 pwc_free_buffers(pdev);
1191
1192 /* Turn off LEDS and power down camera, but only when not unplugged */
1193 if (!pdev->unplugged) {
1194 /* Turn LEDs off */
1195 if (pwc_set_leds(pdev, 0, 0) < 0)
1196 PWC_DEBUG_MODULE("Failed to set LED on/off time.\n");
1197 if (power_save) {
1198 i = pwc_camera_power(pdev, 0);
1199 if (i < 0)
1200 PWC_ERROR("Failed to power down camera (%d)\n", i);
1201 }
1202 pdev->vopen--;
1203 PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
1204 } 697 }
1205 698
699 PWC_DEBUG_OPEN("<< video_close()\n");
1206 return 0; 700 return 0;
1207} 701}
1208 702
1209/*
1210 * FIXME: what about two parallel reads ????
1211 * ANSWER: Not supported. You can't open the device more than once,
1212 despite what the V4L1 interface says. First, I don't see
1213 the need, second there's no mechanism of alerting the
1214 2nd/3rd/... process of events like changing image size.
1215 And I don't see the point of blocking that for the
1216 2nd/3rd/... process.
1217 In multi-threaded environments reading parallel from any
1218 device is tricky anyhow.
1219 */
1220
1221static ssize_t pwc_video_read(struct file *file, char __user *buf, 703static ssize_t pwc_video_read(struct file *file, char __user *buf,
1222 size_t count, loff_t *ppos) 704 size_t count, loff_t *ppos)
1223{ 705{
1224 struct video_device *vdev = file->private_data; 706 struct video_device *vdev = file->private_data;
1225 struct pwc_device *pdev; 707 struct pwc_device *pdev = video_get_drvdata(vdev);
1226 int noblock = file->f_flags & O_NONBLOCK;
1227 DECLARE_WAITQUEUE(wait, current);
1228 int bytes_to_read, rv = 0;
1229 void *image_buffer_addr;
1230
1231 PWC_DEBUG_READ("pwc_video_read(vdev=0x%p, buf=%p, count=%zd) called.\n",
1232 vdev, buf, count);
1233 if (vdev == NULL)
1234 return -EFAULT;
1235 pdev = video_get_drvdata(vdev);
1236 if (pdev == NULL)
1237 return -EFAULT;
1238 708
1239 if (pdev->error_status) { 709 if (!pdev->udev)
1240 rv = -pdev->error_status; /* Something happened, report what. */ 710 return -ENODEV;
1241 goto err_out;
1242 }
1243 711
1244 /* Start the stream (if not already started) */ 712 if (pdev->capt_file != NULL &&
1245 rv = pwc_isoc_init(pdev); 713 pdev->capt_file != file)
1246 if (rv) 714 return -EBUSY;
1247 goto err_out;
1248
1249 /* In case we're doing partial reads, we don't have to wait for a frame */
1250 if (pdev->image_read_pos == 0) {
1251 /* Do wait queueing according to the (doc)book */
1252 add_wait_queue(&pdev->frameq, &wait);
1253 while (pdev->full_frames == NULL) {
1254 /* Check for unplugged/etc. here */
1255 if (pdev->error_status) {
1256 remove_wait_queue(&pdev->frameq, &wait);
1257 set_current_state(TASK_RUNNING);
1258 rv = -pdev->error_status ;
1259 goto err_out;
1260 }
1261 if (noblock) {
1262 remove_wait_queue(&pdev->frameq, &wait);
1263 set_current_state(TASK_RUNNING);
1264 rv = -EWOULDBLOCK;
1265 goto err_out;
1266 }
1267 if (signal_pending(current)) {
1268 remove_wait_queue(&pdev->frameq, &wait);
1269 set_current_state(TASK_RUNNING);
1270 rv = -ERESTARTSYS;
1271 goto err_out;
1272 }
1273 mutex_unlock(&pdev->modlock);
1274 schedule();
1275 set_current_state(TASK_INTERRUPTIBLE);
1276 mutex_lock(&pdev->modlock);
1277 }
1278 remove_wait_queue(&pdev->frameq, &wait);
1279 set_current_state(TASK_RUNNING);
1280 715
1281 /* Decompress and release frame */ 716 pdev->capt_file = file;
1282 if (pwc_handle_frame(pdev)) {
1283 rv = -EFAULT;
1284 goto err_out;
1285 }
1286 }
1287 717
1288 PWC_DEBUG_READ("Copying data to user space.\n"); 718 return vb2_read(&pdev->vb_queue, buf, count, ppos,
1289 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) 719 file->f_flags & O_NONBLOCK);
1290 bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame);
1291 else
1292 bytes_to_read = pdev->view.size;
1293
1294 /* copy bytes to user space; we allow for partial reads */
1295 if (count + pdev->image_read_pos > bytes_to_read)
1296 count = bytes_to_read - pdev->image_read_pos;
1297 image_buffer_addr = pdev->image_data;
1298 image_buffer_addr += pdev->images[pdev->fill_image].offset;
1299 image_buffer_addr += pdev->image_read_pos;
1300 if (copy_to_user(buf, image_buffer_addr, count)) {
1301 rv = -EFAULT;
1302 goto err_out;
1303 }
1304 pdev->image_read_pos += count;
1305 if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */
1306 pdev->image_read_pos = 0;
1307 pwc_next_image(pdev);
1308 }
1309 return count;
1310err_out:
1311 return rv;
1312} 720}
1313 721
1314static unsigned int pwc_video_poll(struct file *file, poll_table *wait) 722static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1315{ 723{
1316 struct video_device *vdev = file->private_data; 724 struct video_device *vdev = file->private_data;
1317 struct pwc_device *pdev; 725 struct pwc_device *pdev = video_get_drvdata(vdev);
1318 int ret;
1319 726
1320 if (vdev == NULL) 727 if (!pdev->udev)
1321 return -EFAULT; 728 return POLL_ERR;
1322 pdev = video_get_drvdata(vdev);
1323 if (pdev == NULL)
1324 return -EFAULT;
1325 729
1326 /* Start the stream (if not already started) */ 730 return vb2_poll(&pdev->vb_queue, file, wait);
1327 ret = pwc_isoc_init(pdev); 731}
1328 if (ret) 732
1329 return ret; 733static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
734{
735 struct video_device *vdev = file->private_data;
736 struct pwc_device *pdev = video_get_drvdata(vdev);
737
738 if (pdev->capt_file != file)
739 return -EBUSY;
740
741 return vb2_mmap(&pdev->vb_queue, vma);
742}
743
744/***************************************************************************/
745/* Videobuf2 operations */
746
747static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
748 unsigned int *nplanes, unsigned long sizes[],
749 void *alloc_ctxs[])
750{
751 struct pwc_device *pdev = vb2_get_drv_priv(vq);
752
753 if (*nbuffers < MIN_FRAMES)
754 *nbuffers = MIN_FRAMES;
755 else if (*nbuffers > MAX_FRAMES)
756 *nbuffers = MAX_FRAMES;
757
758 *nplanes = 1;
1330 759
1331 poll_wait(file, &pdev->frameq, wait); 760 sizes[0] = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2);
1332 if (pdev->error_status)
1333 return POLLERR;
1334 if (pdev->full_frames != NULL) /* we have frames waiting */
1335 return (POLLIN | POLLRDNORM);
1336 761
1337 return 0; 762 return 0;
1338} 763}
1339 764
1340static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) 765static int buffer_init(struct vb2_buffer *vb)
1341{ 766{
1342 struct video_device *vdev = file->private_data; 767 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
1343 struct pwc_device *pdev;
1344 unsigned long start;
1345 unsigned long size;
1346 unsigned long page, pos = 0;
1347 int index;
1348 768
1349 PWC_DEBUG_MEMORY(">> %s\n", __func__); 769 /* need vmalloc since frame buffer > 128K */
1350 pdev = video_get_drvdata(vdev); 770 buf->data = vzalloc(PWC_FRAME_SIZE);
1351 size = vma->vm_end - vma->vm_start; 771 if (buf->data == NULL)
1352 start = vma->vm_start; 772 return -ENOMEM;
1353 773
1354 /* Find the idx buffer for this mapping */ 774 return 0;
1355 for (index = 0; index < pwc_mbufs; index++) { 775}
1356 pos = pdev->images[index].offset; 776
1357 if ((pos>>PAGE_SHIFT) == vma->vm_pgoff) 777static int buffer_prepare(struct vb2_buffer *vb)
1358 break; 778{
779 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
780
781 /* Don't allow queing new buffers after device disconnection */
782 if (!pdev->udev)
783 return -ENODEV;
784
785 return 0;
786}
787
788static int buffer_finish(struct vb2_buffer *vb)
789{
790 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
791 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
792
793 /*
794 * Application has called dqbuf and is getting back a buffer we've
795 * filled, take the pwc data we've stored in buf->data and decompress
796 * it into a usable format, storing the result in the vb2_buffer
797 */
798 return pwc_decompress(pdev, buf);
799}
800
801static void buffer_cleanup(struct vb2_buffer *vb)
802{
803 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
804
805 vfree(buf->data);
806}
807
808static void buffer_queue(struct vb2_buffer *vb)
809{
810 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
811 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
812 unsigned long flags = 0;
813
814 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
815 list_add_tail(&buf->list, &pdev->queued_bufs);
816 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
817}
818
819static int start_streaming(struct vb2_queue *vq)
820{
821 struct pwc_device *pdev = vb2_get_drv_priv(vq);
822
823 if (!pdev->udev)
824 return -ENODEV;
825
826 /* Turn on camera and set LEDS on */
827 pwc_camera_power(pdev, 1);
828 if (pdev->power_save) {
829 /* Restore video mode */
830 pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y,
831 pdev->vframes, pdev->vcompression,
832 pdev->vsnapshot);
1359 } 833 }
1360 if (index == MAX_IMAGES) 834 pwc_set_leds(pdev, led_on, led_off);
1361 return -EINVAL; 835
1362 if (index == 0) { 836 return pwc_isoc_init(pdev);
1363 /* 837}
1364 * Special case for v4l1. In v4l1, we map only one big buffer, 838
1365 * but in v4l2 each buffer is mapped 839static int stop_streaming(struct vb2_queue *vq)
1366 */ 840{
1367 unsigned long total_size; 841 struct pwc_device *pdev = vb2_get_drv_priv(vq);
1368 total_size = pwc_mbufs * pdev->len_per_image; 842
1369 if (size != pdev->len_per_image && size != total_size) { 843 if (pdev->udev) {
1370 PWC_ERROR("Wrong size (%lu) needed to be len_per_image=%d or total_size=%lu\n", 844 pwc_set_leds(pdev, 0, 0);
1371 size, pdev->len_per_image, total_size); 845 pwc_camera_power(pdev, 0);
1372 return -EINVAL; 846 pwc_isoc_cleanup(pdev);
1373 }
1374 } else if (size > pdev->len_per_image)
1375 return -EINVAL;
1376
1377 vma->vm_flags |= VM_IO; /* from 2.6.9-acX */
1378
1379 pos += (unsigned long)pdev->image_data;
1380 while (size > 0) {
1381 page = vmalloc_to_pfn((void *)pos);
1382 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1383 return -EAGAIN;
1384 start += PAGE_SIZE;
1385 pos += PAGE_SIZE;
1386 if (size > PAGE_SIZE)
1387 size -= PAGE_SIZE;
1388 else
1389 size = 0;
1390 } 847 }
848 pwc_cleanup_queued_bufs(pdev);
849
1391 return 0; 850 return 0;
1392} 851}
1393 852
853static void pwc_lock(struct vb2_queue *vq)
854{
855 struct pwc_device *pdev = vb2_get_drv_priv(vq);
856 mutex_lock(&pdev->modlock);
857}
858
859static void pwc_unlock(struct vb2_queue *vq)
860{
861 struct pwc_device *pdev = vb2_get_drv_priv(vq);
862 mutex_unlock(&pdev->modlock);
863}
864
865static struct vb2_ops pwc_vb_queue_ops = {
866 .queue_setup = queue_setup,
867 .buf_init = buffer_init,
868 .buf_prepare = buffer_prepare,
869 .buf_finish = buffer_finish,
870 .buf_cleanup = buffer_cleanup,
871 .buf_queue = buffer_queue,
872 .start_streaming = start_streaming,
873 .stop_streaming = stop_streaming,
874 .wait_prepare = pwc_unlock,
875 .wait_finish = pwc_lock,
876};
877
1394/***************************************************************************/ 878/***************************************************************************/
1395/* USB functions */ 879/* USB functions */
1396 880
@@ -1406,6 +890,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1406 int hint, rc; 890 int hint, rc;
1407 int features = 0; 891 int features = 0;
1408 int video_nr = -1; /* default: use next available device */ 892 int video_nr = -1; /* default: use next available device */
893 int my_power_save = power_save;
1409 char serial_number[30], *name; 894 char serial_number[30], *name;
1410 895
1411 vendor_id = le16_to_cpu(udev->descriptor.idVendor); 896 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
@@ -1513,6 +998,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1513 PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n"); 998 PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n");
1514 name = "Logitech QuickCam Pro 4000"; 999 name = "Logitech QuickCam Pro 4000";
1515 type_id = 740; /* CCD sensor */ 1000 type_id = 740; /* CCD sensor */
1001 if (my_power_save == -1)
1002 my_power_save = 1;
1516 break; 1003 break;
1517 case 0x08b3: 1004 case 0x08b3:
1518 PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n"); 1005 PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n");
@@ -1523,12 +1010,15 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1523 PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); 1010 PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
1524 name = "Logitech QuickCam Zoom"; 1011 name = "Logitech QuickCam Zoom";
1525 type_id = 740; /* CCD sensor */ 1012 type_id = 740; /* CCD sensor */
1526 power_save = 1; 1013 if (my_power_save == -1)
1014 my_power_save = 1;
1527 break; 1015 break;
1528 case 0x08b5: 1016 case 0x08b5:
1529 PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); 1017 PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
1530 name = "Logitech QuickCam Orbit"; 1018 name = "Logitech QuickCam Orbit";
1531 type_id = 740; /* CCD sensor */ 1019 type_id = 740; /* CCD sensor */
1020 if (my_power_save == -1)
1021 my_power_save = 1;
1532 features |= FEATURE_MOTOR_PANTILT; 1022 features |= FEATURE_MOTOR_PANTILT;
1533 break; 1023 break;
1534 case 0x08b6: 1024 case 0x08b6:
@@ -1583,6 +1073,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1583 PWC_INFO("Creative Labs Webcam 5 detected.\n"); 1073 PWC_INFO("Creative Labs Webcam 5 detected.\n");
1584 name = "Creative Labs Webcam 5"; 1074 name = "Creative Labs Webcam 5";
1585 type_id = 730; 1075 type_id = 730;
1076 if (my_power_save == -1)
1077 my_power_save = 1;
1586 break; 1078 break;
1587 case 0x4011: 1079 case 0x4011:
1588 PWC_INFO("Creative Labs Webcam Pro Ex detected.\n"); 1080 PWC_INFO("Creative Labs Webcam Pro Ex detected.\n");
@@ -1640,6 +1132,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1640 else 1132 else
1641 return -ENODEV; /* Not any of the know types; but the list keeps growing. */ 1133 return -ENODEV; /* Not any of the know types; but the list keeps growing. */
1642 1134
1135 if (my_power_save == -1)
1136 my_power_save = 0;
1137
1643 memset(serial_number, 0, 30); 1138 memset(serial_number, 0, 30);
1644 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); 1139 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
1645 PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number); 1140 PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number);
@@ -1654,7 +1149,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1654 return -ENOMEM; 1149 return -ENOMEM;
1655 } 1150 }
1656 pdev->type = type_id; 1151 pdev->type = type_id;
1657 pdev->vsize = default_size;
1658 pdev->vframes = default_fps; 1152 pdev->vframes = default_fps;
1659 strcpy(pdev->serial, serial_number); 1153 strcpy(pdev->serial, serial_number);
1660 pdev->features = features; 1154 pdev->features = features;
@@ -1668,13 +1162,26 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1668 pdev->angle_range.tilt_min = -3000; 1162 pdev->angle_range.tilt_min = -3000;
1669 pdev->angle_range.tilt_max = 2500; 1163 pdev->angle_range.tilt_max = 2500;
1670 } 1164 }
1165 pwc_construct(pdev); /* set min/max sizes correct */
1671 1166
1672 mutex_init(&pdev->modlock); 1167 mutex_init(&pdev->modlock);
1673 spin_lock_init(&pdev->ptrlock); 1168 mutex_init(&pdev->udevlock);
1169 spin_lock_init(&pdev->queued_bufs_lock);
1170 INIT_LIST_HEAD(&pdev->queued_bufs);
1674 1171
1675 pdev->udev = udev; 1172 pdev->udev = udev;
1676 init_waitqueue_head(&pdev->frameq);
1677 pdev->vcompression = pwc_preferred_compression; 1173 pdev->vcompression = pwc_preferred_compression;
1174 pdev->power_save = my_power_save;
1175
1176 /* Init videobuf2 queue structure */
1177 memset(&pdev->vb_queue, 0, sizeof(pdev->vb_queue));
1178 pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1179 pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1180 pdev->vb_queue.drv_priv = pdev;
1181 pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf);
1182 pdev->vb_queue.ops = &pwc_vb_queue_ops;
1183 pdev->vb_queue.mem_ops = &vb2_vmalloc_memops;
1184 vb2_queue_init(&pdev->vb_queue);
1678 1185
1679 /* Init video_device structure */ 1186 /* Init video_device structure */
1680 memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); 1187 memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
@@ -1707,14 +1214,40 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1707 PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); 1214 PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
1708 usb_set_intfdata(intf, pdev); 1215 usb_set_intfdata(intf, pdev);
1709 1216
1217#ifdef CONFIG_USB_PWC_DEBUG
1218 /* Query sensor type */
1219 if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
1220 PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
1221 pdev->vdev.name,
1222 pwc_sensor_type_to_string(rc), rc);
1223 }
1224#endif
1225
1710 /* Set the leds off */ 1226 /* Set the leds off */
1711 pwc_set_leds(pdev, 0, 0); 1227 pwc_set_leds(pdev, 0, 0);
1228
1229 /* Setup intial videomode */
1230 rc = pwc_set_video_mode(pdev, pdev->view_max.x, pdev->view_max.y,
1231 pdev->vframes, pdev->vcompression, 0);
1232 if (rc)
1233 goto err_free_mem;
1234
1235 /* Register controls (and read default values from camera */
1236 rc = pwc_init_controls(pdev);
1237 if (rc) {
1238 PWC_ERROR("Failed to register v4l2 controls (%d).\n", rc);
1239 goto err_free_mem;
1240 }
1241
1242 pdev->vdev.ctrl_handler = &pdev->ctrl_handler;
1243
1244 /* And powerdown the camera until streaming starts */
1712 pwc_camera_power(pdev, 0); 1245 pwc_camera_power(pdev, 0);
1713 1246
1714 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); 1247 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1715 if (rc < 0) { 1248 if (rc < 0) {
1716 PWC_ERROR("Failed to register as video device (%d).\n", rc); 1249 PWC_ERROR("Failed to register as video device (%d).\n", rc);
1717 goto err_free_mem; 1250 goto err_free_controls;
1718 } 1251 }
1719 rc = pwc_create_sysfs_files(pdev); 1252 rc = pwc_create_sysfs_files(pdev);
1720 if (rc) 1253 if (rc)
@@ -1757,7 +1290,10 @@ err_video_unreg:
1757 if (hint < MAX_DEV_HINTS) 1290 if (hint < MAX_DEV_HINTS)
1758 device_hint[hint].pdev = NULL; 1291 device_hint[hint].pdev = NULL;
1759 video_unregister_device(&pdev->vdev); 1292 video_unregister_device(&pdev->vdev);
1293err_free_controls:
1294 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
1760err_free_mem: 1295err_free_mem:
1296 usb_set_intfdata(intf, NULL);
1761 kfree(pdev); 1297 kfree(pdev);
1762 return rc; 1298 return rc;
1763} 1299}
@@ -1767,33 +1303,17 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1767{ 1303{
1768 struct pwc_device *pdev = usb_get_intfdata(intf); 1304 struct pwc_device *pdev = usb_get_intfdata(intf);
1769 1305
1306 mutex_lock(&pdev->udevlock);
1770 mutex_lock(&pdev->modlock); 1307 mutex_lock(&pdev->modlock);
1771 usb_set_intfdata (intf, NULL);
1772 if (pdev == NULL) {
1773 PWC_ERROR("pwc_disconnect() Called without private pointer.\n");
1774 goto disconnect_out;
1775 }
1776 if (pdev->udev == NULL) {
1777 PWC_ERROR("pwc_disconnect() already called for %p\n", pdev);
1778 goto disconnect_out;
1779 }
1780 if (pdev->udev != interface_to_usbdev(intf)) {
1781 PWC_ERROR("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
1782 goto disconnect_out;
1783 }
1784
1785 /* We got unplugged; this is signalled by an EPIPE error code */
1786 pdev->error_status = EPIPE;
1787 pdev->unplugged = 1;
1788
1789 /* Alert waiting processes */
1790 wake_up_interruptible(&pdev->frameq);
1791 1308
1309 usb_set_intfdata(intf, NULL);
1792 /* No need to keep the urbs around after disconnection */ 1310 /* No need to keep the urbs around after disconnection */
1793 pwc_isoc_cleanup(pdev); 1311 pwc_isoc_cleanup(pdev);
1312 pwc_cleanup_queued_bufs(pdev);
1313 pdev->udev = NULL;
1794 1314
1795disconnect_out:
1796 mutex_unlock(&pdev->modlock); 1315 mutex_unlock(&pdev->modlock);
1316 mutex_unlock(&pdev->udevlock);
1797 1317
1798 pwc_remove_sysfs_files(pdev); 1318 pwc_remove_sysfs_files(pdev);
1799 video_unregister_device(&pdev->vdev); 1319 video_unregister_device(&pdev->vdev);
@@ -1809,36 +1329,27 @@ disconnect_out:
1809 * Initialization code & module stuff 1329 * Initialization code & module stuff
1810 */ 1330 */
1811 1331
1812static char *size;
1813static int fps; 1332static int fps;
1814static int fbufs;
1815static int mbufs;
1816static int compression = -1; 1333static int compression = -1;
1817static int leds[2] = { -1, -1 }; 1334static int leds[2] = { -1, -1 };
1818static unsigned int leds_nargs; 1335static unsigned int leds_nargs;
1819static char *dev_hint[MAX_DEV_HINTS]; 1336static char *dev_hint[MAX_DEV_HINTS];
1820static unsigned int dev_hint_nargs; 1337static unsigned int dev_hint_nargs;
1821 1338
1822module_param(size, charp, 0444);
1823module_param(fps, int, 0444); 1339module_param(fps, int, 0444);
1824module_param(fbufs, int, 0444);
1825module_param(mbufs, int, 0444);
1826#ifdef CONFIG_USB_PWC_DEBUG 1340#ifdef CONFIG_USB_PWC_DEBUG
1827module_param_named(trace, pwc_trace, int, 0644); 1341module_param_named(trace, pwc_trace, int, 0644);
1828#endif 1342#endif
1829module_param(power_save, int, 0444); 1343module_param(power_save, int, 0644);
1830module_param(compression, int, 0444); 1344module_param(compression, int, 0444);
1831module_param_array(leds, int, &leds_nargs, 0444); 1345module_param_array(leds, int, &leds_nargs, 0444);
1832module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); 1346module_param_array(dev_hint, charp, &dev_hint_nargs, 0444);
1833 1347
1834MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga");
1835MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); 1348MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
1836MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
1837MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers");
1838#ifdef CONFIG_USB_PWC_DEBUG 1349#ifdef CONFIG_USB_PWC_DEBUG
1839MODULE_PARM_DESC(trace, "For debugging purposes"); 1350MODULE_PARM_DESC(trace, "For debugging purposes");
1840#endif 1351#endif
1841MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); 1352MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off");
1842MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); 1353MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
1843MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); 1354MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
1844MODULE_PARM_DESC(dev_hint, "Device node hints"); 1355MODULE_PARM_DESC(dev_hint, "Device node hints");
@@ -1851,14 +1362,19 @@ MODULE_VERSION( PWC_VERSION );
1851 1362
1852static int __init usb_pwc_init(void) 1363static int __init usb_pwc_init(void)
1853{ 1364{
1854 int i, sz; 1365 int i;
1855 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
1856 1366
1367#ifdef CONFIG_USB_PWC_DEBUG
1857 PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n"); 1368 PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n");
1858 PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); 1369 PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
1859 PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); 1370 PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
1860 PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); 1371 PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
1861 1372
1373 if (pwc_trace >= 0) {
1374 PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace);
1375 }
1376#endif
1377
1862 if (fps) { 1378 if (fps) {
1863 if (fps < 4 || fps > 30) { 1379 if (fps < 4 || fps > 30) {
1864 PWC_ERROR("Framerate out of bounds (4-30).\n"); 1380 PWC_ERROR("Framerate out of bounds (4-30).\n");
@@ -1868,41 +1384,6 @@ static int __init usb_pwc_init(void)
1868 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps); 1384 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps);
1869 } 1385 }
1870 1386
1871 if (size) {
1872 /* string; try matching with array */
1873 for (sz = 0; sz < PSZ_MAX; sz++) {
1874 if (!strcmp(sizenames[sz], size)) { /* Found! */
1875 default_size = sz;
1876 break;
1877 }
1878 }
1879 if (sz == PSZ_MAX) {
1880 PWC_ERROR("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n");
1881 return -EINVAL;
1882 }
1883 PWC_DEBUG_MODULE("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y);
1884 }
1885 if (mbufs) {
1886 if (mbufs < 1 || mbufs > MAX_IMAGES) {
1887 PWC_ERROR("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES);
1888 return -EINVAL;
1889 }
1890 pwc_mbufs = mbufs;
1891 PWC_DEBUG_MODULE("Number of image buffers set to %d.\n", pwc_mbufs);
1892 }
1893 if (fbufs) {
1894 if (fbufs < 2 || fbufs > MAX_FRAMES) {
1895 PWC_ERROR("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES);
1896 return -EINVAL;
1897 }
1898 default_fbufs = fbufs;
1899 PWC_DEBUG_MODULE("Number of frame buffers set to %d.\n", default_fbufs);
1900 }
1901#ifdef CONFIG_USB_PWC_DEBUG
1902 if (pwc_trace >= 0) {
1903 PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace);
1904 }
1905#endif
1906 if (compression >= 0) { 1387 if (compression >= 0) {
1907 if (compression > 3) { 1388 if (compression > 3) {
1908 PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n"); 1389 PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
@@ -1911,8 +1392,6 @@ static int __init usb_pwc_init(void)
1911 pwc_preferred_compression = compression; 1392 pwc_preferred_compression = compression;
1912 PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression); 1393 PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression);
1913 } 1394 }
1914 if (power_save)
1915 PWC_DEBUG_MODULE("Enabling power save on open/close.\n");
1916 if (leds[0] >= 0) 1395 if (leds[0] >= 0)
1917 led_on = leds[0]; 1396 led_on = leds[0];
1918 if (leds[1] >= 0) 1397 if (leds[1] >= 0)
diff --git a/drivers/media/video/pwc/pwc-ioctl.h b/drivers/media/video/pwc/pwc-ioctl.h
deleted file mode 100644
index 8c0cae7b3daf..000000000000
--- a/drivers/media/video/pwc/pwc-ioctl.h
+++ /dev/null
@@ -1,323 +0,0 @@
1#ifndef PWC_IOCTL_H
2#define PWC_IOCTL_H
3
4/* (C) 2001-2004 Nemosoft Unv.
5 (C) 2004-2006 Luc Saillard (luc@saillard.org)
6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version.
9 Please send bug reports and support requests to <luc@saillard.org>.
10 The decompression routines have been implemented by reverse-engineering the
11 Nemosoft binary pwcx module. Caveat emptor.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26*/
27
28/* This is pwc-ioctl.h belonging to PWC 10.0.10
29 It contains structures and defines to communicate from user space
30 directly to the driver.
31 */
32
33/*
34 Changes
35 2001/08/03 Alvarado Added ioctl constants to access methods for
36 changing white balance and red/blue gains
37 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE
38 2003/12/13 Nemosft Unv. Some modifications to make interfacing to
39 PWCX easier
40 */
41
42/* These are private ioctl() commands, specific for the Philips webcams.
43 They contain functions not found in other webcams, and settings not
44 specified in the Video4Linux API.
45
46 The #define names are built up like follows:
47 VIDIOC VIDeo IOCtl prefix
48 PWC Philps WebCam
49 G optional: Get
50 S optional: Set
51 ... the function
52 */
53
54#include <linux/types.h>
55#include <linux/version.h>
56
57 /* Enumeration of image sizes */
58#define PSZ_SQCIF 0x00
59#define PSZ_QSIF 0x01
60#define PSZ_QCIF 0x02
61#define PSZ_SIF 0x03
62#define PSZ_CIF 0x04
63#define PSZ_VGA 0x05
64#define PSZ_MAX 6
65
66
67/* The frame rate is encoded in the video_window.flags parameter using
68 the upper 16 bits, since some flags are defined nowadays. The following
69 defines provide a mask and shift to filter out this value.
70 This value can also be passing using the private flag when using v4l2 and
71 VIDIOC_S_FMT ioctl.
72
73 In 'Snapshot' mode the camera freezes its automatic exposure and colour
74 balance controls.
75 */
76#define PWC_FPS_SHIFT 16
77#define PWC_FPS_MASK 0x00FF0000
78#define PWC_FPS_FRMASK 0x003F0000
79#define PWC_FPS_SNAPSHOT 0x00400000
80#define PWC_QLT_MASK 0x03000000
81#define PWC_QLT_SHIFT 24
82
83
84/* structure for transferring x & y coordinates */
85struct pwc_coord
86{
87 int x, y; /* guess what */
88 int size; /* size, or offset */
89};
90
91
92/* Used with VIDIOCPWCPROBE */
93struct pwc_probe
94{
95 char name[32];
96 int type;
97};
98
99struct pwc_serial
100{
101 char serial[30]; /* String with serial number. Contains terminating 0 */
102};
103
104/* pwc_whitebalance.mode values */
105#define PWC_WB_INDOOR 0
106#define PWC_WB_OUTDOOR 1
107#define PWC_WB_FL 2
108#define PWC_WB_MANUAL 3
109#define PWC_WB_AUTO 4
110
111/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
112 Set mode to one of the PWC_WB_* values above.
113 *red and *blue are the respective gains of these colour components inside
114 the camera; range 0..65535
115 When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
116 otherwise undefined.
117 'read_red' and 'read_blue' are read-only.
118*/
119struct pwc_whitebalance
120{
121 int mode;
122 int manual_red, manual_blue; /* R/W */
123 int read_red, read_blue; /* R/O */
124};
125
126/*
127 'control_speed' and 'control_delay' are used in automatic whitebalance mode,
128 and tell the camera how fast it should react to changes in lighting, and
129 with how much delay. Valid values are 0..65535.
130*/
131struct pwc_wb_speed
132{
133 int control_speed;
134 int control_delay;
135
136};
137
138/* Used with VIDIOCPWC[SG]LED */
139struct pwc_leds
140{
141 int led_on; /* Led on-time; range = 0..25000 */
142 int led_off; /* Led off-time; range = 0..25000 */
143};
144
145/* Image size (used with GREALSIZE) */
146struct pwc_imagesize
147{
148 int width;
149 int height;
150};
151
152/* Defines and structures for Motorized Pan & Tilt */
153#define PWC_MPT_PAN 0x01
154#define PWC_MPT_TILT 0x02
155#define PWC_MPT_TIMEOUT 0x04 /* for status */
156
157/* Set angles; when absolute != 0, the angle is absolute and the
158 driver calculates the relative offset for you. This can only
159 be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
160 absolute angles.
161 */
162struct pwc_mpt_angles
163{
164 int absolute; /* write-only */
165 int pan; /* degrees * 100 */
166 int tilt; /* degress * 100 */
167};
168
169/* Range of angles of the camera, both horizontally and vertically.
170 */
171struct pwc_mpt_range
172{
173 int pan_min, pan_max; /* degrees * 100 */
174 int tilt_min, tilt_max;
175};
176
177struct pwc_mpt_status
178{
179 int status;
180 int time_pan;
181 int time_tilt;
182};
183
184
185/* This is used for out-of-kernel decompression. With it, you can get
186 all the necessary information to initialize and use the decompressor
187 routines in standalone applications.
188 */
189struct pwc_video_command
190{
191 int type; /* camera type (645, 675, 730, etc.) */
192 int release; /* release number */
193
194 int size; /* one of PSZ_* */
195 int alternate;
196 int command_len; /* length of USB video command */
197 unsigned char command_buf[13]; /* Actual USB video command */
198 int bandlength; /* >0 = compressed */
199 int frame_size; /* Size of one (un)compressed frame */
200};
201
202/* Flags for PWCX subroutines. Not all modules honour all flags. */
203#define PWCX_FLAG_PLANAR 0x0001
204#define PWCX_FLAG_BAYER 0x0008
205
206
207/* IOCTL definitions */
208
209 /* Restore user settings */
210#define VIDIOCPWCRUSER _IO('v', 192)
211 /* Save user settings */
212#define VIDIOCPWCSUSER _IO('v', 193)
213 /* Restore factory settings */
214#define VIDIOCPWCFACTORY _IO('v', 194)
215
216 /* You can manipulate the compression factor. A compression preference of 0
217 means use uncompressed modes when available; 1 is low compression, 2 is
218 medium and 3 is high compression preferred. Of course, the higher the
219 compression, the lower the bandwidth used but more chance of artefacts
220 in the image. The driver automatically chooses a higher compression when
221 the preferred mode is not available.
222 */
223 /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */
224#define VIDIOCPWCSCQUAL _IOW('v', 195, int)
225 /* Get preferred compression quality */
226#define VIDIOCPWCGCQUAL _IOR('v', 195, int)
227
228
229/* Retrieve serial number of camera */
230#define VIDIOCPWCGSERIAL _IOR('v', 198, struct pwc_serial)
231
232 /* This is a probe function; since so many devices are supported, it
233 becomes difficult to include all the names in programs that want to
234 check for the enhanced Philips stuff. So in stead, try this PROBE;
235 it returns a structure with the original name, and the corresponding
236 Philips type.
237 To use, fill the structure with zeroes, call PROBE and if that succeeds,
238 compare the name with that returned from VIDIOCGCAP; they should be the
239 same. If so, you can be assured it is a Philips (OEM) cam and the type
240 is valid.
241 */
242#define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe)
243
244 /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
245#define VIDIOCPWCSAGC _IOW('v', 200, int)
246 /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */
247#define VIDIOCPWCGAGC _IOR('v', 200, int)
248 /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */
249#define VIDIOCPWCSSHUTTER _IOW('v', 201, int)
250
251 /* Color compensation (Auto White Balance) */
252#define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance)
253#define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance)
254
255 /* Auto WB speed */
256#define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed)
257#define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed)
258
259 /* LEDs on/off/blink; int range 0..65535 */
260#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds)
261#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds)
262
263 /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */
264#define VIDIOCPWCSCONTOUR _IOW('v', 206, int)
265#define VIDIOCPWCGCONTOUR _IOR('v', 206, int)
266
267 /* Backlight compensation; 0 = off, otherwise on */
268#define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int)
269#define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int)
270
271 /* Flickerless mode; = 0 off, otherwise on */
272#define VIDIOCPWCSFLICKER _IOW('v', 208, int)
273#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
274
275 /* Dynamic noise reduction; 0 off, 3 = high noise reduction */
276#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int)
277#define VIDIOCPWCGDYNNOISE _IOR('v', 209, int)
278
279 /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */
280#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize)
281
282 /* Motorized pan & tilt functions */
283#define VIDIOCPWCMPTRESET _IOW('v', 211, int)
284#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range)
285#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles)
286#define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles)
287#define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status)
288
289 /* Get the USB set-video command; needed for initializing libpwcx */
290#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command)
291struct pwc_table_init_buffer {
292 int len;
293 char *buffer;
294
295};
296#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer)
297
298/*
299 * This is private command used when communicating with v4l2.
300 * In the future all private ioctl will be remove/replace to
301 * use interface offer by v4l2.
302 */
303
304#define V4L2_CID_PRIVATE_SAVE_USER (V4L2_CID_PRIVATE_BASE + 0)
305#define V4L2_CID_PRIVATE_RESTORE_USER (V4L2_CID_PRIVATE_BASE + 1)
306#define V4L2_CID_PRIVATE_RESTORE_FACTORY (V4L2_CID_PRIVATE_BASE + 2)
307#define V4L2_CID_PRIVATE_COLOUR_MODE (V4L2_CID_PRIVATE_BASE + 3)
308#define V4L2_CID_PRIVATE_AUTOCONTOUR (V4L2_CID_PRIVATE_BASE + 4)
309#define V4L2_CID_PRIVATE_CONTOUR (V4L2_CID_PRIVATE_BASE + 5)
310#define V4L2_CID_PRIVATE_BACKLIGHT (V4L2_CID_PRIVATE_BASE + 6)
311#define V4L2_CID_PRIVATE_FLICKERLESS (V4L2_CID_PRIVATE_BASE + 7)
312#define V4L2_CID_PRIVATE_NOISE_REDUCTION (V4L2_CID_PRIVATE_BASE + 8)
313
314struct pwc_raw_frame {
315 __le16 type; /* type of the webcam */
316 __le16 vbandlength; /* Size of 4lines compressed (used by the decompressor) */
317 __u8 cmd[4]; /* the four byte of the command (in case of nala,
318 only the first 3 bytes is filled) */
319 __u8 rawframe[0]; /* frame_size = H/4*vbandlength */
320} __attribute__ ((packed));
321
322
323#endif
diff --git a/drivers/media/video/pwc/pwc-kiara.c b/drivers/media/video/pwc/pwc-kiara.c
index f4ae83c0cf2b..e5f4fd817125 100644
--- a/drivers/media/video/pwc/pwc-kiara.c
+++ b/drivers/media/video/pwc/pwc-kiara.c
@@ -40,7 +40,6 @@
40 40
41 41
42#include "pwc-kiara.h" 42#include "pwc-kiara.h"
43#include "pwc-uncompress.h"
44 43
45const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA] = { 5, 10, 15, 20, 25, 30 }; 44const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA] = { 5, 10, 15, 20, 25, 30 };
46 45
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c
index 6af5bb538358..0b031336eab8 100644
--- a/drivers/media/video/pwc/pwc-misc.c
+++ b/drivers/media/video/pwc/pwc-misc.c
@@ -126,8 +126,4 @@ void pwc_construct(struct pwc_device *pdev)
126 pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */ 126 pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */
127 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; 127 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
128 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; 128 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
129 /* length of image, in YUV format; always allocate enough memory. */
130 pdev->len_per_image = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2);
131} 129}
132
133
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c
index 3b73f295f032..51265092bd31 100644
--- a/drivers/media/video/pwc/pwc-uncompress.c
+++ b/drivers/media/video/pwc/pwc-uncompress.c
@@ -30,26 +30,17 @@
30#include <asm/types.h> 30#include <asm/types.h>
31 31
32#include "pwc.h" 32#include "pwc.h"
33#include "pwc-uncompress.h"
34#include "pwc-dec1.h" 33#include "pwc-dec1.h"
35#include "pwc-dec23.h" 34#include "pwc-dec23.h"
36 35
37int pwc_decompress(struct pwc_device *pdev) 36int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf)
38{ 37{
39 struct pwc_frame_buf *fbuf;
40 int n, line, col, stride; 38 int n, line, col, stride;
41 void *yuv, *image; 39 void *yuv, *image;
42 u16 *src; 40 u16 *src;
43 u16 *dsty, *dstu, *dstv; 41 u16 *dsty, *dstu, *dstv;
44 42
45 if (pdev == NULL) 43 image = vb2_plane_vaddr(&fbuf->vb, 0);
46 return -EFAULT;
47
48 fbuf = pdev->read_frame;
49 if (fbuf == NULL)
50 return -EFAULT;
51 image = pdev->image_data;
52 image += pdev->images[pdev->fill_image].offset;
53 44
54 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ 45 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
55 46
@@ -64,9 +55,13 @@ int pwc_decompress(struct pwc_device *pdev)
64 * determine this using the type of the webcam */ 55 * determine this using the type of the webcam */
65 memcpy(raw_frame->cmd, pdev->cmd_buf, 4); 56 memcpy(raw_frame->cmd, pdev->cmd_buf, 4);
66 memcpy(raw_frame+1, yuv, pdev->frame_size); 57 memcpy(raw_frame+1, yuv, pdev->frame_size);
58 vb2_set_plane_payload(&fbuf->vb, 0,
59 pdev->frame_size + sizeof(struct pwc_raw_frame));
67 return 0; 60 return 0;
68 } 61 }
69 62
63 vb2_set_plane_payload(&fbuf->vb, 0, pdev->view.size);
64
70 if (pdev->vbandlength == 0) { 65 if (pdev->vbandlength == 0) {
71 /* Uncompressed mode. 66 /* Uncompressed mode.
72 * We copy the data into the output buffer, using the viewport 67 * We copy the data into the output buffer, using the viewport
diff --git a/drivers/media/video/pwc/pwc-uncompress.h b/drivers/media/video/pwc/pwc-uncompress.h
deleted file mode 100644
index 43028e74e9e0..000000000000
--- a/drivers/media/video/pwc/pwc-uncompress.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25/* This file is the bridge between the kernel module and the plugin; it
26 describes the structures and datatypes used in both modules. Any
27 significant change should be reflected by increasing the
28 pwc_decompressor_version major number.
29 */
30#ifndef PWC_UNCOMPRESS_H
31#define PWC_UNCOMPRESS_H
32
33
34#include <media/pwc-ioctl.h>
35
36/* from pwc-dec.h */
37#define PWCX_FLAG_PLANAR 0x0001
38/* */
39
40#endif
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index f85c51249c7b..8c70e64444e7 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -2,6 +2,7 @@
2 USB and Video4Linux interface part. 2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv. 3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004-2006 Luc Saillard (luc@saillard.org) 4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 (C) 2011 Hans de Goede <hdegoede@redhat.com>
5 6
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version. 8 driver and thus may have bugs that are not present in the original version.
@@ -31,184 +32,330 @@
31#include <linux/module.h> 32#include <linux/module.h>
32#include <linux/poll.h> 33#include <linux/poll.h>
33#include <linux/vmalloc.h> 34#include <linux/vmalloc.h>
35#include <linux/jiffies.h>
34#include <asm/io.h> 36#include <asm/io.h>
35 37
36#include "pwc.h" 38#include "pwc.h"
37 39
38static struct v4l2_queryctrl pwc_controls[] = { 40#define PWC_CID_CUSTOM(ctrl) ((V4L2_CID_USER_BASE | 0xf000) + custom_ ## ctrl)
39 { 41
40 .id = V4L2_CID_BRIGHTNESS, 42static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
41 .type = V4L2_CTRL_TYPE_INTEGER, 43static int pwc_s_ctrl(struct v4l2_ctrl *ctrl);
42 .name = "Brightness", 44
43 .minimum = 0, 45static const struct v4l2_ctrl_ops pwc_ctrl_ops = {
44 .maximum = 128, 46 .g_volatile_ctrl = pwc_g_volatile_ctrl,
45 .step = 1, 47 .s_ctrl = pwc_s_ctrl,
46 .default_value = 64, 48};
47 }, 49
48 { 50enum { awb_indoor, awb_outdoor, awb_fl, awb_manual, awb_auto };
49 .id = V4L2_CID_CONTRAST, 51enum { custom_autocontour, custom_contour, custom_noise_reduction,
50 .type = V4L2_CTRL_TYPE_INTEGER, 52 custom_save_user, custom_restore_user, custom_restore_factory };
51 .name = "Contrast", 53
52 .minimum = 0, 54const char * const pwc_auto_whitebal_qmenu[] = {
53 .maximum = 64, 55 "Indoor (Incandescant Lighting) Mode",
54 .step = 1, 56 "Outdoor (Sunlight) Mode",
55 .default_value = 0, 57 "Indoor (Fluorescent Lighting) Mode",
56 }, 58 "Manual Mode",
57 { 59 "Auto Mode",
58 .id = V4L2_CID_SATURATION, 60 NULL
59 .type = V4L2_CTRL_TYPE_INTEGER, 61};
60 .name = "Saturation", 62
61 .minimum = -100, 63static const struct v4l2_ctrl_config pwc_auto_white_balance_cfg = {
62 .maximum = 100, 64 .ops = &pwc_ctrl_ops,
63 .step = 1, 65 .id = V4L2_CID_AUTO_WHITE_BALANCE,
64 .default_value = 0, 66 .type = V4L2_CTRL_TYPE_MENU,
65 }, 67 .max = awb_auto,
66 { 68 .qmenu = pwc_auto_whitebal_qmenu,
67 .id = V4L2_CID_GAMMA, 69};
68 .type = V4L2_CTRL_TYPE_INTEGER, 70
69 .name = "Gamma", 71static const struct v4l2_ctrl_config pwc_autocontour_cfg = {
70 .minimum = 0, 72 .ops = &pwc_ctrl_ops,
71 .maximum = 32, 73 .id = PWC_CID_CUSTOM(autocontour),
72 .step = 1, 74 .type = V4L2_CTRL_TYPE_BOOLEAN,
73 .default_value = 0, 75 .name = "Auto contour",
74 }, 76 .min = 0,
75 { 77 .max = 1,
76 .id = V4L2_CID_RED_BALANCE, 78 .step = 1,
77 .type = V4L2_CTRL_TYPE_INTEGER, 79};
78 .name = "Red Gain", 80
79 .minimum = 0, 81static const struct v4l2_ctrl_config pwc_contour_cfg = {
80 .maximum = 256, 82 .ops = &pwc_ctrl_ops,
81 .step = 1, 83 .id = PWC_CID_CUSTOM(contour),
82 .default_value = 0, 84 .type = V4L2_CTRL_TYPE_INTEGER,
83 }, 85 .name = "Contour",
84 { 86 .min = 0,
85 .id = V4L2_CID_BLUE_BALANCE, 87 .max = 63,
86 .type = V4L2_CTRL_TYPE_INTEGER, 88 .step = 1,
87 .name = "Blue Gain", 89};
88 .minimum = 0, 90
89 .maximum = 256, 91static const struct v4l2_ctrl_config pwc_backlight_cfg = {
90 .step = 1, 92 .ops = &pwc_ctrl_ops,
91 .default_value = 0, 93 .id = V4L2_CID_BACKLIGHT_COMPENSATION,
92 }, 94 .type = V4L2_CTRL_TYPE_BOOLEAN,
93 { 95 .min = 0,
94 .id = V4L2_CID_AUTO_WHITE_BALANCE, 96 .max = 1,
95 .type = V4L2_CTRL_TYPE_BOOLEAN, 97 .step = 1,
96 .name = "Auto White Balance", 98};
97 .minimum = 0, 99
98 .maximum = 1, 100static const struct v4l2_ctrl_config pwc_flicker_cfg = {
99 .step = 1, 101 .ops = &pwc_ctrl_ops,
100 .default_value = 0, 102 .id = V4L2_CID_BAND_STOP_FILTER,
101 }, 103 .type = V4L2_CTRL_TYPE_BOOLEAN,
102 { 104 .min = 0,
103 .id = V4L2_CID_EXPOSURE, 105 .max = 1,
104 .type = V4L2_CTRL_TYPE_INTEGER, 106 .step = 1,
105 .name = "Shutter Speed (Exposure)", 107};
106 .minimum = 0, 108
107 .maximum = 256, 109static const struct v4l2_ctrl_config pwc_noise_reduction_cfg = {
108 .step = 1, 110 .ops = &pwc_ctrl_ops,
109 .default_value = 200, 111 .id = PWC_CID_CUSTOM(noise_reduction),
110 }, 112 .type = V4L2_CTRL_TYPE_INTEGER,
111 { 113 .name = "Dynamic Noise Reduction",
112 .id = V4L2_CID_AUTOGAIN, 114 .min = 0,
113 .type = V4L2_CTRL_TYPE_BOOLEAN, 115 .max = 3,
114 .name = "Auto Gain Enabled", 116 .step = 1,
115 .minimum = 0, 117};
116 .maximum = 1, 118
117 .step = 1, 119static const struct v4l2_ctrl_config pwc_save_user_cfg = {
118 .default_value = 1, 120 .ops = &pwc_ctrl_ops,
119 }, 121 .id = PWC_CID_CUSTOM(save_user),
120 { 122 .type = V4L2_CTRL_TYPE_BUTTON,
121 .id = V4L2_CID_GAIN, 123 .name = "Save User Settings",
122 .type = V4L2_CTRL_TYPE_INTEGER,
123 .name = "Gain Level",
124 .minimum = 0,
125 .maximum = 256,
126 .step = 1,
127 .default_value = 0,
128 },
129 {
130 .id = V4L2_CID_PRIVATE_SAVE_USER,
131 .type = V4L2_CTRL_TYPE_BUTTON,
132 .name = "Save User Settings",
133 .minimum = 0,
134 .maximum = 0,
135 .step = 0,
136 .default_value = 0,
137 },
138 {
139 .id = V4L2_CID_PRIVATE_RESTORE_USER,
140 .type = V4L2_CTRL_TYPE_BUTTON,
141 .name = "Restore User Settings",
142 .minimum = 0,
143 .maximum = 0,
144 .step = 0,
145 .default_value = 0,
146 },
147 {
148 .id = V4L2_CID_PRIVATE_RESTORE_FACTORY,
149 .type = V4L2_CTRL_TYPE_BUTTON,
150 .name = "Restore Factory Settings",
151 .minimum = 0,
152 .maximum = 0,
153 .step = 0,
154 .default_value = 0,
155 },
156 {
157 .id = V4L2_CID_PRIVATE_COLOUR_MODE,
158 .type = V4L2_CTRL_TYPE_BOOLEAN,
159 .name = "Colour mode",
160 .minimum = 0,
161 .maximum = 1,
162 .step = 1,
163 .default_value = 0,
164 },
165 {
166 .id = V4L2_CID_PRIVATE_AUTOCONTOUR,
167 .type = V4L2_CTRL_TYPE_BOOLEAN,
168 .name = "Auto contour",
169 .minimum = 0,
170 .maximum = 1,
171 .step = 1,
172 .default_value = 0,
173 },
174 {
175 .id = V4L2_CID_PRIVATE_CONTOUR,
176 .type = V4L2_CTRL_TYPE_INTEGER,
177 .name = "Contour",
178 .minimum = 0,
179 .maximum = 63,
180 .step = 1,
181 .default_value = 0,
182 },
183 {
184 .id = V4L2_CID_PRIVATE_BACKLIGHT,
185 .type = V4L2_CTRL_TYPE_BOOLEAN,
186 .name = "Backlight compensation",
187 .minimum = 0,
188 .maximum = 1,
189 .step = 1,
190 .default_value = 0,
191 },
192 {
193 .id = V4L2_CID_PRIVATE_FLICKERLESS,
194 .type = V4L2_CTRL_TYPE_BOOLEAN,
195 .name = "Flickerless",
196 .minimum = 0,
197 .maximum = 1,
198 .step = 1,
199 .default_value = 0,
200 },
201 {
202 .id = V4L2_CID_PRIVATE_NOISE_REDUCTION,
203 .type = V4L2_CTRL_TYPE_INTEGER,
204 .name = "Noise reduction",
205 .minimum = 0,
206 .maximum = 3,
207 .step = 1,
208 .default_value = 0,
209 },
210}; 124};
211 125
126static const struct v4l2_ctrl_config pwc_restore_user_cfg = {
127 .ops = &pwc_ctrl_ops,
128 .id = PWC_CID_CUSTOM(restore_user),
129 .type = V4L2_CTRL_TYPE_BUTTON,
130 .name = "Restore User Settings",
131};
132
133static const struct v4l2_ctrl_config pwc_restore_factory_cfg = {
134 .ops = &pwc_ctrl_ops,
135 .id = PWC_CID_CUSTOM(restore_factory),
136 .type = V4L2_CTRL_TYPE_BUTTON,
137 .name = "Restore Factory Settings",
138};
139
140int pwc_init_controls(struct pwc_device *pdev)
141{
142 struct v4l2_ctrl_handler *hdl;
143 struct v4l2_ctrl_config cfg;
144 int r, def;
145
146 hdl = &pdev->ctrl_handler;
147 r = v4l2_ctrl_handler_init(hdl, 20);
148 if (r)
149 return r;
150
151 /* Brightness, contrast, saturation, gamma */
152 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, BRIGHTNESS_FORMATTER, &def);
153 if (r || def > 127)
154 def = 63;
155 pdev->brightness = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
156 V4L2_CID_BRIGHTNESS, 0, 127, 1, def);
157
158 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, CONTRAST_FORMATTER, &def);
159 if (r || def > 63)
160 def = 31;
161 pdev->contrast = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
162 V4L2_CID_CONTRAST, 0, 63, 1, def);
163
164 if (pdev->type >= 675) {
165 if (pdev->type < 730)
166 pdev->saturation_fmt = SATURATION_MODE_FORMATTER2;
167 else
168 pdev->saturation_fmt = SATURATION_MODE_FORMATTER1;
169 r = pwc_get_s8_ctrl(pdev, GET_CHROM_CTL, pdev->saturation_fmt,
170 &def);
171 if (r || def < -100 || def > 100)
172 def = 0;
173 pdev->saturation = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
174 V4L2_CID_SATURATION, -100, 100, 1, def);
175 }
176
177 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, GAMMA_FORMATTER, &def);
178 if (r || def > 31)
179 def = 15;
180 pdev->gamma = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
181 V4L2_CID_GAMMA, 0, 31, 1, def);
182
183 /* auto white balance, red gain, blue gain */
184 r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL, WB_MODE_FORMATTER, &def);
185 if (r || def > awb_auto)
186 def = awb_auto;
187 cfg = pwc_auto_white_balance_cfg;
188 cfg.name = v4l2_ctrl_get_name(cfg.id);
189 cfg.def = def;
190 pdev->auto_white_balance = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
191 /* check auto controls to avoid NULL deref in v4l2_ctrl_auto_cluster */
192 if (!pdev->auto_white_balance)
193 return hdl->error;
194
195 r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
196 PRESET_MANUAL_RED_GAIN_FORMATTER, &def);
197 if (r)
198 def = 127;
199 pdev->red_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
200 V4L2_CID_RED_BALANCE, 0, 255, 1, def);
201
202 r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
203 PRESET_MANUAL_BLUE_GAIN_FORMATTER, &def);
204 if (r)
205 def = 127;
206 pdev->blue_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
207 V4L2_CID_BLUE_BALANCE, 0, 255, 1, def);
208
209 v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual,
210 pdev->auto_white_balance->cur.val == awb_auto);
211
212 /* autogain, gain */
213 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AGC_MODE_FORMATTER, &def);
214 if (r || (def != 0 && def != 0xff))
215 def = 0;
216 /* Note a register value if 0 means auto gain is on */
217 pdev->autogain = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
218 V4L2_CID_AUTOGAIN, 0, 1, 1, def == 0);
219 if (!pdev->autogain)
220 return hdl->error;
221
222 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, PRESET_AGC_FORMATTER, &def);
223 if (r || def > 63)
224 def = 31;
225 pdev->gain = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
226 V4L2_CID_GAIN, 0, 63, 1, def);
227
228 /* auto exposure, exposure */
229 if (DEVICE_USE_CODEC2(pdev->type)) {
230 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, SHUTTER_MODE_FORMATTER,
231 &def);
232 if (r || (def != 0 && def != 0xff))
233 def = 0;
234 /*
235 * def = 0 auto, def = ff manual
236 * menu idx 0 = auto, idx 1 = manual
237 */
238 pdev->exposure_auto = v4l2_ctrl_new_std_menu(hdl,
239 &pwc_ctrl_ops,
240 V4L2_CID_EXPOSURE_AUTO,
241 1, 0, def != 0);
242 if (!pdev->exposure_auto)
243 return hdl->error;
244
245 /* GET_LUM_CTL, PRESET_SHUTTER_FORMATTER is unreliable */
246 r = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
247 READ_SHUTTER_FORMATTER, &def);
248 if (r || def > 655)
249 def = 655;
250 pdev->exposure = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
251 V4L2_CID_EXPOSURE, 0, 655, 1, def);
252 /* CODEC2: separate auto gain & auto exposure */
253 v4l2_ctrl_auto_cluster(2, &pdev->autogain, 0, true);
254 v4l2_ctrl_auto_cluster(2, &pdev->exposure_auto,
255 V4L2_EXPOSURE_MANUAL, true);
256 } else if (DEVICE_USE_CODEC3(pdev->type)) {
257 /* GET_LUM_CTL, PRESET_SHUTTER_FORMATTER is unreliable */
258 r = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
259 READ_SHUTTER_FORMATTER, &def);
260 if (r || def > 255)
261 def = 255;
262 pdev->exposure = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
263 V4L2_CID_EXPOSURE, 0, 255, 1, def);
264 /* CODEC3: both gain and exposure controlled by autogain */
265 pdev->autogain_expo_cluster[0] = pdev->autogain;
266 pdev->autogain_expo_cluster[1] = pdev->gain;
267 pdev->autogain_expo_cluster[2] = pdev->exposure;
268 v4l2_ctrl_auto_cluster(3, pdev->autogain_expo_cluster,
269 0, true);
270 }
271
272 /* color / bw setting */
273 r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL, COLOUR_MODE_FORMATTER,
274 &def);
275 if (r || (def != 0 && def != 0xff))
276 def = 0xff;
277 /* def = 0 bw, def = ff color, menu idx 0 = color, idx 1 = bw */
278 pdev->colorfx = v4l2_ctrl_new_std_menu(hdl, &pwc_ctrl_ops,
279 V4L2_CID_COLORFX, 1, 0, def == 0);
280
281 /* autocontour, contour */
282 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &def);
283 if (r || (def != 0 && def != 0xff))
284 def = 0;
285 cfg = pwc_autocontour_cfg;
286 cfg.def = def == 0;
287 pdev->autocontour = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
288 if (!pdev->autocontour)
289 return hdl->error;
290
291 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &def);
292 if (r || def > 63)
293 def = 31;
294 cfg = pwc_contour_cfg;
295 cfg.def = def;
296 pdev->contour = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
297
298 v4l2_ctrl_auto_cluster(2, &pdev->autocontour, 0, false);
299
300 /* backlight */
301 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
302 BACK_LIGHT_COMPENSATION_FORMATTER, &def);
303 if (r || (def != 0 && def != 0xff))
304 def = 0;
305 cfg = pwc_backlight_cfg;
306 cfg.name = v4l2_ctrl_get_name(cfg.id);
307 cfg.def = def == 0;
308 pdev->backlight = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
309
310 /* flikker rediction */
311 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
312 FLICKERLESS_MODE_FORMATTER, &def);
313 if (r || (def != 0 && def != 0xff))
314 def = 0;
315 cfg = pwc_flicker_cfg;
316 cfg.name = v4l2_ctrl_get_name(cfg.id);
317 cfg.def = def == 0;
318 pdev->flicker = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
319
320 /* Dynamic noise reduction */
321 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
322 DYNAMIC_NOISE_CONTROL_FORMATTER, &def);
323 if (r || def > 3)
324 def = 2;
325 cfg = pwc_noise_reduction_cfg;
326 cfg.def = def;
327 pdev->noise_reduction = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
328
329 /* Save / Restore User / Factory Settings */
330 pdev->save_user = v4l2_ctrl_new_custom(hdl, &pwc_save_user_cfg, NULL);
331 pdev->restore_user = v4l2_ctrl_new_custom(hdl, &pwc_restore_user_cfg,
332 NULL);
333 if (pdev->restore_user)
334 pdev->restore_user->flags = V4L2_CTRL_FLAG_UPDATE;
335 pdev->restore_factory = v4l2_ctrl_new_custom(hdl,
336 &pwc_restore_factory_cfg,
337 NULL);
338 if (pdev->restore_factory)
339 pdev->restore_factory->flags = V4L2_CTRL_FLAG_UPDATE;
340
341 if (!(pdev->features & FEATURE_MOTOR_PANTILT))
342 return hdl->error;
343
344 /* Motor pan / tilt / reset */
345 pdev->motor_pan = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
346 V4L2_CID_PAN_RELATIVE, -4480, 4480, 64, 0);
347 if (!pdev->motor_pan)
348 return hdl->error;
349 pdev->motor_tilt = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
350 V4L2_CID_TILT_RELATIVE, -1920, 1920, 64, 0);
351 pdev->motor_pan_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
352 V4L2_CID_PAN_RESET, 0, 0, 0, 0);
353 pdev->motor_tilt_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
354 V4L2_CID_TILT_RESET, 0, 0, 0, 0);
355 v4l2_ctrl_cluster(4, &pdev->motor_pan);
356
357 return hdl->error;
358}
212 359
213static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f) 360static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f)
214{ 361{
@@ -284,10 +431,21 @@ static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
284} 431}
285 432
286/* ioctl(VIDIOC_SET_FMT) */ 433/* ioctl(VIDIOC_SET_FMT) */
287static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) 434
435static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
288{ 436{
437 struct pwc_device *pdev = video_drvdata(file);
289 int ret, fps, snapshot, compression, pixelformat; 438 int ret, fps, snapshot, compression, pixelformat;
290 439
440 if (!pdev->udev)
441 return -ENODEV;
442
443 if (pdev->capt_file != NULL &&
444 pdev->capt_file != file)
445 return -EBUSY;
446
447 pdev->capt_file = file;
448
291 ret = pwc_vidioc_try_fmt(pdev, f); 449 ret = pwc_vidioc_try_fmt(pdev, f);
292 if (ret<0) 450 if (ret<0)
293 return ret; 451 return ret;
@@ -309,7 +467,7 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
309 pixelformat != V4L2_PIX_FMT_PWC2) 467 pixelformat != V4L2_PIX_FMT_PWC2)
310 return -EINVAL; 468 return -EINVAL;
311 469
312 if (pdev->iso_init) 470 if (vb2_is_streaming(&pdev->vb_queue))
313 return -EBUSY; 471 return -EBUSY;
314 472
315 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " 473 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
@@ -343,13 +501,14 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
343 501
344static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 502static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
345{ 503{
346 struct video_device *vdev = video_devdata(file);
347 struct pwc_device *pdev = video_drvdata(file); 504 struct pwc_device *pdev = video_drvdata(file);
348 505
506 if (!pdev->udev)
507 return -ENODEV;
508
349 strcpy(cap->driver, PWC_NAME); 509 strcpy(cap->driver, PWC_NAME);
350 strlcpy(cap->card, vdev->name, sizeof(cap->card)); 510 strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card));
351 usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info)); 511 usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
352 cap->version = PWC_VERSION_CODE;
353 cap->capabilities = 512 cap->capabilities =
354 V4L2_CAP_VIDEO_CAPTURE | 513 V4L2_CAP_VIDEO_CAPTURE |
355 V4L2_CAP_STREAMING | 514 V4L2_CAP_STREAMING |
@@ -377,255 +536,396 @@ static int pwc_s_input(struct file *file, void *fh, unsigned int i)
377 return i ? -EINVAL : 0; 536 return i ? -EINVAL : 0;
378} 537}
379 538
380static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) 539static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
381{ 540{
382 int i, idx; 541 struct pwc_device *pdev =
383 u32 id; 542 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
384 543 int ret = 0;
385 id = c->id; 544
386 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { 545 /*
387 id &= V4L2_CTRL_ID_MASK; 546 * Sometimes it can take quite long for the pwc to complete usb control
388 id++; 547 * transfers, so release the modlock to give streaming by another
389 idx = -1; 548 * process / thread the chance to continue with a dqbuf.
390 for (i = 0; i < ARRAY_SIZE(pwc_controls); i++) { 549 */
391 if (pwc_controls[i].id < id) 550 mutex_unlock(&pdev->modlock);
392 continue; 551
393 if (idx >= 0 552 /*
394 && pwc_controls[i].id > pwc_controls[idx].id) 553 * Take the udev-lock to protect against the disconnect handler
395 continue; 554 * completing and setting dev->udev to NULL underneath us. Other code
396 idx = i; 555 * does not need to do this since it is protected by the modlock.
556 */
557 mutex_lock(&pdev->udevlock);
558
559 if (!pdev->udev) {
560 ret = -ENODEV;
561 goto leave;
562 }
563
564 switch (ctrl->id) {
565 case V4L2_CID_AUTO_WHITE_BALANCE:
566 if (pdev->color_bal_valid && time_before(jiffies,
567 pdev->last_color_bal_update + HZ / 4)) {
568 pdev->red_balance->val = pdev->last_red_balance;
569 pdev->blue_balance->val = pdev->last_blue_balance;
570 break;
397 } 571 }
398 if (idx < 0) 572 ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
399 return -EINVAL; 573 READ_RED_GAIN_FORMATTER,
400 memcpy(c, &pwc_controls[idx], sizeof pwc_controls[0]); 574 &pdev->red_balance->val);
401 return 0; 575 if (ret)
576 break;
577 ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
578 READ_BLUE_GAIN_FORMATTER,
579 &pdev->blue_balance->val);
580 if (ret)
581 break;
582 pdev->last_red_balance = pdev->red_balance->val;
583 pdev->last_blue_balance = pdev->blue_balance->val;
584 pdev->last_color_bal_update = jiffies;
585 pdev->color_bal_valid = true;
586 break;
587 case V4L2_CID_AUTOGAIN:
588 if (pdev->gain_valid && time_before(jiffies,
589 pdev->last_gain_update + HZ / 4)) {
590 pdev->gain->val = pdev->last_gain;
591 break;
592 }
593 ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
594 READ_AGC_FORMATTER, &pdev->gain->val);
595 if (ret)
596 break;
597 pdev->last_gain = pdev->gain->val;
598 pdev->last_gain_update = jiffies;
599 pdev->gain_valid = true;
600 if (!DEVICE_USE_CODEC3(pdev->type))
601 break;
602 /* Fall through for CODEC3 where autogain also controls expo */
603 case V4L2_CID_EXPOSURE_AUTO:
604 if (pdev->exposure_valid && time_before(jiffies,
605 pdev->last_exposure_update + HZ / 4)) {
606 pdev->exposure->val = pdev->last_exposure;
607 break;
608 }
609 ret = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
610 READ_SHUTTER_FORMATTER,
611 &pdev->exposure->val);
612 if (ret)
613 break;
614 pdev->last_exposure = pdev->exposure->val;
615 pdev->last_exposure_update = jiffies;
616 pdev->exposure_valid = true;
617 break;
618 default:
619 ret = -EINVAL;
402 } 620 }
403 for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) { 621
404 if (pwc_controls[i].id == c->id) { 622 if (ret)
405 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n"); 623 PWC_ERROR("g_ctrl %s error %d\n", ctrl->name, ret);
406 memcpy(c, &pwc_controls[i], sizeof(struct v4l2_queryctrl)); 624
407 return 0; 625leave:
626 mutex_unlock(&pdev->udevlock);
627 mutex_lock(&pdev->modlock);
628 return ret;
629}
630
631static int pwc_set_awb(struct pwc_device *pdev)
632{
633 int ret = 0;
634
635 if (pdev->auto_white_balance->is_new) {
636 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
637 WB_MODE_FORMATTER,
638 pdev->auto_white_balance->val);
639 if (ret)
640 return ret;
641
642 /* Update val when coming from auto or going to a preset */
643 if (pdev->red_balance->is_volatile ||
644 pdev->auto_white_balance->val == awb_indoor ||
645 pdev->auto_white_balance->val == awb_outdoor ||
646 pdev->auto_white_balance->val == awb_fl) {
647 if (!pdev->red_balance->is_new)
648 pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
649 READ_RED_GAIN_FORMATTER,
650 &pdev->red_balance->val);
651 if (!pdev->blue_balance->is_new)
652 pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
653 READ_BLUE_GAIN_FORMATTER,
654 &pdev->blue_balance->val);
655 }
656 if (pdev->auto_white_balance->val == awb_auto) {
657 pdev->red_balance->is_volatile = true;
658 pdev->blue_balance->is_volatile = true;
659 pdev->color_bal_valid = false; /* Force cache update */
660 } else {
661 pdev->red_balance->is_volatile = false;
662 pdev->blue_balance->is_volatile = false;
408 } 663 }
409 } 664 }
410 return -EINVAL; 665
666 if (ret == 0 && pdev->red_balance->is_new) {
667 if (pdev->auto_white_balance->val != awb_manual)
668 return -EBUSY;
669 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
670 PRESET_MANUAL_RED_GAIN_FORMATTER,
671 pdev->red_balance->val);
672 }
673
674 if (ret == 0 && pdev->blue_balance->is_new) {
675 if (pdev->auto_white_balance->val != awb_manual)
676 return -EBUSY;
677 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
678 PRESET_MANUAL_BLUE_GAIN_FORMATTER,
679 pdev->blue_balance->val);
680 }
681 return ret;
411} 682}
412 683
413static int pwc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) 684/* For CODEC2 models which have separate autogain and auto exposure */
685static int pwc_set_autogain(struct pwc_device *pdev)
414{ 686{
415 struct pwc_device *pdev = video_drvdata(file); 687 int ret = 0;
416 int ret; 688
689 if (pdev->autogain->is_new) {
690 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
691 AGC_MODE_FORMATTER,
692 pdev->autogain->val ? 0 : 0xff);
693 if (ret)
694 return ret;
695 if (pdev->autogain->val)
696 pdev->gain_valid = false; /* Force cache update */
697 else if (!pdev->gain->is_new)
698 pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
699 READ_AGC_FORMATTER,
700 &pdev->gain->val);
701 }
702 if (ret == 0 && pdev->gain->is_new) {
703 if (pdev->autogain->val)
704 return -EBUSY;
705 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
706 PRESET_AGC_FORMATTER,
707 pdev->gain->val);
708 }
709 return ret;
710}
417 711
418 switch (c->id) { 712/* For CODEC2 models which have separate autogain and auto exposure */
419 case V4L2_CID_BRIGHTNESS: 713static int pwc_set_exposure_auto(struct pwc_device *pdev)
420 c->value = pwc_get_brightness(pdev); 714{
421 if (c->value < 0) 715 int ret = 0;
422 return -EINVAL; 716 int is_auto = pdev->exposure_auto->val == V4L2_EXPOSURE_AUTO;
423 return 0; 717
424 case V4L2_CID_CONTRAST: 718 if (pdev->exposure_auto->is_new) {
425 c->value = pwc_get_contrast(pdev); 719 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
426 if (c->value < 0) 720 SHUTTER_MODE_FORMATTER,
427 return -EINVAL; 721 is_auto ? 0 : 0xff);
428 return 0; 722 if (ret)
429 case V4L2_CID_SATURATION: 723 return ret;
430 ret = pwc_get_saturation(pdev, &c->value); 724 if (is_auto)
431 if (ret < 0) 725 pdev->exposure_valid = false; /* Force cache update */
432 return -EINVAL; 726 else if (!pdev->exposure->is_new)
433 return 0; 727 pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
434 case V4L2_CID_GAMMA: 728 READ_SHUTTER_FORMATTER,
435 c->value = pwc_get_gamma(pdev); 729 &pdev->exposure->val);
436 if (c->value < 0) 730 }
437 return -EINVAL; 731 if (ret == 0 && pdev->exposure->is_new) {
438 return 0; 732 if (is_auto)
439 case V4L2_CID_RED_BALANCE: 733 return -EBUSY;
440 ret = pwc_get_red_gain(pdev, &c->value); 734 ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
441 if (ret < 0) 735 PRESET_SHUTTER_FORMATTER,
442 return -EINVAL; 736 pdev->exposure->val);
443 c->value >>= 8; 737 }
444 return 0; 738 return ret;
445 case V4L2_CID_BLUE_BALANCE: 739}
446 ret = pwc_get_blue_gain(pdev, &c->value);
447 if (ret < 0)
448 return -EINVAL;
449 c->value >>= 8;
450 return 0;
451 case V4L2_CID_AUTO_WHITE_BALANCE:
452 ret = pwc_get_awb(pdev);
453 if (ret < 0)
454 return -EINVAL;
455 c->value = (ret == PWC_WB_MANUAL) ? 0 : 1;
456 return 0;
457 case V4L2_CID_GAIN:
458 ret = pwc_get_agc(pdev, &c->value);
459 if (ret < 0)
460 return -EINVAL;
461 c->value >>= 8;
462 return 0;
463 case V4L2_CID_AUTOGAIN:
464 ret = pwc_get_agc(pdev, &c->value);
465 if (ret < 0)
466 return -EINVAL;
467 c->value = (c->value < 0) ? 1 : 0;
468 return 0;
469 case V4L2_CID_EXPOSURE:
470 ret = pwc_get_shutter_speed(pdev, &c->value);
471 if (ret < 0)
472 return -EINVAL;
473 return 0;
474 case V4L2_CID_PRIVATE_COLOUR_MODE:
475 ret = pwc_get_colour_mode(pdev, &c->value);
476 if (ret < 0)
477 return -EINVAL;
478 return 0;
479 case V4L2_CID_PRIVATE_AUTOCONTOUR:
480 ret = pwc_get_contour(pdev, &c->value);
481 if (ret < 0)
482 return -EINVAL;
483 c->value = (c->value == -1 ? 1 : 0);
484 return 0;
485 case V4L2_CID_PRIVATE_CONTOUR:
486 ret = pwc_get_contour(pdev, &c->value);
487 if (ret < 0)
488 return -EINVAL;
489 c->value >>= 10;
490 return 0;
491 case V4L2_CID_PRIVATE_BACKLIGHT:
492 ret = pwc_get_backlight(pdev, &c->value);
493 if (ret < 0)
494 return -EINVAL;
495 return 0;
496 case V4L2_CID_PRIVATE_FLICKERLESS:
497 ret = pwc_get_flicker(pdev, &c->value);
498 if (ret < 0)
499 return -EINVAL;
500 c->value = (c->value ? 1 : 0);
501 return 0;
502 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
503 ret = pwc_get_dynamic_noise(pdev, &c->value);
504 if (ret < 0)
505 return -EINVAL;
506 return 0;
507 740
508 case V4L2_CID_PRIVATE_SAVE_USER: 741/* For CODEC3 models which have autogain controlling both gain and exposure */
509 case V4L2_CID_PRIVATE_RESTORE_USER: 742static int pwc_set_autogain_expo(struct pwc_device *pdev)
510 case V4L2_CID_PRIVATE_RESTORE_FACTORY: 743{
511 return -EINVAL; 744 int ret = 0;
745
746 if (pdev->autogain->is_new) {
747 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
748 AGC_MODE_FORMATTER,
749 pdev->autogain->val ? 0 : 0xff);
750 if (ret)
751 return ret;
752 if (pdev->autogain->val) {
753 pdev->gain_valid = false; /* Force cache update */
754 pdev->exposure_valid = false; /* Force cache update */
755 } else {
756 if (!pdev->gain->is_new)
757 pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
758 READ_AGC_FORMATTER,
759 &pdev->gain->val);
760 if (!pdev->exposure->is_new)
761 pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
762 READ_SHUTTER_FORMATTER,
763 &pdev->exposure->val);
764 }
512 } 765 }
513 return -EINVAL; 766 if (ret == 0 && pdev->gain->is_new) {
767 if (pdev->autogain->val)
768 return -EBUSY;
769 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
770 PRESET_AGC_FORMATTER,
771 pdev->gain->val);
772 }
773 if (ret == 0 && pdev->exposure->is_new) {
774 if (pdev->autogain->val)
775 return -EBUSY;
776 ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
777 PRESET_SHUTTER_FORMATTER,
778 pdev->exposure->val);
779 }
780 return ret;
514} 781}
515 782
516static int pwc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) 783static int pwc_set_motor(struct pwc_device *pdev)
517{ 784{
518 struct pwc_device *pdev = video_drvdata(file);
519 int ret; 785 int ret;
786 u8 buf[4];
787
788 buf[0] = 0;
789 if (pdev->motor_pan_reset->is_new)
790 buf[0] |= 0x01;
791 if (pdev->motor_tilt_reset->is_new)
792 buf[0] |= 0x02;
793 if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) {
794 ret = send_control_msg(pdev, SET_MPT_CTL,
795 PT_RESET_CONTROL_FORMATTER, buf, 1);
796 if (ret < 0)
797 return ret;
798 }
520 799
521 switch (c->id) { 800 memset(buf, 0, sizeof(buf));
522 case V4L2_CID_BRIGHTNESS: 801 if (pdev->motor_pan->is_new) {
523 c->value <<= 9; 802 buf[0] = pdev->motor_pan->val & 0xFF;
524 ret = pwc_set_brightness(pdev, c->value); 803 buf[1] = (pdev->motor_pan->val >> 8);
804 }
805 if (pdev->motor_tilt->is_new) {
806 buf[2] = pdev->motor_tilt->val & 0xFF;
807 buf[3] = (pdev->motor_tilt->val >> 8);
808 }
809 if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) {
810 ret = send_control_msg(pdev, SET_MPT_CTL,
811 PT_RELATIVE_CONTROL_FORMATTER,
812 buf, sizeof(buf));
525 if (ret < 0) 813 if (ret < 0)
526 return -EINVAL; 814 return ret;
527 return 0; 815 }
816
817 return 0;
818}
819
820static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
821{
822 struct pwc_device *pdev =
823 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
824 int ret = 0;
825
826 /* See the comments on locking in pwc_g_volatile_ctrl */
827 mutex_unlock(&pdev->modlock);
828 mutex_lock(&pdev->udevlock);
829
830 if (!pdev->udev) {
831 ret = -ENODEV;
832 goto leave;
833 }
834
835 switch (ctrl->id) {
836 case V4L2_CID_BRIGHTNESS:
837 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
838 BRIGHTNESS_FORMATTER, ctrl->val);
839 break;
528 case V4L2_CID_CONTRAST: 840 case V4L2_CID_CONTRAST:
529 c->value <<= 10; 841 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
530 ret = pwc_set_contrast(pdev, c->value); 842 CONTRAST_FORMATTER, ctrl->val);
531 if (ret < 0) 843 break;
532 return -EINVAL;
533 return 0;
534 case V4L2_CID_SATURATION: 844 case V4L2_CID_SATURATION:
535 ret = pwc_set_saturation(pdev, c->value); 845 ret = pwc_set_s8_ctrl(pdev, SET_CHROM_CTL,
536 if (ret < 0) 846 pdev->saturation_fmt, ctrl->val);
537 return -EINVAL; 847 break;
538 return 0;
539 case V4L2_CID_GAMMA: 848 case V4L2_CID_GAMMA:
540 c->value <<= 11; 849 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
541 ret = pwc_set_gamma(pdev, c->value); 850 GAMMA_FORMATTER, ctrl->val);
542 if (ret < 0) 851 break;
543 return -EINVAL;
544 return 0;
545 case V4L2_CID_RED_BALANCE:
546 c->value <<= 8;
547 ret = pwc_set_red_gain(pdev, c->value);
548 if (ret < 0)
549 return -EINVAL;
550 return 0;
551 case V4L2_CID_BLUE_BALANCE:
552 c->value <<= 8;
553 ret = pwc_set_blue_gain(pdev, c->value);
554 if (ret < 0)
555 return -EINVAL;
556 return 0;
557 case V4L2_CID_AUTO_WHITE_BALANCE: 852 case V4L2_CID_AUTO_WHITE_BALANCE:
558 c->value = (c->value == 0) ? PWC_WB_MANUAL : PWC_WB_AUTO; 853 ret = pwc_set_awb(pdev);
559 ret = pwc_set_awb(pdev, c->value); 854 break;
560 if (ret < 0)
561 return -EINVAL;
562 return 0;
563 case V4L2_CID_EXPOSURE:
564 c->value <<= 8;
565 ret = pwc_set_shutter_speed(pdev, c->value ? 0 : 1, c->value);
566 if (ret < 0)
567 return -EINVAL;
568 return 0;
569 case V4L2_CID_AUTOGAIN: 855 case V4L2_CID_AUTOGAIN:
570 /* autogain off means nothing without a gain */ 856 if (DEVICE_USE_CODEC2(pdev->type))
571 if (c->value == 0) 857 ret = pwc_set_autogain(pdev);
572 return 0; 858 else if (DEVICE_USE_CODEC3(pdev->type))
573 ret = pwc_set_agc(pdev, c->value, 0); 859 ret = pwc_set_autogain_expo(pdev);
574 if (ret < 0) 860 else
575 return -EINVAL; 861 ret = -EINVAL;
576 return 0; 862 break;
577 case V4L2_CID_GAIN: 863 case V4L2_CID_EXPOSURE_AUTO:
578 c->value <<= 8; 864 if (DEVICE_USE_CODEC2(pdev->type))
579 ret = pwc_set_agc(pdev, 0, c->value); 865 ret = pwc_set_exposure_auto(pdev);
580 if (ret < 0) 866 else
581 return -EINVAL; 867 ret = -EINVAL;
582 return 0; 868 break;
583 case V4L2_CID_PRIVATE_SAVE_USER: 869 case V4L2_CID_COLORFX:
584 if (pwc_save_user(pdev)) 870 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
585 return -EINVAL; 871 COLOUR_MODE_FORMATTER,
586 return 0; 872 ctrl->val ? 0 : 0xff);
587 case V4L2_CID_PRIVATE_RESTORE_USER: 873 break;
588 if (pwc_restore_user(pdev)) 874 case PWC_CID_CUSTOM(autocontour):
589 return -EINVAL; 875 if (pdev->autocontour->is_new) {
590 return 0; 876 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
591 case V4L2_CID_PRIVATE_RESTORE_FACTORY: 877 AUTO_CONTOUR_FORMATTER,
592 if (pwc_restore_factory(pdev)) 878 pdev->autocontour->val ? 0 : 0xff);
593 return -EINVAL; 879 }
594 return 0; 880 if (ret == 0 && pdev->contour->is_new) {
595 case V4L2_CID_PRIVATE_COLOUR_MODE: 881 if (pdev->autocontour->val) {
596 ret = pwc_set_colour_mode(pdev, c->value); 882 ret = -EBUSY;
597 if (ret < 0) 883 break;
598 return -EINVAL; 884 }
599 return 0; 885 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
600 case V4L2_CID_PRIVATE_AUTOCONTOUR: 886 PRESET_CONTOUR_FORMATTER,
601 c->value = (c->value == 1) ? -1 : 0; 887 pdev->contour->val);
602 ret = pwc_set_contour(pdev, c->value); 888 }
603 if (ret < 0) 889 break;
604 return -EINVAL; 890 case V4L2_CID_BACKLIGHT_COMPENSATION:
605 return 0; 891 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
606 case V4L2_CID_PRIVATE_CONTOUR: 892 BACK_LIGHT_COMPENSATION_FORMATTER,
607 c->value <<= 10; 893 ctrl->val ? 0 : 0xff);
608 ret = pwc_set_contour(pdev, c->value); 894 break;
609 if (ret < 0) 895 case V4L2_CID_BAND_STOP_FILTER:
610 return -EINVAL; 896 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
611 return 0; 897 FLICKERLESS_MODE_FORMATTER,
612 case V4L2_CID_PRIVATE_BACKLIGHT: 898 ctrl->val ? 0 : 0xff);
613 ret = pwc_set_backlight(pdev, c->value); 899 break;
614 if (ret < 0) 900 case PWC_CID_CUSTOM(noise_reduction):
615 return -EINVAL; 901 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
616 return 0; 902 DYNAMIC_NOISE_CONTROL_FORMATTER,
617 case V4L2_CID_PRIVATE_FLICKERLESS: 903 ctrl->val);
618 ret = pwc_set_flicker(pdev, c->value); 904 break;
619 if (ret < 0) 905 case PWC_CID_CUSTOM(save_user):
620 return -EINVAL; 906 ret = pwc_button_ctrl(pdev, SAVE_USER_DEFAULTS_FORMATTER);
621 case V4L2_CID_PRIVATE_NOISE_REDUCTION: 907 break;
622 ret = pwc_set_dynamic_noise(pdev, c->value); 908 case PWC_CID_CUSTOM(restore_user):
623 if (ret < 0) 909 ret = pwc_button_ctrl(pdev, RESTORE_USER_DEFAULTS_FORMATTER);
624 return -EINVAL; 910 break;
625 return 0; 911 case PWC_CID_CUSTOM(restore_factory):
626 912 ret = pwc_button_ctrl(pdev,
913 RESTORE_FACTORY_DEFAULTS_FORMATTER);
914 break;
915 case V4L2_CID_PAN_RELATIVE:
916 ret = pwc_set_motor(pdev);
917 break;
918 default:
919 ret = -EINVAL;
627 } 920 }
628 return -EINVAL; 921
922 if (ret)
923 PWC_ERROR("s_ctrl %s error %d\n", ctrl->name, ret);
924
925leave:
926 mutex_unlock(&pdev->udevlock);
927 mutex_lock(&pdev->modlock);
928 return ret;
629} 929}
630 930
631static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) 931static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
@@ -667,157 +967,77 @@ static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *
667 return pwc_vidioc_try_fmt(pdev, f); 967 return pwc_vidioc_try_fmt(pdev, f);
668} 968}
669 969
670static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 970static int pwc_reqbufs(struct file *file, void *fh,
971 struct v4l2_requestbuffers *rb)
671{ 972{
672 struct pwc_device *pdev = video_drvdata(file); 973 struct pwc_device *pdev = video_drvdata(file);
673 974
674 return pwc_vidioc_set_fmt(pdev, f); 975 if (pdev->capt_file != NULL &&
675} 976 pdev->capt_file != file)
676 977 return -EBUSY;
677static int pwc_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
678{
679 int nbuffers;
680 978
681 PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n", rb->count); 979 pdev->capt_file = file;
682 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
683 return -EINVAL;
684 if (rb->memory != V4L2_MEMORY_MMAP)
685 return -EINVAL;
686 980
687 nbuffers = rb->count; 981 return vb2_reqbufs(&pdev->vb_queue, rb);
688 if (nbuffers < 2)
689 nbuffers = 2;
690 else if (nbuffers > pwc_mbufs)
691 nbuffers = pwc_mbufs;
692 /* Force to use our # of buffers */
693 rb->count = pwc_mbufs;
694 return 0;
695} 982}
696 983
697static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) 984static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
698{ 985{
699 struct pwc_device *pdev = video_drvdata(file); 986 struct pwc_device *pdev = video_drvdata(file);
700 int index;
701 987
702 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n", buf->index); 988 return vb2_querybuf(&pdev->vb_queue, buf);
703 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
704 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n");
705 return -EINVAL;
706 }
707 index = buf->index;
708 if (index < 0 || index >= pwc_mbufs) {
709 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index);
710 return -EINVAL;
711 }
712
713 buf->m.offset = index * pdev->len_per_image;
714 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
715 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
716 else
717 buf->bytesused = pdev->view.size;
718 buf->field = V4L2_FIELD_NONE;
719 buf->memory = V4L2_MEMORY_MMAP;
720 /*buf->flags = V4L2_BUF_FLAG_MAPPED;*/
721 buf->length = pdev->len_per_image;
722
723 PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n", buf->index);
724 PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n", buf->m.offset);
725 PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n", buf->bytesused);
726
727 return 0;
728} 989}
729 990
730static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) 991static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
731{ 992{
732 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n", buf->index); 993 struct pwc_device *pdev = video_drvdata(file);
733 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
734 return -EINVAL;
735 if (buf->memory != V4L2_MEMORY_MMAP)
736 return -EINVAL;
737 if (buf->index >= pwc_mbufs)
738 return -EINVAL;
739 994
740 buf->flags |= V4L2_BUF_FLAG_QUEUED; 995 if (!pdev->udev)
741 buf->flags &= ~V4L2_BUF_FLAG_DONE; 996 return -ENODEV;
742 997
743 return 0; 998 if (pdev->capt_file != file)
999 return -EBUSY;
1000
1001 return vb2_qbuf(&pdev->vb_queue, buf);
744} 1002}
745 1003
746static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) 1004static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
747{ 1005{
748 DECLARE_WAITQUEUE(wait, current);
749 struct pwc_device *pdev = video_drvdata(file); 1006 struct pwc_device *pdev = video_drvdata(file);
750 int ret;
751 1007
752 PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n"); 1008 if (!pdev->udev)
1009 return -ENODEV;
753 1010
754 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1011 if (pdev->capt_file != file)
755 return -EINVAL; 1012 return -EBUSY;
756
757 add_wait_queue(&pdev->frameq, &wait);
758 while (pdev->full_frames == NULL) {
759 if (pdev->error_status) {
760 remove_wait_queue(&pdev->frameq, &wait);
761 set_current_state(TASK_RUNNING);
762 return -pdev->error_status;
763 }
764
765 if (signal_pending(current)) {
766 remove_wait_queue(&pdev->frameq, &wait);
767 set_current_state(TASK_RUNNING);
768 return -ERESTARTSYS;
769 }
770 mutex_unlock(&pdev->modlock);
771 schedule();
772 set_current_state(TASK_INTERRUPTIBLE);
773 mutex_lock(&pdev->modlock);
774 }
775 remove_wait_queue(&pdev->frameq, &wait);
776 set_current_state(TASK_RUNNING);
777
778 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n");
779 /* Decompress data in pdev->images[pdev->fill_image] */
780 ret = pwc_handle_frame(pdev);
781 if (ret)
782 return -EFAULT;
783 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n");
784
785 buf->index = pdev->fill_image;
786 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
787 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
788 else
789 buf->bytesused = pdev->view.size;
790 buf->flags = V4L2_BUF_FLAG_MAPPED;
791 buf->field = V4L2_FIELD_NONE;
792 do_gettimeofday(&buf->timestamp);
793 buf->sequence = 0;
794 buf->memory = V4L2_MEMORY_MMAP;
795 buf->m.offset = pdev->fill_image * pdev->len_per_image;
796 buf->length = pdev->len_per_image;
797 pwc_next_image(pdev);
798
799 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n", buf->index);
800 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n", buf->length);
801 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n", buf->m.offset);
802 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n", buf->bytesused);
803 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n");
804 return 0;
805 1013
1014 return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK);
806} 1015}
807 1016
808static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) 1017static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
809{ 1018{
810 struct pwc_device *pdev = video_drvdata(file); 1019 struct pwc_device *pdev = video_drvdata(file);
811 1020
812 return pwc_isoc_init(pdev); 1021 if (!pdev->udev)
1022 return -ENODEV;
1023
1024 if (pdev->capt_file != file)
1025 return -EBUSY;
1026
1027 return vb2_streamon(&pdev->vb_queue, i);
813} 1028}
814 1029
815static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) 1030static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
816{ 1031{
817 struct pwc_device *pdev = video_drvdata(file); 1032 struct pwc_device *pdev = video_drvdata(file);
818 1033
819 pwc_isoc_cleanup(pdev); 1034 if (!pdev->udev)
820 return 0; 1035 return -ENODEV;
1036
1037 if (pdev->capt_file != file)
1038 return -EBUSY;
1039
1040 return vb2_streamoff(&pdev->vb_queue, i);
821} 1041}
822 1042
823static int pwc_enum_framesizes(struct file *file, void *fh, 1043static int pwc_enum_framesizes(struct file *file, void *fh,
@@ -896,9 +1116,6 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = {
896 .vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap, 1116 .vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap,
897 .vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap, 1117 .vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap,
898 .vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap, 1118 .vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap,
899 .vidioc_queryctrl = pwc_queryctrl,
900 .vidioc_g_ctrl = pwc_g_ctrl,
901 .vidioc_s_ctrl = pwc_s_ctrl,
902 .vidioc_reqbufs = pwc_reqbufs, 1119 .vidioc_reqbufs = pwc_reqbufs,
903 .vidioc_querybuf = pwc_querybuf, 1120 .vidioc_querybuf = pwc_querybuf,
904 .vidioc_qbuf = pwc_qbuf, 1121 .vidioc_qbuf = pwc_qbuf,
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 083f8b15df73..0e4e2d7b7872 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -29,7 +29,6 @@
29#include <linux/usb.h> 29#include <linux/usb.h>
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/wait.h> 31#include <linux/wait.h>
32#include <linux/version.h>
33#include <linux/mutex.h> 32#include <linux/mutex.h>
34#include <linux/mm.h> 33#include <linux/mm.h>
35#include <linux/slab.h> 34#include <linux/slab.h>
@@ -37,19 +36,16 @@
37#include <linux/videodev2.h> 36#include <linux/videodev2.h>
38#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
39#include <media/v4l2-ioctl.h> 38#include <media/v4l2-ioctl.h>
39#include <media/v4l2-ctrls.h>
40#include <media/videobuf2-vmalloc.h>
40#ifdef CONFIG_USB_PWC_INPUT_EVDEV 41#ifdef CONFIG_USB_PWC_INPUT_EVDEV
41#include <linux/input.h> 42#include <linux/input.h>
42#endif 43#endif
43 44
44#include "pwc-uncompress.h"
45#include <media/pwc-ioctl.h> 45#include <media/pwc-ioctl.h>
46 46
47/* Version block */ 47/* Version block */
48#define PWC_MAJOR 10 48#define PWC_VERSION "10.0.15"
49#define PWC_MINOR 0
50#define PWC_EXTRAMINOR 12
51#define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR)
52#define PWC_VERSION "10.0.14"
53#define PWC_NAME "pwc" 49#define PWC_NAME "pwc"
54#define PFX PWC_NAME ": " 50#define PFX PWC_NAME ": "
55 51
@@ -81,9 +77,9 @@
81#define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE) 77#define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE)
82 78
83#define PWC_DEBUG(level, fmt, args...) do {\ 79#define PWC_DEBUG(level, fmt, args...) do {\
84 if ((PWC_DEBUG_LEVEL_ ##level) & pwc_trace) \ 80 if ((PWC_DEBUG_LEVEL_ ##level) & pwc_trace) \
85 printk(KERN_DEBUG PFX fmt, ##args); \ 81 printk(KERN_DEBUG PFX fmt, ##args); \
86 } while(0) 82 } while (0)
87 83
88#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args) 84#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
89#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args) 85#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
@@ -110,25 +106,21 @@
110#define FEATURE_CODEC1 0x0002 106#define FEATURE_CODEC1 0x0002
111#define FEATURE_CODEC2 0x0004 107#define FEATURE_CODEC2 0x0004
112 108
113/* Turn certain features on/off */
114#define PWC_INT_PIPE 0
115
116/* Ignore errors in the first N frames, to allow for startup delays */ 109/* Ignore errors in the first N frames, to allow for startup delays */
117#define FRAME_LOWMARK 5 110#define FRAME_LOWMARK 5
118 111
119/* Size and number of buffers for the ISO pipe. */ 112/* Size and number of buffers for the ISO pipe. */
120#define MAX_ISO_BUFS 2 113#define MAX_ISO_BUFS 3
121#define ISO_FRAMES_PER_DESC 10 114#define ISO_FRAMES_PER_DESC 10
122#define ISO_MAX_FRAME_SIZE 960 115#define ISO_MAX_FRAME_SIZE 960
123#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE) 116#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
124 117
125/* Frame buffers: contains compressed or uncompressed video data. */
126#define MAX_FRAMES 5
127/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */ 118/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
128#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE) 119#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
129 120
130/* Absolute maximum number of buffers available for mmap() */ 121/* Absolute minimum and maximum number of buffers available for mmap() */
131#define MAX_IMAGES 10 122#define MIN_FRAMES 2
123#define MAX_FRAMES 16
132 124
133/* Some macros to quickly find the type of a webcam */ 125/* Some macros to quickly find the type of a webcam */
134#define DEVICE_USE_CODEC1(x) ((x)<675) 126#define DEVICE_USE_CODEC1(x) ((x)<675)
@@ -136,149 +128,221 @@
136#define DEVICE_USE_CODEC3(x) ((x)>=700) 128#define DEVICE_USE_CODEC3(x) ((x)>=700)
137#define DEVICE_USE_CODEC23(x) ((x)>=675) 129#define DEVICE_USE_CODEC23(x) ((x)>=675)
138 130
139/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ 131/* from pwc-dec.h */
140struct pwc_iso_buf 132#define PWCX_FLAG_PLANAR 0x0001
141{ 133
142 void *data; 134/* Request types: video */
143 int length; 135#define SET_LUM_CTL 0x01
144 int read; 136#define GET_LUM_CTL 0x02
145 struct urb *urb; 137#define SET_CHROM_CTL 0x03
146}; 138#define GET_CHROM_CTL 0x04
139#define SET_STATUS_CTL 0x05
140#define GET_STATUS_CTL 0x06
141#define SET_EP_STREAM_CTL 0x07
142#define GET_EP_STREAM_CTL 0x08
143#define GET_XX_CTL 0x09
144#define SET_XX_CTL 0x0A
145#define GET_XY_CTL 0x0B
146#define SET_XY_CTL 0x0C
147#define SET_MPT_CTL 0x0D
148#define GET_MPT_CTL 0x0E
149
150/* Selectors for the Luminance controls [GS]ET_LUM_CTL */
151#define AGC_MODE_FORMATTER 0x2000
152#define PRESET_AGC_FORMATTER 0x2100
153#define SHUTTER_MODE_FORMATTER 0x2200
154#define PRESET_SHUTTER_FORMATTER 0x2300
155#define PRESET_CONTOUR_FORMATTER 0x2400
156#define AUTO_CONTOUR_FORMATTER 0x2500
157#define BACK_LIGHT_COMPENSATION_FORMATTER 0x2600
158#define CONTRAST_FORMATTER 0x2700
159#define DYNAMIC_NOISE_CONTROL_FORMATTER 0x2800
160#define FLICKERLESS_MODE_FORMATTER 0x2900
161#define AE_CONTROL_SPEED 0x2A00
162#define BRIGHTNESS_FORMATTER 0x2B00
163#define GAMMA_FORMATTER 0x2C00
164
165/* Selectors for the Chrominance controls [GS]ET_CHROM_CTL */
166#define WB_MODE_FORMATTER 0x1000
167#define AWB_CONTROL_SPEED_FORMATTER 0x1100
168#define AWB_CONTROL_DELAY_FORMATTER 0x1200
169#define PRESET_MANUAL_RED_GAIN_FORMATTER 0x1300
170#define PRESET_MANUAL_BLUE_GAIN_FORMATTER 0x1400
171#define COLOUR_MODE_FORMATTER 0x1500
172#define SATURATION_MODE_FORMATTER1 0x1600
173#define SATURATION_MODE_FORMATTER2 0x1700
174
175/* Selectors for the Status controls [GS]ET_STATUS_CTL */
176#define SAVE_USER_DEFAULTS_FORMATTER 0x0200
177#define RESTORE_USER_DEFAULTS_FORMATTER 0x0300
178#define RESTORE_FACTORY_DEFAULTS_FORMATTER 0x0400
179#define READ_AGC_FORMATTER 0x0500
180#define READ_SHUTTER_FORMATTER 0x0600
181#define READ_RED_GAIN_FORMATTER 0x0700
182#define READ_BLUE_GAIN_FORMATTER 0x0800
183
184/* Formatters for the motorized pan & tilt [GS]ET_MPT_CTL */
185#define PT_RELATIVE_CONTROL_FORMATTER 0x01
186#define PT_RESET_CONTROL_FORMATTER 0x02
187#define PT_STATUS_FORMATTER 0x03
147 188
148/* intermediate buffers with raw data from the USB cam */ 189/* intermediate buffers with raw data from the USB cam */
149struct pwc_frame_buf 190struct pwc_frame_buf
150{ 191{
151 void *data; 192 struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
152 volatile int filled; /* number of bytes filled */ 193 struct list_head list;
153 struct pwc_frame_buf *next; /* list */ 194 void *data;
154}; 195 int filled; /* number of bytes filled */
155
156/* additionnal informations used when dealing image between kernel and userland */
157struct pwc_imgbuf
158{
159 unsigned long offset; /* offset of this buffer in the big array of image_data */
160 int vma_use_count; /* count the number of time this memory is mapped */
161}; 196};
162 197
163struct pwc_device 198struct pwc_device
164{ 199{
165 struct video_device vdev; 200 struct video_device vdev;
166 201 struct mutex modlock;
167 /* Pointer to our usb_device, may be NULL after unplug */ 202
168 struct usb_device *udev; 203 /* Pointer to our usb_device, may be NULL after unplug */
169 204 struct usb_device *udev;
170 int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */ 205 /* Protects the setting of udev to NULL by our disconnect handler */
171 int release; /* release number */ 206 struct mutex udevlock;
172 int features; /* feature bits */ 207
173 char serial[30]; /* serial number (string) */ 208 /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
174 int error_status; /* set when something goes wrong with the cam (unplugged, USB errors) */ 209 int type;
175 int usb_init; /* set when the cam has been initialized over USB */ 210 int release; /* release number */
176 211 int features; /* feature bits */
177 /*** Video data ***/ 212 char serial[30]; /* serial number (string) */
178 int vopen; /* flag */ 213
179 int vendpoint; /* video isoc endpoint */ 214 /*** Video data ***/
180 int vcinterface; /* video control interface */ 215 struct file *capt_file; /* file doing video capture */
181 int valternate; /* alternate interface needed */ 216 int vendpoint; /* video isoc endpoint */
182 int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ 217 int vcinterface; /* video control interface */
183 int pixfmt; /* pixelformat: V4L2_PIX_FMT_YUV420 or raw: _PWC1, _PWC2 */ 218 int valternate; /* alternate interface needed */
184 int vframe_count; /* received frames */ 219 int vframes, vsize; /* frames-per-second & size (see PSZ_*) */
185 int vframes_dumped; /* counter for dumped frames */ 220 int pixfmt; /* pixelformat: V4L2_PIX_FMT_YUV420 or _PWCX */
186 int vframes_error; /* frames received in error */ 221 int vframe_count; /* received frames */
187 int vmax_packet_size; /* USB maxpacket size */ 222 int vmax_packet_size; /* USB maxpacket size */
188 int vlast_packet_size; /* for frame synchronisation */ 223 int vlast_packet_size; /* for frame synchronisation */
189 int visoc_errors; /* number of contiguous ISOC errors */ 224 int visoc_errors; /* number of contiguous ISOC errors */
190 int vcompression; /* desired compression factor */ 225 int vcompression; /* desired compression factor */
191 int vbandlength; /* compressed band length; 0 is uncompressed */ 226 int vbandlength; /* compressed band length; 0 is uncompressed */
192 char vsnapshot; /* snapshot mode */ 227 char vsnapshot; /* snapshot mode */
193 char vsync; /* used by isoc handler */ 228 char vsync; /* used by isoc handler */
194 char vmirror; /* for ToUCaM series */ 229 char vmirror; /* for ToUCaM series */
195 char unplugged; 230 char power_save; /* Do powersaving for this cam */
196 231
197 int cmd_len; 232 int cmd_len;
198 unsigned char cmd_buf[13]; 233 unsigned char cmd_buf[13];
199 234
200 /* The image acquisition requires 3 to 4 steps: 235 struct urb *urbs[MAX_ISO_BUFS];
201 1. data is gathered in short packets from the USB controller 236 char iso_init;
202 2. data is synchronized and packed into a frame buffer 237
203 3a. in case data is compressed, decompress it directly into image buffer 238 /* videobuf2 queue and queued buffers list */
204 3b. in case data is uncompressed, copy into image buffer with viewport 239 struct vb2_queue vb_queue;
205 4. data is transferred to the user process 240 struct list_head queued_bufs;
206 241 spinlock_t queued_bufs_lock;
207 Note that MAX_ISO_BUFS != MAX_FRAMES != MAX_IMAGES.... 242
208 We have in effect a back-to-back-double-buffer system. 243 /*
209 */ 244 * Frame currently being filled, this only gets touched by the
210 /* 1: isoc */ 245 * isoc urb complete handler, and by stream start / stop since
211 struct pwc_iso_buf sbuf[MAX_ISO_BUFS]; 246 * start / stop touch it before / after starting / killing the urbs
212 char iso_init; 247 * no locking is needed around this
213 248 */
214 /* 2: frame */ 249 struct pwc_frame_buf *fill_buf;
215 struct pwc_frame_buf *fbuf; /* all frames */ 250
216 struct pwc_frame_buf *empty_frames, *empty_frames_tail; /* all empty frames */ 251 int frame_header_size, frame_trailer_size;
217 struct pwc_frame_buf *full_frames, *full_frames_tail; /* all filled frames */ 252 int frame_size;
218 struct pwc_frame_buf *fill_frame; /* frame currently being filled */ 253 int frame_total_size; /* including header & trailer */
219 struct pwc_frame_buf *read_frame; /* frame currently read by user process */ 254 int drop_frames;
220 int frame_header_size, frame_trailer_size; 255
221 int frame_size; 256 void *decompress_data; /* private data for decompression engine */
222 int frame_total_size; /* including header & trailer */ 257
223 int drop_frames; 258 /*
224 259 * We have an 'image' and a 'view', where 'image' is the fixed-size img
225 /* 3: decompression */ 260 * as delivered by the camera, and 'view' is the size requested by the
226 void *decompress_data; /* private data for decompression engine */ 261 * program. The camera image is centered in this viewport, laced with
227 262 * a gray or black border. view_min <= image <= view <= view_max;
228 /* 4: image */ 263 */
229 /* We have an 'image' and a 'view', where 'image' is the fixed-size image 264 int image_mask; /* supported sizes */
230 as delivered by the camera, and 'view' is the size requested by the 265 struct pwc_coord view_min, view_max; /* minimum and maximum view */
231 program. The camera image is centered in this viewport, laced with 266 struct pwc_coord abs_max; /* maximum supported size */
232 a gray or black border. view_min <= image <= view <= view_max; 267 struct pwc_coord image, view; /* image and viewport size */
233 */ 268 struct pwc_coord offset; /* offset of the viewport */
234 int image_mask; /* bitmask of supported sizes */ 269
235 struct pwc_coord view_min, view_max; /* minimum and maximum viewable sizes */ 270 /*** motorized pan/tilt feature */
236 struct pwc_coord abs_max; /* maximum supported size with compression */ 271 struct pwc_mpt_range angle_range;
237 struct pwc_coord image, view; /* image and viewport size */ 272 int pan_angle; /* in degrees * 100 */
238 struct pwc_coord offset; /* offset within the viewport */ 273 int tilt_angle; /* absolute angle; 0,0 is home */
239 274
240 void *image_data; /* total buffer, which is subdivided into ... */ 275 /*
241 struct pwc_imgbuf images[MAX_IMAGES];/* ...several images... */ 276 * Set to 1 when the user push the button, reset to 0
242 int fill_image; /* ...which are rotated. */ 277 * when this value is read from sysfs.
243 int len_per_image; /* length per image */ 278 */
244 int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ 279 int snapshot_button_status;
245 int image_used[MAX_IMAGES]; /* For MCAPTURE and SYNC */
246
247 struct mutex modlock; /* to prevent races in video_open(), etc */
248 spinlock_t ptrlock; /* for manipulating the buffer pointers */
249
250 /*** motorized pan/tilt feature */
251 struct pwc_mpt_range angle_range;
252 int pan_angle; /* in degrees * 100 */
253 int tilt_angle; /* absolute angle; 0,0 is home position */
254 int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */
255#ifdef CONFIG_USB_PWC_INPUT_EVDEV 280#ifdef CONFIG_USB_PWC_INPUT_EVDEV
256 struct input_dev *button_dev; /* webcam snapshot button input */ 281 struct input_dev *button_dev; /* webcam snapshot button input */
257 char button_phys[64]; 282 char button_phys[64];
258#endif 283#endif
259 284
260 /*** Misc. data ***/ 285 /* controls */
261 wait_queue_head_t frameq; /* When waiting for a frame to finish... */ 286 struct v4l2_ctrl_handler ctrl_handler;
262#if PWC_INT_PIPE 287 u16 saturation_fmt;
263 void *usb_int_handler; /* for the interrupt endpoint */ 288 struct v4l2_ctrl *brightness;
264#endif 289 struct v4l2_ctrl *contrast;
290 struct v4l2_ctrl *saturation;
291 struct v4l2_ctrl *gamma;
292 struct {
293 /* awb / red-blue balance cluster */
294 struct v4l2_ctrl *auto_white_balance;
295 struct v4l2_ctrl *red_balance;
296 struct v4l2_ctrl *blue_balance;
297 /* usb ctrl transfers are slow, so we cache things */
298 int color_bal_valid;
299 unsigned long last_color_bal_update; /* In jiffies */
300 s32 last_red_balance;
301 s32 last_blue_balance;
302 };
303 struct {
304 /* autogain / gain cluster */
305 struct v4l2_ctrl *autogain;
306 struct v4l2_ctrl *gain;
307 int gain_valid;
308 unsigned long last_gain_update; /* In jiffies */
309 s32 last_gain;
310 };
311 struct {
312 /* exposure_auto / exposure cluster */
313 struct v4l2_ctrl *exposure_auto;
314 struct v4l2_ctrl *exposure;
315 int exposure_valid;
316 unsigned long last_exposure_update; /* In jiffies */
317 s32 last_exposure;
318 };
319 struct v4l2_ctrl *colorfx;
320 struct {
321 /* autocontour/contour cluster */
322 struct v4l2_ctrl *autocontour;
323 struct v4l2_ctrl *contour;
324 };
325 struct v4l2_ctrl *backlight;
326 struct v4l2_ctrl *flicker;
327 struct v4l2_ctrl *noise_reduction;
328 struct v4l2_ctrl *save_user;
329 struct v4l2_ctrl *restore_user;
330 struct v4l2_ctrl *restore_factory;
331 struct {
332 /* motor control cluster */
333 struct v4l2_ctrl *motor_pan;
334 struct v4l2_ctrl *motor_tilt;
335 struct v4l2_ctrl *motor_pan_reset;
336 struct v4l2_ctrl *motor_tilt_reset;
337 };
338 /* CODEC3 models have both gain and exposure controlled by autogain */
339 struct v4l2_ctrl *autogain_expo_cluster[3];
265}; 340};
266 341
267#ifdef __cplusplus
268extern "C" {
269#endif
270
271/* Global variables */ 342/* Global variables */
272#ifdef CONFIG_USB_PWC_DEBUG 343#ifdef CONFIG_USB_PWC_DEBUG
273extern int pwc_trace; 344extern int pwc_trace;
274#endif 345#endif
275extern int pwc_mbufs;
276
277/** functions in pwc-if.c */
278int pwc_handle_frame(struct pwc_device *pdev);
279void pwc_next_image(struct pwc_device *pdev);
280int pwc_isoc_init(struct pwc_device *pdev);
281void pwc_isoc_cleanup(struct pwc_device *pdev);
282 346
283/** Functions in pwc-misc.c */ 347/** Functions in pwc-misc.c */
284/* sizes in pixels */ 348/* sizes in pixels */
@@ -291,50 +355,25 @@ void pwc_construct(struct pwc_device *pdev);
291/* Request a certain video mode. Returns < 0 if not possible */ 355/* Request a certain video mode. Returns < 0 if not possible */
292extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); 356extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
293extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size); 357extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
294/* Calculate the number of bytes per image (not frame) */
295extern int pwc_mpt_reset(struct pwc_device *pdev, int flags); 358extern int pwc_mpt_reset(struct pwc_device *pdev, int flags);
296extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt); 359extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt);
297
298/* Various controls; should be obvious. Value 0..65535, or < 0 on error */
299extern int pwc_get_brightness(struct pwc_device *pdev);
300extern int pwc_set_brightness(struct pwc_device *pdev, int value);
301extern int pwc_get_contrast(struct pwc_device *pdev);
302extern int pwc_set_contrast(struct pwc_device *pdev, int value);
303extern int pwc_get_gamma(struct pwc_device *pdev);
304extern int pwc_set_gamma(struct pwc_device *pdev, int value);
305extern int pwc_get_saturation(struct pwc_device *pdev, int *value);
306extern int pwc_set_saturation(struct pwc_device *pdev, int value);
307extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); 360extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
308extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); 361extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
309extern int pwc_restore_user(struct pwc_device *pdev); 362extern int send_control_msg(struct pwc_device *pdev,
310extern int pwc_save_user(struct pwc_device *pdev); 363 u8 request, u16 value, void *buf, int buflen);
311extern int pwc_restore_factory(struct pwc_device *pdev); 364
312 365/* Control get / set helpers */
313/* exported for use by v4l2 controls */ 366int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data);
314extern int pwc_get_red_gain(struct pwc_device *pdev, int *value); 367int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data);
315extern int pwc_set_red_gain(struct pwc_device *pdev, int value); 368int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data);
316extern int pwc_get_blue_gain(struct pwc_device *pdev, int *value); 369#define pwc_set_s8_ctrl pwc_set_u8_ctrl
317extern int pwc_set_blue_gain(struct pwc_device *pdev, int value); 370int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *dat);
318extern int pwc_get_awb(struct pwc_device *pdev); 371int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data);
319extern int pwc_set_awb(struct pwc_device *pdev, int mode); 372int pwc_button_ctrl(struct pwc_device *pdev, u16 value);
320extern int pwc_set_agc(struct pwc_device *pdev, int mode, int value); 373int pwc_init_controls(struct pwc_device *pdev);
321extern int pwc_get_agc(struct pwc_device *pdev, int *value);
322extern int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value);
323extern int pwc_get_shutter_speed(struct pwc_device *pdev, int *value);
324
325extern int pwc_set_colour_mode(struct pwc_device *pdev, int colour);
326extern int pwc_get_colour_mode(struct pwc_device *pdev, int *colour);
327extern int pwc_set_contour(struct pwc_device *pdev, int contour);
328extern int pwc_get_contour(struct pwc_device *pdev, int *contour);
329extern int pwc_set_backlight(struct pwc_device *pdev, int backlight);
330extern int pwc_get_backlight(struct pwc_device *pdev, int *backlight);
331extern int pwc_set_flicker(struct pwc_device *pdev, int flicker);
332extern int pwc_get_flicker(struct pwc_device *pdev, int *flicker);
333extern int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise);
334extern int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise);
335 374
336/* Power down or up the camera; not supported by all models */ 375/* Power down or up the camera; not supported by all models */
337extern int pwc_camera_power(struct pwc_device *pdev, int power); 376extern void pwc_camera_power(struct pwc_device *pdev, int power);
338 377
339/* Private ioctl()s; see pwc-ioctl.h */ 378/* Private ioctl()s; see pwc-ioctl.h */
340extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); 379extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
@@ -343,12 +382,6 @@ extern const struct v4l2_ioctl_ops pwc_ioctl_ops;
343 382
344/** pwc-uncompress.c */ 383/** pwc-uncompress.c */
345/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ 384/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
346extern int pwc_decompress(struct pwc_device *pdev); 385int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf);
347
348#ifdef __cplusplus
349}
350#endif
351
352 386
353#endif 387#endif
354/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */