aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/arv.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c1
-rw-r--r--drivers/media/video/gspca/conex.c4
-rw-r--r--drivers/media/video/gspca/etoms.c137
-rw-r--r--drivers/media/video/gspca/gspca.c12
-rw-r--r--drivers/media/video/gspca/gspca.h5
-rw-r--r--drivers/media/video/gspca/ov519.c476
-rw-r--r--drivers/media/video/gspca/pac7311.c54
-rw-r--r--drivers/media/video/gspca/sonixb.c2
-rw-r--r--drivers/media/video/gspca/sonixj.c287
-rw-r--r--drivers/media/video/gspca/spca505.c12
-rw-r--r--drivers/media/video/gspca/spca506.c12
-rw-r--r--drivers/media/video/gspca/spca508.c18
-rw-r--r--drivers/media/video/gspca/spca561.c42
-rw-r--r--drivers/media/video/gspca/vc032x.c4
-rw-r--r--drivers/media/video/gspca/zc3xx.c6
-rw-r--r--drivers/media/video/pxa_camera.c58
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c2
-rw-r--r--drivers/media/video/soc_camera.c26
-rw-r--r--drivers/media/video/soc_camera_platform.c2
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c33
-rw-r--r--drivers/media/video/uvc/uvc_driver.c26
-rw-r--r--drivers/media/video/uvc/uvc_video.c33
-rw-r--r--drivers/media/video/v4l2-dev.c4
-rw-r--r--drivers/media/video/vino.c1
26 files changed, 674 insertions, 587 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index d4a6e56a7135..ecbfa1b39b70 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -630,7 +630,7 @@ config VIDEO_ZORAN_ZR36060
630 depends on VIDEO_ZORAN 630 depends on VIDEO_ZORAN
631 help 631 help
632 Say Y to support Zoran boards based on 36060 chips. 632 Say Y to support Zoran boards based on 36060 chips.
633 This includes Iomega Bus, Pinnacle DC10, Linux media Labs 33 633 This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33
634 and 33 R10 and AverMedia 6 boards. 634 and 33 R10 and AverMedia 6 boards.
635 635
636config VIDEO_ZORAN_BUZ 636config VIDEO_ZORAN_BUZ
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 56ebfd5ef6fa..9e436ad3d34b 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -29,6 +29,7 @@
29#include <linux/sched.h> 29#include <linux/sched.h>
30#include <linux/videodev.h> 30#include <linux/videodev.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
32#include <media/v4l2-ioctl.h>
32#include <linux/mutex.h> 33#include <linux/mutex.h>
33 34
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
@@ -755,7 +756,6 @@ static const struct file_operations ar_fops = {
755 756
756static struct video_device ar_template = { 757static struct video_device ar_template = {
757 .name = "Colour AR VGA", 758 .name = "Colour AR VGA",
758 .type = VID_TYPE_CAPTURE,
759 .fops = &ar_fops, 759 .fops = &ar_fops,
760 .release = ar_release, 760 .release = ar_release,
761 .minor = -1, 761 .minor = -1,
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 476ae44a62d2..452da70e719f 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1015,6 +1015,7 @@ struct em28xx_board em28xx_boards[] = {
1015 .valid = EM28XX_BOARD_NOT_VALIDATED, 1015 .valid = EM28XX_BOARD_NOT_VALIDATED,
1016 .vchannels = 3, 1016 .vchannels = 3,
1017 .tuner_type = TUNER_XC2028, 1017 .tuner_type = TUNER_XC2028,
1018 .mts_firmware = 1,
1018 .decoder = EM28XX_TVP5150, 1019 .decoder = EM28XX_TVP5150,
1019 .input = { { 1020 .input = { {
1020 .type = EM28XX_VMUX_TELEVISION, 1021 .type = EM28XX_VMUX_TELEVISION,
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 44b0bffeb20e..cd3a3f5829b2 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -123,7 +123,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
123{ 123{
124 struct usb_device *dev = gspca_dev->dev; 124 struct usb_device *dev = gspca_dev->dev;
125 125
126#ifdef CONFIG_VIDEO_ADV_DEBUG 126#ifdef GSPCA_DEBUG
127 if (len > sizeof gspca_dev->usb_buf) { 127 if (len > sizeof gspca_dev->usb_buf) {
128 err("reg_r: buffer overflow"); 128 err("reg_r: buffer overflow");
129 return; 129 return;
@@ -163,7 +163,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
163{ 163{
164 struct usb_device *dev = gspca_dev->dev; 164 struct usb_device *dev = gspca_dev->dev;
165 165
166#ifdef CONFIG_VIDEO_ADV_DEBUG 166#ifdef GSPCA_DEBUG
167 if (len > sizeof gspca_dev->usb_buf) { 167 if (len > sizeof gspca_dev->usb_buf) {
168 err("reg_w: buffer overflow"); 168 err("reg_w: buffer overflow");
169 return; 169 return;
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index c8c2f02fcf00..1dbe92d01e6a 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -233,7 +233,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
233{ 233{
234 struct usb_device *dev = gspca_dev->dev; 234 struct usb_device *dev = gspca_dev->dev;
235 235
236#ifdef CONFIG_VIDEO_ADV_DEBUG 236#ifdef GSPCA_DEBUG
237 if (len > sizeof gspca_dev->usb_buf) { 237 if (len > sizeof gspca_dev->usb_buf) {
238 err("reg_r: buffer overflow"); 238 err("reg_r: buffer overflow");
239 return; 239 return;
@@ -271,7 +271,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
271{ 271{
272 struct usb_device *dev = gspca_dev->dev; 272 struct usb_device *dev = gspca_dev->dev;
273 273
274#ifdef CONFIG_VIDEO_ADV_DEBUG 274#ifdef GSPCA_DEBUG
275 if (len > sizeof gspca_dev->usb_buf) { 275 if (len > sizeof gspca_dev->usb_buf) {
276 err("reg_w: buffer overflow"); 276 err("reg_w: buffer overflow");
277 return; 277 return;
@@ -461,6 +461,52 @@ static void Et_init2(struct gspca_dev *gspca_dev)
461 reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ 461 reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */
462} 462}
463 463
464static void setbrightness(struct gspca_dev *gspca_dev)
465{
466 struct sd *sd = (struct sd *) gspca_dev;
467 int i;
468 __u8 brightness = sd->brightness;
469
470 for (i = 0; i < 4; i++)
471 reg_w_val(gspca_dev, ET_O_RED + i, brightness);
472}
473
474static void getbrightness(struct gspca_dev *gspca_dev)
475{
476 struct sd *sd = (struct sd *) gspca_dev;
477 int i;
478 int brightness = 0;
479
480 for (i = 0; i < 4; i++) {
481 reg_r(gspca_dev, ET_O_RED + i, 1);
482 brightness += gspca_dev->usb_buf[0];
483 }
484 sd->brightness = brightness >> 3;
485}
486
487static void setcontrast(struct gspca_dev *gspca_dev)
488{
489 struct sd *sd = (struct sd *) gspca_dev;
490 __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
491 __u8 contrast = sd->contrast;
492
493 memset(RGBG, contrast, sizeof(RGBG) - 2);
494 reg_w(gspca_dev, ET_G_RED, RGBG, 6);
495}
496
497static void getcontrast(struct gspca_dev *gspca_dev)
498{
499 struct sd *sd = (struct sd *) gspca_dev;
500 int i;
501 int contrast = 0;
502
503 for (i = 0; i < 4; i++) {
504 reg_r(gspca_dev, ET_G_RED + i, 1);
505 contrast += gspca_dev->usb_buf[0];
506 }
507 sd->contrast = contrast >> 2;
508}
509
464static void setcolors(struct gspca_dev *gspca_dev) 510static void setcolors(struct gspca_dev *gspca_dev)
465{ 511{
466 struct sd *sd = (struct sd *) gspca_dev; 512 struct sd *sd = (struct sd *) gspca_dev;
@@ -492,6 +538,16 @@ static void getcolors(struct gspca_dev *gspca_dev)
492 } 538 }
493} 539}
494 540
541static void setautogain(struct gspca_dev *gspca_dev)
542{
543 struct sd *sd = (struct sd *) gspca_dev;
544
545 if (sd->autogain)
546 sd->ag_cnt = AG_CNT_START;
547 else
548 sd->ag_cnt = -1;
549}
550
495static void Et_init1(struct gspca_dev *gspca_dev) 551static void Et_init1(struct gspca_dev *gspca_dev)
496{ 552{
497 __u8 value; 553 __u8 value;
@@ -614,6 +670,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
614 sd->contrast = CONTRAST_DEF; 670 sd->contrast = CONTRAST_DEF;
615 sd->colors = COLOR_DEF; 671 sd->colors = COLOR_DEF;
616 sd->autogain = AUTOGAIN_DEF; 672 sd->autogain = AUTOGAIN_DEF;
673 sd->ag_cnt = -1;
617 return 0; 674 return 0;
618} 675}
619 676
@@ -641,6 +698,8 @@ static void sd_start(struct gspca_dev *gspca_dev)
641 else 698 else
642 Et_init2(gspca_dev); 699 Et_init2(gspca_dev);
643 700
701 setautogain(gspca_dev);
702
644 reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); 703 reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
645 et_video(gspca_dev, 1); /* video on */ 704 et_video(gspca_dev, 1); /* video on */
646} 705}
@@ -658,52 +717,6 @@ static void sd_close(struct gspca_dev *gspca_dev)
658{ 717{
659} 718}
660 719
661static void setbrightness(struct gspca_dev *gspca_dev)
662{
663 struct sd *sd = (struct sd *) gspca_dev;
664 int i;
665 __u8 brightness = sd->brightness;
666
667 for (i = 0; i < 4; i++)
668 reg_w_val(gspca_dev, ET_O_RED + i, brightness);
669}
670
671static void getbrightness(struct gspca_dev *gspca_dev)
672{
673 struct sd *sd = (struct sd *) gspca_dev;
674 int i;
675 int brightness = 0;
676
677 for (i = 0; i < 4; i++) {
678 reg_r(gspca_dev, ET_O_RED + i, 1);
679 brightness += gspca_dev->usb_buf[0];
680 }
681 sd->brightness = brightness >> 3;
682}
683
684static void setcontrast(struct gspca_dev *gspca_dev)
685{
686 struct sd *sd = (struct sd *) gspca_dev;
687 __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
688 __u8 contrast = sd->contrast;
689
690 memset(RGBG, contrast, sizeof(RGBG) - 2);
691 reg_w(gspca_dev, ET_G_RED, RGBG, 6);
692}
693
694static void getcontrast(struct gspca_dev *gspca_dev)
695{
696 struct sd *sd = (struct sd *) gspca_dev;
697 int i;
698 int contrast = 0;
699
700 for (i = 0; i < 4; i++) {
701 reg_r(gspca_dev, ET_G_RED + i, 1);
702 contrast += gspca_dev->usb_buf[0];
703 }
704 sd->contrast = contrast >> 2;
705}
706
707static __u8 Et_getgainG(struct gspca_dev *gspca_dev) 720static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
708{ 721{
709 struct sd *sd = (struct sd *) gspca_dev; 722 struct sd *sd = (struct sd *) gspca_dev;
@@ -733,15 +746,22 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
733#define LIMIT(color) \ 746#define LIMIT(color) \
734 (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) 747 (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color))
735 748
736static void setautogain(struct gspca_dev *gspca_dev) 749static void do_autogain(struct gspca_dev *gspca_dev)
737{ 750{
738 __u8 luma = 0; 751 struct sd *sd = (struct sd *) gspca_dev;
752 __u8 luma;
739 __u8 luma_mean = 128; 753 __u8 luma_mean = 128;
740 __u8 luma_delta = 20; 754 __u8 luma_delta = 20;
741 __u8 spring = 4; 755 __u8 spring = 4;
742 int Gbright = 0; 756 int Gbright;
743 __u8 r, g, b; 757 __u8 r, g, b;
744 758
759 if (sd->ag_cnt < 0)
760 return;
761 if (--sd->ag_cnt >= 0)
762 return;
763 sd->ag_cnt = AG_CNT_START;
764
745 Gbright = Et_getgainG(gspca_dev); 765 Gbright = Et_getgainG(gspca_dev);
746 reg_r(gspca_dev, ET_LUMA_CENTER, 4); 766 reg_r(gspca_dev, ET_LUMA_CENTER, 4);
747 g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; 767 g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1;
@@ -768,7 +788,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
768 __u8 *data, /* isoc packet */ 788 __u8 *data, /* isoc packet */
769 int len) /* iso packet length */ 789 int len) /* iso packet length */
770{ 790{
771 struct sd *sd;
772 int seqframe; 791 int seqframe;
773 792
774 seqframe = data[0] & 0x3f; 793 seqframe = data[0] & 0x3f;
@@ -783,13 +802,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
783 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 802 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
784 data, 0); 803 data, 0);
785 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); 804 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
786 sd = (struct sd *) gspca_dev;
787 if (sd->ag_cnt >= 0) {
788 if (--sd->ag_cnt < 0) {
789 sd->ag_cnt = AG_CNT_START;
790 setautogain(gspca_dev);
791 }
792 }
793 return; 805 return;
794 } 806 }
795 if (len) { 807 if (len) {
@@ -862,10 +874,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
862 struct sd *sd = (struct sd *) gspca_dev; 874 struct sd *sd = (struct sd *) gspca_dev;
863 875
864 sd->autogain = val; 876 sd->autogain = val;
865 if (val) 877 if (gspca_dev->streaming)
866 sd->ag_cnt = AG_CNT_START; 878 setautogain(gspca_dev);
867 else
868 sd->ag_cnt = -1;
869 return 0; 879 return 0;
870} 880}
871 881
@@ -889,6 +899,7 @@ static struct sd_desc sd_desc = {
889 .stop0 = sd_stop0, 899 .stop0 = sd_stop0,
890 .close = sd_close, 900 .close = sd_close,
891 .pkt_scan = sd_pkt_scan, 901 .pkt_scan = sd_pkt_scan,
902 .dq_callback = do_autogain,
892}; 903};
893 904
894/* -- module initialisation -- */ 905/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 3a051c925ff6..15d302b28b79 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -47,7 +47,7 @@ MODULE_LICENSE("GPL");
47 47
48static int video_nr = -1; 48static int video_nr = -1;
49 49
50#ifdef CONFIG_VIDEO_ADV_DEBUG 50#ifdef GSPCA_DEBUG
51int gspca_debug = D_ERR | D_PROBE; 51int gspca_debug = D_ERR | D_PROBE;
52EXPORT_SYMBOL(gspca_debug); 52EXPORT_SYMBOL(gspca_debug);
53 53
@@ -677,7 +677,7 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
677 w = fmt->fmt.pix.width; 677 w = fmt->fmt.pix.width;
678 h = fmt->fmt.pix.height; 678 h = fmt->fmt.pix.height;
679 679
680#ifdef CONFIG_VIDEO_ADV_DEBUG 680#ifdef GSPCA_DEBUG
681 if (gspca_debug & D_CONF) 681 if (gspca_debug & D_CONF)
682 PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); 682 PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h);
683#endif 683#endif
@@ -785,7 +785,7 @@ static int dev_open(struct inode *inode, struct file *file)
785 } 785 }
786 gspca_dev->users++; 786 gspca_dev->users++;
787 file->private_data = gspca_dev; 787 file->private_data = gspca_dev;
788#ifdef CONFIG_VIDEO_ADV_DEBUG 788#ifdef GSPCA_DEBUG
789 /* activate the v4l2 debug */ 789 /* activate the v4l2 debug */
790 if (gspca_debug & D_V4L2) 790 if (gspca_debug & D_V4L2)
791 gspca_dev->vdev.debug |= 3; 791 gspca_dev->vdev.debug |= 3;
@@ -904,7 +904,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
904 if (ctrl->id != ctrls->qctrl.id) 904 if (ctrl->id != ctrls->qctrl.id)
905 continue; 905 continue;
906 if (ctrl->value < ctrls->qctrl.minimum 906 if (ctrl->value < ctrls->qctrl.minimum
907 && ctrl->value > ctrls->qctrl.maximum) 907 || ctrl->value > ctrls->qctrl.maximum)
908 return -ERANGE; 908 return -ERANGE;
909 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); 909 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
910 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 910 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
@@ -1080,7 +1080,7 @@ static int vidioc_streamon(struct file *file, void *priv,
1080 if (ret < 0) 1080 if (ret < 0)
1081 goto out; 1081 goto out;
1082 } 1082 }
1083#ifdef CONFIG_VIDEO_ADV_DEBUG 1083#ifdef GSPCA_DEBUG
1084 if (gspca_debug & D_STREAM) { 1084 if (gspca_debug & D_STREAM) {
1085 PDEBUG_MODE("stream on OK", 1085 PDEBUG_MODE("stream on OK",
1086 gspca_dev->pixfmt, 1086 gspca_dev->pixfmt,
@@ -1913,7 +1913,7 @@ static void __exit gspca_exit(void)
1913module_init(gspca_init); 1913module_init(gspca_init);
1914module_exit(gspca_exit); 1914module_exit(gspca_exit);
1915 1915
1916#ifdef CONFIG_VIDEO_ADV_DEBUG 1916#ifdef GSPCA_DEBUG
1917module_param_named(debug, gspca_debug, int, 0644); 1917module_param_named(debug, gspca_debug, int, 0644);
1918MODULE_PARM_DESC(debug, 1918MODULE_PARM_DESC(debug,
1919 "Debug (bit) 0x01:error 0x02:probe 0x04:config" 1919 "Debug (bit) 0x01:error 0x02:probe 0x04:config"
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 3fd2c4eee204..67e448940eaa 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -9,7 +9,10 @@
9#include <media/v4l2-common.h> 9#include <media/v4l2-common.h>
10#include <linux/mutex.h> 10#include <linux/mutex.h>
11 11
12#ifdef CONFIG_VIDEO_ADV_DEBUG 12/* compilation option */
13#define GSPCA_DEBUG 1
14
15#ifdef GSPCA_DEBUG
13/* GSPCA our debug messages */ 16/* GSPCA our debug messages */
14extern int gspca_debug; 17extern int gspca_debug;
15#define PDEBUG(level, fmt, args...) \ 18#define PDEBUG(level, fmt, args...) \
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 83139efc4629..b4f00ec0885c 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -40,14 +40,15 @@ struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */ 40 struct gspca_dev gspca_dev; /* !! must be the first item */
41 41
42 /* Determined by sensor type */ 42 /* Determined by sensor type */
43 short maxwidth; 43 char sif;
44 short maxheight;
45 44
46 unsigned char primary_i2c_slave; /* I2C write id of sensor */ 45 unsigned char primary_i2c_slave; /* I2C write id of sensor */
47 46
48 unsigned char brightness; 47 unsigned char brightness;
49 unsigned char contrast; 48 unsigned char contrast;
50 unsigned char colors; 49 unsigned char colors;
50 __u8 hflip;
51 __u8 vflip;
51 52
52 char compress; /* Should the next frame be compressed? */ 53 char compress; /* Should the next frame be compressed? */
53 char compress_inited; /* Are compression params uploaded? */ 54 char compress_inited; /* Are compression params uploaded? */
@@ -77,9 +78,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 78static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 79static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 80static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
80 85
81static struct ctrl sd_ctrls[] = { 86static struct ctrl sd_ctrls[] = {
82#define SD_BRIGHTNESS 0
83 { 87 {
84 { 88 {
85 .id = V4L2_CID_BRIGHTNESS, 89 .id = V4L2_CID_BRIGHTNESS,
@@ -88,12 +92,12 @@ static struct ctrl sd_ctrls[] = {
88 .minimum = 0, 92 .minimum = 0,
89 .maximum = 255, 93 .maximum = 255,
90 .step = 1, 94 .step = 1,
91 .default_value = 127, 95#define BRIGHTNESS_DEF 127
96 .default_value = BRIGHTNESS_DEF,
92 }, 97 },
93 .set = sd_setbrightness, 98 .set = sd_setbrightness,
94 .get = sd_getbrightness, 99 .get = sd_getbrightness,
95 }, 100 },
96#define SD_CONTRAST 1
97 { 101 {
98 { 102 {
99 .id = V4L2_CID_CONTRAST, 103 .id = V4L2_CID_CONTRAST,
@@ -102,31 +106,61 @@ static struct ctrl sd_ctrls[] = {
102 .minimum = 0, 106 .minimum = 0,
103 .maximum = 255, 107 .maximum = 255,
104 .step = 1, 108 .step = 1,
105 .default_value = 127, 109#define CONTRAST_DEF 127
110 .default_value = CONTRAST_DEF,
106 }, 111 },
107 .set = sd_setcontrast, 112 .set = sd_setcontrast,
108 .get = sd_getcontrast, 113 .get = sd_getcontrast,
109 }, 114 },
110#define SD_COLOR 2
111 { 115 {
112 { 116 {
113 .id = V4L2_CID_SATURATION, 117 .id = V4L2_CID_SATURATION,
114 .type = V4L2_CTRL_TYPE_INTEGER, 118 .type = V4L2_CTRL_TYPE_INTEGER,
115 .name = "Saturation", 119 .name = "Color",
116 .minimum = 0, 120 .minimum = 0,
117 .maximum = 255, 121 .maximum = 255,
118 .step = 1, 122 .step = 1,
119 .default_value = 127, 123#define COLOR_DEF 127
124 .default_value = COLOR_DEF,
120 }, 125 },
121 .set = sd_setcolors, 126 .set = sd_setcolors,
122 .get = sd_getcolors, 127 .get = sd_getcolors,
123 }, 128 },
129/* next controls work with ov7670 only */
130 {
131 {
132 .id = V4L2_CID_HFLIP,
133 .type = V4L2_CTRL_TYPE_BOOLEAN,
134 .name = "Mirror",
135 .minimum = 0,
136 .maximum = 1,
137 .step = 1,
138#define HFLIP_DEF 0
139 .default_value = HFLIP_DEF,
140 },
141 .set = sd_sethflip,
142 .get = sd_gethflip,
143 },
144 {
145 {
146 .id = V4L2_CID_VFLIP,
147 .type = V4L2_CTRL_TYPE_BOOLEAN,
148 .name = "Vflip",
149 .minimum = 0,
150 .maximum = 1,
151 .step = 1,
152#define VFLIP_DEF 0
153 .default_value = VFLIP_DEF,
154 },
155 .set = sd_setvflip,
156 .get = sd_getvflip,
157 },
124}; 158};
125 159
126static struct v4l2_pix_format vga_mode[] = { 160static struct v4l2_pix_format vga_mode[] = {
127 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 161 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
128 .bytesperline = 320, 162 .bytesperline = 320,
129 .sizeimage = 320 * 240 * 3 / 8 + 589, 163 .sizeimage = 320 * 240 * 3 / 8 + 590,
130 .colorspace = V4L2_COLORSPACE_JPEG, 164 .colorspace = V4L2_COLORSPACE_JPEG,
131 .priv = 1}, 165 .priv = 1},
132 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 166 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -138,12 +172,12 @@ static struct v4l2_pix_format vga_mode[] = {
138static struct v4l2_pix_format sif_mode[] = { 172static struct v4l2_pix_format sif_mode[] = {
139 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 173 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
140 .bytesperline = 176, 174 .bytesperline = 176,
141 .sizeimage = 176 * 144 * 3 / 8 + 589, 175 .sizeimage = 176 * 144 * 3 / 8 + 590,
142 .colorspace = V4L2_COLORSPACE_JPEG, 176 .colorspace = V4L2_COLORSPACE_JPEG,
143 .priv = 1}, 177 .priv = 1},
144 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 178 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
145 .bytesperline = 352, 179 .bytesperline = 352,
146 .sizeimage = 352 * 288 * 3 / 8 + 589, 180 .sizeimage = 352 * 288 * 3 / 8 + 590,
147 .colorspace = V4L2_COLORSPACE_JPEG, 181 .colorspace = V4L2_COLORSPACE_JPEG,
148 .priv = 0}, 182 .priv = 0},
149}; 183};
@@ -225,6 +259,7 @@ static struct v4l2_pix_format sif_mode[] = {
225#define OV7670_REG_VSTART 0x19 /* Vert start high bits */ 259#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
226#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ 260#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
227#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ 261#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
262#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
228#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ 263#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
229#define OV7670_REG_AEW 0x24 /* AGC upper limit */ 264#define OV7670_REG_AEW 0x24 /* AGC upper limit */
230#define OV7670_REG_AEB 0x25 /* AGC lower limit */ 265#define OV7670_REG_AEB 0x25 /* AGC lower limit */
@@ -258,16 +293,6 @@ static struct v4l2_pix_format sif_mode[] = {
258#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ 293#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
259#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ 294#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
260 295
261struct ovsensor_window {
262 short x;
263 short y;
264 short width;
265 short height;
266/* int format; */
267 short quarter; /* Scale width and height down 2x */
268 short clockdiv; /* Clock divisor setting */
269};
270
271static unsigned char ov7670_abs_to_sm(unsigned char v) 296static unsigned char ov7670_abs_to_sm(unsigned char v)
272{ 297{
273 if (v > 127) 298 if (v > 127)
@@ -499,19 +524,6 @@ static int init_ov_sensor(struct sd *sd)
499 return 0; 524 return 0;
500} 525}
501 526
502/* Switch on standard JPEG compression. Returns 0 for success. */
503static int ov519_init_compression(struct sd *sd)
504{
505 if (!sd->compress_inited) {
506 if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) {
507 PDEBUG(D_ERR, "Error switching to compressed mode");
508 return -EIO;
509 }
510 sd->compress_inited = 1;
511 }
512 return 0;
513}
514
515/* Set the read and write slave IDs. The "slave" argument is the write slave, 527/* Set the read and write slave IDs. The "slave" argument is the write slave,
516 * and the read slave will be set to (slave + 1). 528 * and the read slave will be set to (slave + 1).
517 * This should not be called from outside the i2c I/O functions. 529 * This should not be called from outside the i2c I/O functions.
@@ -681,21 +693,17 @@ static int ov8xx0_configure(struct sd *sd)
681 return -1; 693 return -1;
682 } 694 }
683 if ((rc & 3) == 1) { 695 if ((rc & 3) == 1) {
684 PDEBUG(D_PROBE, "Sensor is an OV8610");
685 sd->sensor = SEN_OV8610; 696 sd->sensor = SEN_OV8610;
686 } else { 697 } else {
687 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); 698 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
688 return -1; 699 return -1;
689 } 700 }
690 PDEBUG(D_PROBE, "Writing 8610 registers"); 701 PDEBUG(D_PROBE, "Writing 8610 registers");
691 if (write_i2c_regvals(sd, 702 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
692 norm_8610,
693 sizeof norm_8610 / sizeof norm_8610[0]))
694 return -1; 703 return -1;
695 704
696 /* Set sensor-specific vars */ 705 /* Set sensor-specific vars */
697 sd->maxwidth = 640; 706/* sd->sif = 0; already done */
698 sd->maxheight = 480;
699 return 0; 707 return 0;
700} 708}
701 709
@@ -825,7 +833,7 @@ static int ov7xx0_configure(struct sd *sd)
825 { OV7670_REG_COM7, OV7670_COM7_RESET }, 833 { OV7670_REG_COM7, OV7670_COM7_RESET },
826 { OV7670_REG_TSLB, 0x04 }, /* OV */ 834 { OV7670_REG_TSLB, 0x04 }, /* OV */
827 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ 835 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
828 { OV7670_REG_CLKRC, 0x1 }, 836 { OV7670_REG_CLKRC, 0x01 },
829 /* 837 /*
830 * Set the hardware window. These values from OV don't entirely 838 * Set the hardware window. These values from OV don't entirely
831 * make sense - hstop is less than hstart. But they work... 839 * make sense - hstop is less than hstart. But they work...
@@ -839,16 +847,12 @@ static int ov7xx0_configure(struct sd *sd)
839 { 0x70, 0x3a }, { 0x71, 0x35 }, 847 { 0x70, 0x3a }, { 0x71, 0x35 },
840 { 0x72, 0x11 }, { 0x73, 0xf0 }, 848 { 0x72, 0x11 }, { 0x73, 0xf0 },
841 { 0xa2, 0x02 }, 849 { 0xa2, 0x02 },
842/* jfm */ 850/* { OV7670_REG_COM10, 0x0 }, */
843/* { OV7670_REG_COM10, 0x0 }, */
844 851
845 /* Gamma curve values */ 852 /* Gamma curve values */
846 { 0x7a, 0x20 }, 853 { 0x7a, 0x20 },
847/* jfm:win 7b=1c */
848 { 0x7b, 0x10 }, 854 { 0x7b, 0x10 },
849/* jfm:win 7c=28 */
850 { 0x7c, 0x1e }, 855 { 0x7c, 0x1e },
851/* jfm:win 7d=3c */
852 { 0x7d, 0x35 }, 856 { 0x7d, 0x35 },
853 { 0x7e, 0x5a }, { 0x7f, 0x69 }, 857 { 0x7e, 0x5a }, { 0x7f, 0x69 },
854 { 0x80, 0x76 }, { 0x81, 0x80 }, 858 { 0x80, 0x76 }, { 0x81, 0x80 },
@@ -864,13 +868,11 @@ static int ov7xx0_configure(struct sd *sd)
864 | OV7670_COM8_BFILT }, 868 | OV7670_COM8_BFILT },
865 { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, 869 { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 },
866 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ 870 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
867/* jfm:win 14=38 */
868 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ 871 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
869 { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, 872 { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 },
870 { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, 873 { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 },
871 { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, 874 { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 },
872 { OV7670_REG_HAECC2, 0x68 }, 875 { OV7670_REG_HAECC2, 0x68 },
873/* jfm:win a1=0b */
874 { 0xa1, 0x03 }, /* magic */ 876 { 0xa1, 0x03 }, /* magic */
875 { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, 877 { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 },
876 { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, 878 { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 },
@@ -884,8 +886,6 @@ static int ov7xx0_configure(struct sd *sd)
884 /* Almost all of these are magic "reserved" values. */ 886 /* Almost all of these are magic "reserved" values. */
885 { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, 887 { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b },
886 { 0x16, 0x02 }, 888 { 0x16, 0x02 },
887/* jfm */
888/* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */
889 { OV7670_REG_MVFP, 0x07 }, 889 { OV7670_REG_MVFP, 0x07 },
890 { 0x21, 0x02 }, { 0x22, 0x91 }, 890 { 0x21, 0x02 }, { 0x22, 0x91 },
891 { 0x29, 0x07 }, { 0x33, 0x0b }, 891 { 0x29, 0x07 }, { 0x33, 0x0b },
@@ -930,7 +930,10 @@ static int ov7xx0_configure(struct sd *sd)
930 { OV7670_REG_EDGE, 0 }, 930 { OV7670_REG_EDGE, 0 },
931 { 0x75, 0x05 }, { 0x76, 0xe1 }, 931 { 0x75, 0x05 }, { 0x76, 0xe1 },
932 { 0x4c, 0 }, { 0x77, 0x01 }, 932 { 0x4c, 0 }, { 0x77, 0x01 },
933 { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, 933 { OV7670_REG_COM13, OV7670_COM13_GAMMA
934 | OV7670_COM13_UVSAT
935 | 2}, /* was 3 */
936 { 0x4b, 0x09 },
934 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, 937 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 },
935 { 0x56, 0x40 }, 938 { 0x56, 0x40 },
936 939
@@ -956,30 +959,10 @@ static int ov7xx0_configure(struct sd *sd)
956 { 0x79, 0x03 }, { 0xc8, 0x40 }, 959 { 0x79, 0x03 }, { 0xc8, 0x40 },
957 { 0x79, 0x05 }, { 0xc8, 0x30 }, 960 { 0x79, 0x05 }, { 0xc8, 0x30 },
958 { 0x79, 0x26 }, 961 { 0x79, 0x26 },
959 962 };
960 /* Format YUV422 */
961 { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */
962 { OV7670_REG_RGB444, 0 }, /* No RGB444 please */
963 { OV7670_REG_COM1, 0 },
964 { OV7670_REG_COM15, OV7670_COM15_R00FF },
965 { OV7670_REG_COM9, 0x18 },
966 /* 4x gain ceiling; 0x8 is reserved bit */
967 { 0x4f, 0x80 }, /* "matrix coefficient 1" */
968 { 0x50, 0x80 }, /* "matrix coefficient 2" */
969 { 0x52, 0x22 }, /* "matrix coefficient 4" */
970 { 0x53, 0x5e }, /* "matrix coefficient 5" */
971 { 0x54, 0x80 }, /* "matrix coefficient 6" */
972 { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT },
973};
974 963
975 PDEBUG(D_PROBE, "starting OV7xx0 configuration"); 964 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
976 965
977/* jfm:already done? */
978 if (init_ov_sensor(sd) < 0)
979 PDEBUG(D_ERR, "Failed to read sensor ID");
980 else
981 PDEBUG(D_PROBE, "OV7xx0 initialized");
982
983 /* Detect sensor (sub)type */ 966 /* Detect sensor (sub)type */
984 rc = i2c_r(sd, OV7610_REG_COM_I); 967 rc = i2c_r(sd, OV7610_REG_COM_I);
985 968
@@ -1025,20 +1008,25 @@ static int ov7xx0_configure(struct sd *sd)
1025 return low; 1008 return low;
1026 } 1009 }
1027 if (high == 0x76) { 1010 if (high == 0x76) {
1028 if (low == 0x30) { 1011 switch (low) {
1012 case 0x30:
1029 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); 1013 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
1030 sd->sensor = SEN_OV7630; 1014 sd->sensor = SEN_OV7630;
1031 } else if (low == 0x40) { 1015 break;
1016 case 0x40:
1032 PDEBUG(D_PROBE, "Sensor is an OV7645"); 1017 PDEBUG(D_PROBE, "Sensor is an OV7645");
1033 sd->sensor = SEN_OV7640; /* FIXME */ 1018 sd->sensor = SEN_OV7640; /* FIXME */
1034 } else if (low == 0x45) { 1019 break;
1020 case 0x45:
1035 PDEBUG(D_PROBE, "Sensor is an OV7645B"); 1021 PDEBUG(D_PROBE, "Sensor is an OV7645B");
1036 sd->sensor = SEN_OV7640; /* FIXME */ 1022 sd->sensor = SEN_OV7640; /* FIXME */
1037 } else if (low == 0x48) { 1023 break;
1024 case 0x48:
1038 PDEBUG(D_PROBE, "Sensor is an OV7648"); 1025 PDEBUG(D_PROBE, "Sensor is an OV7648");
1039 sd->sensor = SEN_OV7640; /* FIXME */ 1026 sd->sensor = SEN_OV7640; /* FIXME */
1040 } else { 1027 break;
1041 PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); 1028 default:
1029 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
1042 return -1; 1030 return -1;
1043 } 1031 }
1044 } else { 1032 } else {
@@ -1050,34 +1038,34 @@ static int ov7xx0_configure(struct sd *sd)
1050 return -1; 1038 return -1;
1051 } 1039 }
1052 1040
1053 if (sd->sensor == SEN_OV7620) { 1041 switch (sd->sensor) {
1042 case SEN_OV7620:
1054 PDEBUG(D_PROBE, "Writing 7620 registers"); 1043 PDEBUG(D_PROBE, "Writing 7620 registers");
1055 if (write_i2c_regvals(sd, norm_7620, 1044 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
1056 sizeof norm_7620 / sizeof norm_7620[0]))
1057 return -1; 1045 return -1;
1058 } else if (sd->sensor == SEN_OV7630) { 1046 break;
1047 case SEN_OV7630:
1059 PDEBUG(D_ERR, "7630 is not supported by this driver version"); 1048 PDEBUG(D_ERR, "7630 is not supported by this driver version");
1060 return -1; 1049 return -1;
1061 } else if (sd->sensor == SEN_OV7640) { 1050 case SEN_OV7640:
1062 PDEBUG(D_PROBE, "Writing 7640 registers"); 1051 PDEBUG(D_PROBE, "Writing 7640 registers");
1063 if (write_i2c_regvals(sd, norm_7640, 1052 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
1064 sizeof norm_7640 / sizeof norm_7640[0]))
1065 return -1; 1053 return -1;
1066 } else if (sd->sensor == SEN_OV7670) { 1054 break;
1055 case SEN_OV7670:
1067 PDEBUG(D_PROBE, "Writing 7670 registers"); 1056 PDEBUG(D_PROBE, "Writing 7670 registers");
1068 if (write_i2c_regvals(sd, norm_7670, 1057 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
1069 sizeof norm_7670 / sizeof norm_7670[0]))
1070 return -1; 1058 return -1;
1071 } else { 1059 break;
1060 default:
1072 PDEBUG(D_PROBE, "Writing 7610 registers"); 1061 PDEBUG(D_PROBE, "Writing 7610 registers");
1073 if (write_i2c_regvals(sd, norm_7610, 1062 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
1074 sizeof norm_7610 / sizeof norm_7610[0]))
1075 return -1; 1063 return -1;
1064 break;
1076 } 1065 }
1077 1066
1078 /* Set sensor-specific vars */ 1067 /* Set sensor-specific vars */
1079 sd->maxwidth = 640; 1068/* sd->sif = 0; already done */
1080 sd->maxheight = 480;
1081 return 0; 1069 return 0;
1082} 1070}
1083 1071
@@ -1231,43 +1219,45 @@ static int ov6xx0_configure(struct sd *sd)
1231 /* Ugh. The first two bits are the version bits, but 1219 /* Ugh. The first two bits are the version bits, but
1232 * the entire register value must be used. I guess OVT 1220 * the entire register value must be used. I guess OVT
1233 * underestimated how many variants they would make. */ 1221 * underestimated how many variants they would make. */
1234 if (rc == 0x00) { 1222 switch (rc) {
1223 case 0x00:
1235 sd->sensor = SEN_OV6630; 1224 sd->sensor = SEN_OV6630;
1236 PDEBUG(D_ERR, 1225 PDEBUG(D_ERR,
1237 "WARNING: Sensor is an OV66308. Your camera may have"); 1226 "WARNING: Sensor is an OV66308. Your camera may have");
1238 PDEBUG(D_ERR, "been misdetected in previous driver versions."); 1227 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
1239 } else if (rc == 0x01) { 1228 break;
1229 case 0x01:
1240 sd->sensor = SEN_OV6620; 1230 sd->sensor = SEN_OV6620;
1241 PDEBUG(D_PROBE, "Sensor is an OV6620"); 1231 break;
1242 } else if (rc == 0x02) { 1232 case 0x02:
1243 sd->sensor = SEN_OV6630; 1233 sd->sensor = SEN_OV6630;
1244 PDEBUG(D_PROBE, "Sensor is an OV66308AE"); 1234 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
1245 } else if (rc == 0x03) { 1235 break;
1236 case 0x03:
1246 sd->sensor = SEN_OV6630; 1237 sd->sensor = SEN_OV6630;
1247 PDEBUG(D_PROBE, "Sensor is an OV66308AF"); 1238 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
1248 } else if (rc == 0x90) { 1239 break;
1240 case 0x90:
1249 sd->sensor = SEN_OV6630; 1241 sd->sensor = SEN_OV6630;
1250 PDEBUG(D_ERR, 1242 PDEBUG(D_ERR,
1251 "WARNING: Sensor is an OV66307. Your camera may have"); 1243 "WARNING: Sensor is an OV66307. Your camera may have");
1252 PDEBUG(D_ERR, "been misdetected in previous driver versions."); 1244 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
1253 } else { 1245 break;
1246 default:
1254 PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); 1247 PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc);
1255 return -1; 1248 return -1;
1256 } 1249 }
1257 1250
1258 /* Set sensor-specific vars */ 1251 /* Set sensor-specific vars */
1259 sd->maxwidth = 352; 1252 sd->sif = 1;
1260 sd->maxheight = 288;
1261 1253
1262 if (sd->sensor == SEN_OV6620) { 1254 if (sd->sensor == SEN_OV6620) {
1263 PDEBUG(D_PROBE, "Writing 6x20 registers"); 1255 PDEBUG(D_PROBE, "Writing 6x20 registers");
1264 if (write_i2c_regvals(sd, norm_6x20, 1256 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
1265 sizeof norm_6x20 / sizeof norm_6x20[0]))
1266 return -1; 1257 return -1;
1267 } else { 1258 } else {
1268 PDEBUG(D_PROBE, "Writing 6x30 registers"); 1259 PDEBUG(D_PROBE, "Writing 6x30 registers");
1269 if (write_i2c_regvals(sd, norm_6x30, 1260 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
1270 sizeof norm_6x30 / sizeof norm_6x30[0]))
1271 return -1; 1261 return -1;
1272 } 1262 }
1273 return 0; 1263 return 0;
@@ -1276,14 +1266,8 @@ static int ov6xx0_configure(struct sd *sd)
1276/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ 1266/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
1277static void ov51x_led_control(struct sd *sd, int on) 1267static void ov51x_led_control(struct sd *sd, int on)
1278{ 1268{
1279 PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); 1269/* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */
1280 1270 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1281/* if (sd->bridge == BRG_OV511PLUS) */
1282/* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */
1283/* else if (sd->bridge == BRG_OV519) */
1284 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1285/* else if (sd->bclass == BCL_OV518) */
1286/* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */
1287} 1271}
1288 1272
1289/* this function is called at probe time */ 1273/* this function is called at probe time */
@@ -1293,11 +1277,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1293 struct sd *sd = (struct sd *) gspca_dev; 1277 struct sd *sd = (struct sd *) gspca_dev;
1294 struct cam *cam; 1278 struct cam *cam;
1295 1279
1296/* (from ov519_configure) */
1297 static const struct ov_regvals init_519[] = { 1280 static const struct ov_regvals init_519[] = {
1298 { 0x5a, 0x6d }, /* EnableSystem */ 1281 { 0x5a, 0x6d }, /* EnableSystem */
1299/* jfm trace usbsnoop3-1.txt */
1300/* jfm 53 = fb */
1301 { 0x53, 0x9b }, 1282 { 0x53, 0x9b },
1302 { 0x54, 0xff }, /* set bit2 to enable jpeg */ 1283 { 0x54, 0xff }, /* set bit2 to enable jpeg */
1303 { 0x5d, 0x03 }, 1284 { 0x5d, 0x03 },
@@ -1314,9 +1295,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1314 1295
1315 if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) 1296 if (write_regvals(sd, init_519, ARRAY_SIZE(init_519)))
1316 goto error; 1297 goto error;
1317/* jfm: not seen in windows trace */
1318 if (ov519_init_compression(sd))
1319 goto error;
1320 ov51x_led_control(sd, 0); /* turn LED off */ 1298 ov51x_led_control(sd, 0); /* turn LED off */
1321 1299
1322 /* Test for 76xx */ 1300 /* Test for 76xx */
@@ -1365,16 +1343,18 @@ static int sd_config(struct gspca_dev *gspca_dev,
1365 1343
1366 cam = &gspca_dev->cam; 1344 cam = &gspca_dev->cam;
1367 cam->epaddr = OV511_ENDPOINT_ADDRESS; 1345 cam->epaddr = OV511_ENDPOINT_ADDRESS;
1368 if (sd->maxwidth == 640) { 1346 if (!sd->sif) {
1369 cam->cam_mode = vga_mode; 1347 cam->cam_mode = vga_mode;
1370 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 1348 cam->nmodes = ARRAY_SIZE(vga_mode);
1371 } else { 1349 } else {
1372 cam->cam_mode = sif_mode; 1350 cam->cam_mode = sif_mode;
1373 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; 1351 cam->nmodes = ARRAY_SIZE(sif_mode);
1374 } 1352 }
1375 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 1353 sd->brightness = BRIGHTNESS_DEF;
1376 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 1354 sd->contrast = CONTRAST_DEF;
1377 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; 1355 sd->colors = COLOR_DEF;
1356 sd->hflip = HFLIP_DEF;
1357 sd->vflip = VFLIP_DEF;
1378 return 0; 1358 return 0;
1379error: 1359error:
1380 PDEBUG(D_ERR, "OV519 Config failed"); 1360 PDEBUG(D_ERR, "OV519 Config failed");
@@ -1394,8 +1374,7 @@ static int sd_open(struct gspca_dev *gspca_dev)
1394 * 1374 *
1395 * Do not put any sensor-specific code in here (including I2C I/O functions) 1375 * Do not put any sensor-specific code in here (including I2C I/O functions)
1396 */ 1376 */
1397static int ov519_mode_init_regs(struct sd *sd, 1377static int ov519_mode_init_regs(struct sd *sd)
1398 int width, int height)
1399{ 1378{
1400 static const struct ov_regvals mode_init_519_ov7670[] = { 1379 static const struct ov_regvals mode_init_519_ov7670[] = {
1401 { 0x5d, 0x03 }, /* Turn off suspend mode */ 1380 { 0x5d, 0x03 }, /* Turn off suspend mode */
@@ -1441,36 +1420,23 @@ static int ov519_mode_init_regs(struct sd *sd,
1441 /* windows reads 0x55 at this point, why? */ 1420 /* windows reads 0x55 at this point, why? */
1442 }; 1421 };
1443 1422
1444/* int hi_res; */
1445
1446 PDEBUG(D_CONF, "mode init %dx%d", width, height);
1447
1448/* if (width >= 800 && height >= 600)
1449 hi_res = 1;
1450 else
1451 hi_res = 0; */
1452
1453/* if (ov51x_stop(sd) < 0)
1454 return -EIO; */
1455
1456 /******** Set the mode ********/ 1423 /******** Set the mode ********/
1457 if (sd->sensor != SEN_OV7670) { 1424 if (sd->sensor != SEN_OV7670) {
1458 if (write_regvals(sd, mode_init_519, 1425 if (write_regvals(sd, mode_init_519,
1459 ARRAY_SIZE(mode_init_519))) 1426 ARRAY_SIZE(mode_init_519)))
1460 return -EIO; 1427 return -EIO;
1428 if (sd->sensor == SEN_OV7640) {
1429 /* Select 8-bit input mode */
1430 reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10);
1431 }
1461 } else { 1432 } else {
1462 if (write_regvals(sd, mode_init_519_ov7670, 1433 if (write_regvals(sd, mode_init_519_ov7670,
1463 ARRAY_SIZE(mode_init_519_ov7670))) 1434 ARRAY_SIZE(mode_init_519_ov7670)))
1464 return -EIO; 1435 return -EIO;
1465 } 1436 }
1466 1437
1467 if (sd->sensor == SEN_OV7640) { 1438 reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4);
1468 /* Select 8-bit input mode */ 1439 reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3);
1469 reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10);
1470 }
1471
1472 reg_w(sd, OV519_CAM_H_SIZE, width >> 4);
1473 reg_w(sd, OV519_CAM_V_SIZE, height >> 3);
1474 reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); 1440 reg_w(sd, OV519_CAM_X_OFFSETL, 0x00);
1475 reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); 1441 reg_w(sd, OV519_CAM_X_OFFSETH, 0x00);
1476 reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); 1442 reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00);
@@ -1485,9 +1451,10 @@ static int ov519_mode_init_regs(struct sd *sd,
1485 1451
1486/* FIXME: These are only valid at the max resolution. */ 1452/* FIXME: These are only valid at the max resolution. */
1487 sd->clockdiv = 0; 1453 sd->clockdiv = 0;
1488 if (sd->sensor == SEN_OV7640) { 1454 switch (sd->sensor) {
1455 case SEN_OV7640:
1489 switch (sd->frame_rate) { 1456 switch (sd->frame_rate) {
1490/*jfm: default was 30 fps */ 1457/*fixme: default was 30 fps */
1491 case 30: 1458 case 30:
1492 reg_w(sd, 0xa4, 0x0c); 1459 reg_w(sd, 0xa4, 0x0c);
1493 reg_w(sd, 0x23, 0xff); 1460 reg_w(sd, 0x23, 0xff);
@@ -1517,7 +1484,8 @@ static int ov519_mode_init_regs(struct sd *sd,
1517 sd->clockdiv = 1; 1484 sd->clockdiv = 1;
1518 break; 1485 break;
1519 } 1486 }
1520 } else if (sd->sensor == SEN_OV8610) { 1487 break;
1488 case SEN_OV8610:
1521 switch (sd->frame_rate) { 1489 switch (sd->frame_rate) {
1522 default: /* 15 fps */ 1490 default: /* 15 fps */
1523/* case 15: */ 1491/* case 15: */
@@ -1533,41 +1501,37 @@ static int ov519_mode_init_regs(struct sd *sd,
1533 reg_w(sd, 0x23, 0x1b); 1501 reg_w(sd, 0x23, 0x1b);
1534 break; 1502 break;
1535 } 1503 }
1536 sd->clockdiv = 0; 1504 break;
1537 } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ 1505 case SEN_OV7670: /* guesses, based on 7640 */
1538 PDEBUG(D_STREAM, "Setting framerate to %d fps", 1506 PDEBUG(D_STREAM, "Setting framerate to %d fps",
1539 (sd->frame_rate == 0) ? 15 : sd->frame_rate); 1507 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
1508 reg_w(sd, 0xa4, 0x10);
1540 switch (sd->frame_rate) { 1509 switch (sd->frame_rate) {
1541 case 30: 1510 case 30:
1542 reg_w(sd, 0xa4, 0x10);
1543 reg_w(sd, 0x23, 0xff); 1511 reg_w(sd, 0x23, 0xff);
1544 break; 1512 break;
1545 case 20: 1513 case 20:
1546 reg_w(sd, 0xa4, 0x10);
1547 reg_w(sd, 0x23, 0x1b); 1514 reg_w(sd, 0x23, 0x1b);
1548 break; 1515 break;
1549 default: /* 15 fps */ 1516 default:
1550/* case 15: */ 1517/* case 15: */
1551 reg_w(sd, 0xa4, 0x10);
1552 reg_w(sd, 0x23, 0xff); 1518 reg_w(sd, 0x23, 0xff);
1553 sd->clockdiv = 1; 1519 sd->clockdiv = 1;
1554 break; 1520 break;
1555 } 1521 }
1522 break;
1556 } 1523 }
1557 1524
1558/* if (ov51x_restart(sd) < 0)
1559 return -EIO; */
1560
1561 /* Reset it just for good measure */
1562/* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0)
1563 return -EIO; */
1564 return 0; 1525 return 0;
1565} 1526}
1566 1527
1567static int mode_init_ov_sensor_regs(struct sd *sd, 1528static int mode_init_ov_sensor_regs(struct sd *sd)
1568 struct ovsensor_window *win)
1569{ 1529{
1570 int qvga = win->quarter; 1530 struct gspca_dev *gspca_dev;
1531 int qvga;
1532
1533 gspca_dev = &sd->gspca_dev;
1534 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1571 1535
1572 /******** Mode (VGA/QVGA) and sensor specific regs ********/ 1536 /******** Mode (VGA/QVGA) and sensor specific regs ********/
1573 switch (sd->sensor) { 1537 switch (sd->sensor) {
@@ -1611,8 +1575,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1611 OV7670_COM7_FMT_MASK); 1575 OV7670_COM7_FMT_MASK);
1612 break; 1576 break;
1613 case SEN_OV6620: 1577 case SEN_OV6620:
1614 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
1615 break;
1616 case SEN_OV6630: 1578 case SEN_OV6630:
1617 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 1579 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
1618 break; 1580 break;
@@ -1621,24 +1583,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1621 } 1583 }
1622 1584
1623 /******** Palette-specific regs ********/ 1585 /******** Palette-specific regs ********/
1624/* Need to do work here for the OV7670 */ 1586 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
1625 1587 /* not valid on the OV6620/OV7620/6630? */
1626 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { 1588 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
1627 /* not valid on the OV6620/OV7620/6630? */ 1589 }
1628 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
1629 }
1630 1590
1631 /* The OV518 needs special treatment. Although both the OV518 1591 /* The OV518 needs special treatment. Although both the OV518
1632 * and the OV6630 support a 16-bit video bus, only the 8 bit Y 1592 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
1633 * bus is actually used. The UV bus is tied to ground. 1593 * bus is actually used. The UV bus is tied to ground.
1634 * Therefore, the OV6630 needs to be in 8-bit multiplexed 1594 * Therefore, the OV6630 needs to be in 8-bit multiplexed
1635 * output mode */ 1595 * output mode */
1636 1596
1637 /* OV7640 is 8-bit only */ 1597 /* OV7640 is 8-bit only */
1638 1598
1639 if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) 1599 if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640)
1640 i2c_w_mask(sd, 0x13, 0x00, 0x20); 1600 i2c_w_mask(sd, 0x13, 0x00, 0x20);
1641/* } */
1642 1601
1643 /******** Clock programming ********/ 1602 /******** Clock programming ********/
1644 /* The OV6620 needs special handling. This prevents the 1603 /* The OV6620 needs special handling. This prevents the
@@ -1647,14 +1606,14 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1647 1606
1648 /* Clock down */ 1607 /* Clock down */
1649 i2c_w(sd, 0x2a, 0x04); 1608 i2c_w(sd, 0x2a, 0x04);
1650 i2c_w(sd, 0x11, win->clockdiv); 1609 i2c_w(sd, 0x11, sd->clockdiv);
1651 i2c_w(sd, 0x2a, 0x84); 1610 i2c_w(sd, 0x2a, 0x84);
1652 /* This next setting is critical. It seems to improve 1611 /* This next setting is critical. It seems to improve
1653 * the gain or the contrast. The "reserved" bits seem 1612 * the gain or the contrast. The "reserved" bits seem
1654 * to have some effect in this case. */ 1613 * to have some effect in this case. */
1655 i2c_w(sd, 0x2d, 0x85); 1614 i2c_w(sd, 0x2d, 0x85);
1656 } else if (win->clockdiv >= 0) { 1615 } else if (sd->clockdiv >= 0) {
1657 i2c_w(sd, 0x11, win->clockdiv); 1616 i2c_w(sd, 0x11, sd->clockdiv);
1658 } 1617 }
1659 1618
1660 /******** Special Features ********/ 1619 /******** Special Features ********/
@@ -1674,7 +1633,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1674 /* is fully tested. */ 1633 /* is fully tested. */
1675 /* 7620/6620/6630? don't have register 0x35, so play it safe */ 1634 /* 7620/6620/6630? don't have register 0x35, so play it safe */
1676 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { 1635 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
1677 if (win->width == 640 /*&& win->height == 480*/) 1636 if (!qvga)
1678 i2c_w(sd, 0x35, 0x9e); 1637 i2c_w(sd, 0x35, 0x9e);
1679 else 1638 else
1680 i2c_w(sd, 0x35, 0x1e); 1639 i2c_w(sd, 0x35, 0x1e);
@@ -1682,13 +1641,31 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1682 return 0; 1641 return 0;
1683} 1642}
1684 1643
1685static int set_ov_sensor_window(struct sd *sd, 1644static void sethvflip(struct sd *sd)
1686 struct ovsensor_window *win)
1687{ 1645{
1646 if (sd->sensor != SEN_OV7670)
1647 return;
1648 if (sd->gspca_dev.streaming)
1649 ov51x_stop(sd);
1650 i2c_w_mask(sd, OV7670_REG_MVFP,
1651 OV7670_MVFP_MIRROR * sd->hflip
1652 | OV7670_MVFP_VFLIP * sd->vflip,
1653 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
1654 if (sd->gspca_dev.streaming)
1655 ov51x_restart(sd);
1656}
1657
1658static int set_ov_sensor_window(struct sd *sd)
1659{
1660 struct gspca_dev *gspca_dev;
1661 int qvga;
1688 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; 1662 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
1689 int ret, hstart, hstop, vstop, vstart; 1663 int ret, hstart, hstop, vstop, vstart;
1690 __u8 v; 1664 __u8 v;
1691 1665
1666 gspca_dev = &sd->gspca_dev;
1667 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1668
1692 /* The different sensor ICs handle setting up of window differently. 1669 /* The different sensor ICs handle setting up of window differently.
1693 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ 1670 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
1694 switch (sd->sensor) { 1671 switch (sd->sensor) {
@@ -1733,7 +1710,7 @@ static int set_ov_sensor_window(struct sd *sd,
1733 switch (sd->sensor) { 1710 switch (sd->sensor) {
1734 case SEN_OV6620: 1711 case SEN_OV6620:
1735 case SEN_OV6630: 1712 case SEN_OV6630:
1736 if (win->quarter) { /* QCIF */ 1713 if (qvga) { /* QCIF */
1737 hwscale = 0; 1714 hwscale = 0;
1738 vwscale = 0; 1715 vwscale = 0;
1739 } else { /* CIF */ 1716 } else { /* CIF */
@@ -1743,7 +1720,7 @@ static int set_ov_sensor_window(struct sd *sd,
1743 } 1720 }
1744 break; 1721 break;
1745 case SEN_OV8610: 1722 case SEN_OV8610:
1746 if (win->quarter) { /* QSVGA */ 1723 if (qvga) { /* QSVGA */
1747 hwscale = 1; 1724 hwscale = 1;
1748 vwscale = 1; 1725 vwscale = 1;
1749 } else { /* SVGA */ 1726 } else { /* SVGA */
@@ -1752,7 +1729,7 @@ static int set_ov_sensor_window(struct sd *sd,
1752 } 1729 }
1753 break; 1730 break;
1754 default: /* SEN_OV7xx0 */ 1731 default: /* SEN_OV7xx0 */
1755 if (win->quarter) { /* QVGA */ 1732 if (qvga) { /* QVGA */
1756 hwscale = 1; 1733 hwscale = 1;
1757 vwscale = 0; 1734 vwscale = 0;
1758 } else { /* VGA */ 1735 } else { /* VGA */
@@ -1761,7 +1738,7 @@ static int set_ov_sensor_window(struct sd *sd,
1761 } 1738 }
1762 } 1739 }
1763 1740
1764 ret = mode_init_ov_sensor_regs(sd, win); 1741 ret = mode_init_ov_sensor_regs(sd);
1765 if (ret < 0) 1742 if (ret < 0)
1766 return ret; 1743 return ret;
1767 1744
@@ -1782,7 +1759,7 @@ static int set_ov_sensor_window(struct sd *sd,
1782 /* I can hard code this for OV7670s */ 1759 /* I can hard code this for OV7670s */
1783 /* Yes, these numbers do look odd, but they're tested and work! */ 1760 /* Yes, these numbers do look odd, but they're tested and work! */
1784 if (sd->sensor == SEN_OV7670) { 1761 if (sd->sensor == SEN_OV7670) {
1785 if (win->quarter) { /* QVGA from ov7670.c by 1762 if (qvga) { /* QVGA from ov7670.c by
1786 * Jonathan Corbet */ 1763 * Jonathan Corbet */
1787 hstart = 164; 1764 hstart = 164;
1788 hstop = 20; 1765 hstop = 20;
@@ -1796,75 +1773,45 @@ static int set_ov_sensor_window(struct sd *sd,
1796 } 1773 }
1797 /* OV7670 hardware window registers are split across 1774 /* OV7670 hardware window registers are split across
1798 * multiple locations */ 1775 * multiple locations */
1799 i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); 1776 i2c_w(sd, OV7670_REG_HSTART, hstart >> 3);
1800 i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); 1777 i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3);
1801 v = i2c_r(sd, OV7670_REG_HREF); 1778 v = i2c_r(sd, OV7670_REG_HREF);
1802 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); 1779 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
1803 msleep(10); /* need to sleep between read and write to 1780 msleep(10); /* need to sleep between read and write to
1804 * same reg! */ 1781 * same reg! */
1805 i2c_w(sd, OV7670_REG_HREF, v); 1782 i2c_w(sd, OV7670_REG_HREF, v);
1806 1783
1807 i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); 1784 i2c_w(sd, OV7670_REG_VSTART, vstart >> 2);
1808 i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); 1785 i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2);
1809 v = i2c_r(sd, OV7670_REG_VREF); 1786 v = i2c_r(sd, OV7670_REG_VREF);
1810 v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); 1787 v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
1811 msleep(10); /* need to sleep between read and write to 1788 msleep(10); /* need to sleep between read and write to
1812 * same reg! */ 1789 * same reg! */
1813 i2c_w(sd, OV7670_REG_VREF, v); 1790 i2c_w(sd, OV7670_REG_VREF, v);
1814 1791 sethvflip(sd);
1815 } else { 1792 } else {
1816 i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); 1793 i2c_w(sd, 0x17, hwsbase);
1817 i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); 1794 i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
1818 i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); 1795 i2c_w(sd, 0x19, vwsbase);
1819 i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); 1796 i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
1820 } 1797 }
1821 return 0; 1798 return 0;
1822} 1799}
1823 1800
1824static int ov_sensor_mode_setup(struct sd *sd,
1825 int width, int height)
1826{
1827 struct ovsensor_window win;
1828
1829/* win.format = mode; */
1830
1831 /* Unless subcapture is enabled,
1832 * center the image window and downsample
1833 * if possible to increase the field of view */
1834 /* NOTE: OV518(+) and OV519 does downsampling on its own */
1835 win.width = width;
1836 win.height = height;
1837 if (width == sd->maxwidth)
1838 win.quarter = 0;
1839 else
1840 win.quarter = 1;
1841
1842 /* Center it */
1843 win.x = (win.width - width) / 2;
1844 win.y = (win.height - height) / 2;
1845
1846 /* Clock is determined by OV519 frame rate code */
1847 win.clockdiv = sd->clockdiv;
1848
1849 PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv);
1850 return set_ov_sensor_window(sd, &win);
1851}
1852
1853/* -- start the camera -- */ 1801/* -- start the camera -- */
1854static void sd_start(struct gspca_dev *gspca_dev) 1802static void sd_start(struct gspca_dev *gspca_dev)
1855{ 1803{
1856 struct sd *sd = (struct sd *) gspca_dev; 1804 struct sd *sd = (struct sd *) gspca_dev;
1857 int ret; 1805 int ret;
1858 1806
1859 1807 ret = ov519_mode_init_regs(sd);
1860 ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height);
1861 if (ret < 0) 1808 if (ret < 0)
1862 goto out; 1809 goto out;
1863 ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); 1810 ret = set_ov_sensor_window(sd);
1864 if (ret < 0) 1811 if (ret < 0)
1865 goto out; 1812 goto out;
1866 1813
1867 ret = ov51x_restart((struct sd *) gspca_dev); 1814 ret = ov51x_restart(sd);
1868 if (ret < 0) 1815 if (ret < 0)
1869 goto out; 1816 goto out;
1870 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); 1817 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
@@ -1938,12 +1885,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1938{ 1885{
1939 struct sd *sd = (struct sd *) gspca_dev; 1886 struct sd *sd = (struct sd *) gspca_dev;
1940 int val; 1887 int val;
1941/* int was_streaming; */
1942 1888
1943 val = sd->brightness; 1889 val = sd->brightness;
1944 PDEBUG(D_CONF, "brightness:%d", val); 1890 PDEBUG(D_CONF, "brightness:%d", val);
1945/* was_streaming = gspca_dev->streaming; 1891/* if (gspca_dev->streaming)
1946 * if (was_streaming)
1947 * ov51x_stop(sd); */ 1892 * ov51x_stop(sd); */
1948 switch (sd->sensor) { 1893 switch (sd->sensor) {
1949 case SEN_OV8610: 1894 case SEN_OV8610:
@@ -1961,12 +1906,12 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1961 i2c_w(sd, OV7610_REG_BRT, val); 1906 i2c_w(sd, OV7610_REG_BRT, val);
1962 break; 1907 break;
1963 case SEN_OV7670: 1908 case SEN_OV7670:
1964/*jfm - from windblows 1909/*win trace
1965 * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ 1910 * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
1966 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); 1911 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
1967 break; 1912 break;
1968 } 1913 }
1969/* if (was_streaming) 1914/* if (gspca_dev->streaming)
1970 * ov51x_restart(sd); */ 1915 * ov51x_restart(sd); */
1971} 1916}
1972 1917
@@ -1974,12 +1919,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1974{ 1919{
1975 struct sd *sd = (struct sd *) gspca_dev; 1920 struct sd *sd = (struct sd *) gspca_dev;
1976 int val; 1921 int val;
1977/* int was_streaming; */
1978 1922
1979 val = sd->contrast; 1923 val = sd->contrast;
1980 PDEBUG(D_CONF, "contrast:%d", val); 1924 PDEBUG(D_CONF, "contrast:%d", val);
1981/* was_streaming = gspca_dev->streaming; 1925/* if (gspca_dev->streaming)
1982 if (was_streaming)
1983 ov51x_stop(sd); */ 1926 ov51x_stop(sd); */
1984 switch (sd->sensor) { 1927 switch (sd->sensor) {
1985 case SEN_OV7610: 1928 case SEN_OV7610:
@@ -2016,7 +1959,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
2016 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); 1959 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
2017 break; 1960 break;
2018 } 1961 }
2019/* if (was_streaming) 1962/* if (gspca_dev->streaming)
2020 ov51x_restart(sd); */ 1963 ov51x_restart(sd); */
2021} 1964}
2022 1965
@@ -2024,12 +1967,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
2024{ 1967{
2025 struct sd *sd = (struct sd *) gspca_dev; 1968 struct sd *sd = (struct sd *) gspca_dev;
2026 int val; 1969 int val;
2027/* int was_streaming; */
2028 1970
2029 val = sd->colors; 1971 val = sd->colors;
2030 PDEBUG(D_CONF, "saturation:%d", val); 1972 PDEBUG(D_CONF, "saturation:%d", val);
2031/* was_streaming = gspca_dev->streaming; 1973/* if (gspca_dev->streaming)
2032 if (was_streaming)
2033 ov51x_stop(sd); */ 1974 ov51x_stop(sd); */
2034 switch (sd->sensor) { 1975 switch (sd->sensor) {
2035 case SEN_OV8610: 1976 case SEN_OV8610:
@@ -2055,7 +1996,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
2055 /* set REG_COM13 values for UV sat auto mode */ 1996 /* set REG_COM13 values for UV sat auto mode */
2056 break; 1997 break;
2057 } 1998 }
2058/* if (was_streaming) 1999/* if (gspca_dev->streaming)
2059 ov51x_restart(sd); */ 2000 ov51x_restart(sd); */
2060} 2001}
2061 2002
@@ -2110,6 +2051,40 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2110 return 0; 2051 return 0;
2111} 2052}
2112 2053
2054static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2055{
2056 struct sd *sd = (struct sd *) gspca_dev;
2057
2058 sd->hflip = val;
2059 sethvflip(sd);
2060 return 0;
2061}
2062
2063static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
2064{
2065 struct sd *sd = (struct sd *) gspca_dev;
2066
2067 *val = sd->hflip;
2068 return 0;
2069}
2070
2071static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2072{
2073 struct sd *sd = (struct sd *) gspca_dev;
2074
2075 sd->vflip = val;
2076 sethvflip(sd);
2077 return 0;
2078}
2079
2080static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2081{
2082 struct sd *sd = (struct sd *) gspca_dev;
2083
2084 *val = sd->vflip;
2085 return 0;
2086}
2087
2113/* sub-driver description */ 2088/* sub-driver description */
2114static const struct sd_desc sd_desc = { 2089static const struct sd_desc sd_desc = {
2115 .name = MODULE_NAME, 2090 .name = MODULE_NAME,
@@ -2178,4 +2153,3 @@ module_exit(sd_mod_exit);
2178 2153
2179module_param(frame_rate, int, 0644); 2154module_param(frame_rate, int, 0644);
2180MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); 2155MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");
2181
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index ea3d7021f401..815bea6edc44 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -31,7 +31,9 @@ MODULE_LICENSE("GPL");
31struct sd { 31struct sd {
32 struct gspca_dev gspca_dev; /* !! must be the first item */ 32 struct gspca_dev gspca_dev; /* !! must be the first item */
33 33
34 int avg_lum; 34 int lum_sum;
35 atomic_t avg_lum;
36 atomic_t do_gain;
35 37
36 unsigned char brightness; 38 unsigned char brightness;
37 unsigned char contrast; 39 unsigned char contrast;
@@ -271,6 +273,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
271 sd->contrast = CONTRAST_DEF; 273 sd->contrast = CONTRAST_DEF;
272 sd->colors = COLOR_DEF; 274 sd->colors = COLOR_DEF;
273 sd->autogain = AUTOGAIN_DEF; 275 sd->autogain = AUTOGAIN_DEF;
276 sd->ag_cnt = -1;
274 return 0; 277 return 0;
275} 278}
276 279
@@ -311,6 +314,18 @@ static void setcolors(struct gspca_dev *gspca_dev)
311 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); 314 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
312} 315}
313 316
317static void setautogain(struct gspca_dev *gspca_dev)
318{
319 struct sd *sd = (struct sd *) gspca_dev;
320
321 if (sd->autogain) {
322 sd->lum_sum = 0;
323 sd->ag_cnt = AG_CNT_START;
324 } else {
325 sd->ag_cnt = -1;
326 }
327}
328
314/* this function is called at open time */ 329/* this function is called at open time */
315static int sd_open(struct gspca_dev *gspca_dev) 330static int sd_open(struct gspca_dev *gspca_dev)
316{ 331{
@@ -320,8 +335,6 @@ static int sd_open(struct gspca_dev *gspca_dev)
320 335
321static void sd_start(struct gspca_dev *gspca_dev) 336static void sd_start(struct gspca_dev *gspca_dev)
322{ 337{
323 struct sd *sd = (struct sd *) gspca_dev;
324
325 reg_w(gspca_dev, 0xff, 0x01); 338 reg_w(gspca_dev, 0xff, 0x01);
326 reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); 339 reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8);
327 reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); 340 reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8);
@@ -394,6 +407,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
394 setcontrast(gspca_dev); 407 setcontrast(gspca_dev);
395 setbrightness(gspca_dev); 408 setbrightness(gspca_dev);
396 setcolors(gspca_dev); 409 setcolors(gspca_dev);
410 setautogain(gspca_dev);
397 411
398 /* set correct resolution */ 412 /* set correct resolution */
399 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 413 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
@@ -431,13 +445,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
431 reg_w(gspca_dev, 0xff, 0x01); 445 reg_w(gspca_dev, 0xff, 0x01);
432 reg_w(gspca_dev, 0x78, 0x04); 446 reg_w(gspca_dev, 0x78, 0x04);
433 reg_w(gspca_dev, 0x78, 0x05); 447 reg_w(gspca_dev, 0x78, 0x05);
434
435 if (sd->autogain) {
436 sd->ag_cnt = AG_CNT_START;
437 sd->avg_lum = 0;
438 } else {
439 sd->ag_cnt = -1;
440 }
441} 448}
442 449
443static void sd_stopN(struct gspca_dev *gspca_dev) 450static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -473,13 +480,20 @@ static void sd_close(struct gspca_dev *gspca_dev)
473 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ 480 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
474} 481}
475 482
476static void setautogain(struct gspca_dev *gspca_dev, int luma) 483static void do_autogain(struct gspca_dev *gspca_dev)
477{ 484{
485 struct sd *sd = (struct sd *) gspca_dev;
486 int luma;
478 int luma_mean = 128; 487 int luma_mean = 128;
479 int luma_delta = 20; 488 int luma_delta = 20;
480 __u8 spring = 5; 489 __u8 spring = 5;
481 int Gbright; 490 int Gbright;
482 491
492 if (!atomic_read(&sd->do_gain))
493 return;
494 atomic_set(&sd->do_gain, 0);
495
496 luma = atomic_read(&sd->avg_lum);
483 Gbright = reg_r(gspca_dev, 0x02); 497 Gbright = reg_r(gspca_dev, 0x02);
484 PDEBUG(D_FRAM, "luma mean %d", luma); 498 PDEBUG(D_FRAM, "luma mean %d", luma);
485 if (luma < luma_mean - luma_delta || 499 if (luma < luma_mean - luma_delta ||
@@ -523,12 +537,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
523 537
524 /* start of frame */ 538 /* start of frame */
525 if (sd->ag_cnt >= 0 && p > 28) { 539 if (sd->ag_cnt >= 0 && p > 28) {
526 sd->avg_lum += data[p - 23]; 540 sd->lum_sum += data[p - 23];
527 if (--sd->ag_cnt < 0) { 541 if (--sd->ag_cnt < 0) {
528 sd->ag_cnt = AG_CNT_START; 542 sd->ag_cnt = AG_CNT_START;
529 setautogain(gspca_dev, 543 atomic_set(&sd->avg_lum,
530 sd->avg_lum / AG_CNT_START); 544 sd->lum_sum / AG_CNT_START);
531 sd->avg_lum = 0; 545 sd->lum_sum = 0;
546 atomic_set(&sd->do_gain, 1);
532 } 547 }
533 } 548 }
534 549
@@ -677,12 +692,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
677 struct sd *sd = (struct sd *) gspca_dev; 692 struct sd *sd = (struct sd *) gspca_dev;
678 693
679 sd->autogain = val; 694 sd->autogain = val;
680 if (val) { 695 if (gspca_dev->streaming)
681 sd->ag_cnt = AG_CNT_START; 696 setautogain(gspca_dev);
682 sd->avg_lum = 0;
683 } else {
684 sd->ag_cnt = -1;
685 }
686 return 0; 697 return 0;
687} 698}
688 699
@@ -706,6 +717,7 @@ static struct sd_desc sd_desc = {
706 .stop0 = sd_stop0, 717 .stop0 = sd_stop0,
707 .close = sd_close, 718 .close = sd_close,
708 .pkt_scan = sd_pkt_scan, 719 .pkt_scan = sd_pkt_scan,
720 .dq_callback = do_autogain,
709}; 721};
710 722
711/* -- module initialisation -- */ 723/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index e18748c5a14d..11210c71f66c 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -408,7 +408,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
408 const __u8 *buffer, 408 const __u8 *buffer,
409 int len) 409 int len)
410{ 410{
411#ifdef CONFIG_VIDEO_ADV_DEBUG 411#ifdef GSPCA_DEBUG
412 if (len > sizeof gspca_dev->usb_buf) { 412 if (len > sizeof gspca_dev->usb_buf) {
413 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); 413 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
414 return; 414 return;
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 33a3df1f6915..245a30ec5fb1 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 int avg_lum; 35 atomic_t avg_lum;
36 unsigned int exposure; 36 unsigned int exposure;
37 37
38 unsigned short brightness; 38 unsigned short brightness;
@@ -148,55 +148,58 @@ static struct v4l2_pix_format vga_mode[] = {
148 148
149/*Data from sn9c102p+hv71331r */ 149/*Data from sn9c102p+hv71331r */
150static const __u8 sn_hv7131[] = { 150static const __u8 sn_hv7131[] = {
151/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ 151/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
152 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, 152 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
153/* rega regb regc regd rege regf reg10 reg11 */ 153/* reg8 reg9 rega regb regc regd rege regf */
154 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ 154 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
155/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ 155/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
156 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, 156 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
157/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ 157/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 158 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
159}; 159};
160 160
161static const __u8 sn_mi0360[] = { 161static const __u8 sn_mi0360[] = {
162/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ 162/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
163 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, 163 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
164/* rega regb regc regd rege regf reg10 reg11 */ 164/* reg8 reg9 rega regb regc regd rege regf */
165 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 165 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
166/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ 166/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
167 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, 167 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
168/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ 168/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 169 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
170}; 170};
171 171
172static const __u8 sn_mo4000[] = { 172static const __u8 sn_mo4000[] = {
173/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ 173/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
174 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, 174 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
175/* reg9 rega regb regc regd rege regf reg10 reg11*/ 175/* reg8 reg9 rega regb regc regd rege regf */
176 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 176 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ 177/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
178 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, 178 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
179/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ 179/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, 180 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
181 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7,
182 0xd3, 0xdf, 0xea, 0xf5
183}; 181};
184 182
185static const __u8 sn_ov7648[] = { 183static const __u8 sn_ov7648[] = {
186 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, 184/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
187 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, 185 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
188 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 186/* reg8 reg9 rega regb regc regd rege regf */
187 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10,
188/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
189 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82,
190/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
191 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
189}; 192};
190 193
191static const __u8 sn_ov7660[] = { 194static const __u8 sn_ov7660[] = {
192/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ 195/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
193 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, 196 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
194/* reg9 rega regb regc regd rege regf reg10 reg11*/ 197/* reg8 reg9 rega regb regc regd rege regf */
195 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 198 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
196/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ 199/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
197 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00, 200 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
198/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ 201/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 202 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200}; 203};
201 204
202/* sequence specific to the sensors - !! index = SENSOR_xxx */ 205/* sequence specific to the sensors - !! index = SENSOR_xxx */
@@ -212,10 +215,6 @@ static const __u8 regsn20[] = {
212 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 215 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
213 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff 216 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
214}; 217};
215static const __u8 regsn20_sn9c120[] = {
216 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90,
217 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff
218};
219static const __u8 regsn20_sn9c325[] = { 218static const __u8 regsn20_sn9c325[] = {
220 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, 219 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
221 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 220 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
@@ -227,21 +226,6 @@ static const __u8 reg84[] = {
227/* 0x00, 0x00, 0x00, 0x00, 0x00 */ 226/* 0x00, 0x00, 0x00, 0x00, 0x00 */
228 0xf7, 0x0f, 0x0a, 0x00, 0x00 227 0xf7, 0x0f, 0x0a, 0x00, 0x00
229}; 228};
230static const __u8 reg84_sn9c120_1[] = {
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x00, 0x0c, 0x00, 0x00
234};
235static const __u8 reg84_sn9c120_2[] = {
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x0c, 0x02, 0x3b
239};
240static const __u8 reg84_sn9c120_3[] = {
241 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f,
242 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f,
243 0xf5, 0x0f, 0x0c, 0x02, 0x3b
244};
245static const __u8 reg84_sn9c325[] = { 229static const __u8 reg84_sn9c325[] = {
246 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, 230 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
247 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, 231 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
@@ -360,17 +344,15 @@ static const __u8 ov7660_sensor_init[][8] = {
360 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 344 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
361/* (delay 20ms) */ 345/* (delay 20ms) */
362 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, 346 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
363 /* Outformat ?? rawRGB */ 347 /* Outformat = rawRGB */
364 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ 348 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
365 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, 349 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
366/* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */
367 /* GAIN BLUE RED VREF */ 350 /* GAIN BLUE RED VREF */
368 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, 351 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
369 /* COM 1 BAVE GEAVE AECHH */ 352 /* COM 1 BAVE GEAVE AECHH */
370 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ 353 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
371 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ 354 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
372 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, 355 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
373/* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */
374 /* AECH CLKRC COM7 COM8 */ 356 /* AECH CLKRC COM7 COM8 */
375 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ 357 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
376 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, 358 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
@@ -379,8 +361,8 @@ static const __u8 ov7660_sensor_init[][8] = {
379 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ 361 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
380 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, 362 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
381 /* BOS GBOS GROS ROS (BGGR offset) */ 363 /* BOS GBOS GROS ROS (BGGR offset) */
382 {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, 364/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
383/* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */ 365 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
384 /* AEW AEB VPT BBIAS */ 366 /* AEW AEB VPT BBIAS */
385 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, 367 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
386 /* GbBIAS RSVD EXHCH EXHCL */ 368 /* GbBIAS RSVD EXHCH EXHCL */
@@ -407,9 +389,9 @@ static const __u8 ov7660_sensor_init[][8] = {
407 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, 389 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
408 /* LCC1 LCC2 LCC3 LCC4 */ 390 /* LCC1 LCC2 LCC3 LCC4 */
409 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ 391 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
410 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, 392 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
411 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, 393 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
412 /* band gap reference [0..3] DBLV */ 394 /* band gap reference [0:3] DBLV */
413 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ 395 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
414 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ 396 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
415 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ 397 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
@@ -419,37 +401,35 @@ static const __u8 ov7660_sensor_init[][8] = {
419 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ 401 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
420 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ 402 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
421 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ 403 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
422 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, 404 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
423/****** (some exchanges in the win trace) ******/ 405/****** (some exchanges in the win trace) ******/
424 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, 406 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
425 /* bits[3..0]reserved */ 407 /* bits[3..0]reserved */
426 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, 408 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, 409 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
428 /* VREF vertical frame ctrl */ 410 /* VREF vertical frame ctrl */
429 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, 411 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ 412 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
431 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, 413 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
432 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, 414 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
433/* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */ 415 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
434 {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10}, 416/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
435 {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10},
436/****** (some exchanges in the win trace) ******/ 417/****** (some exchanges in the win trace) ******/
437 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ 418 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
438 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ 419 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
439 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, 420 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
440 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, 421 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
441 {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, 422/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
442/****** (some exchanges in the win trace) ******/ 423/****** (some exchanges in the win trace) ******/
443/**********startsensor KO if changed !!****/ 424/******!! startsensor KO if changed !!****/
444 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, 425 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
445 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, 426 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
446 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, 427 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, 428 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
448/* here may start the isoc exchanges */
449 {} 429 {}
450}; 430};
451/* reg0x04 reg0x07 reg 0x10 */ 431/* reg 0x04 reg 0x07 reg 0x10 */
452/* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ 432/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
453 433
454static const __u8 ov7648_sensor_init[][8] = { 434static const __u8 ov7648_sensor_init[][8] = {
455 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, 435 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
@@ -680,13 +660,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
680 const __u8 *reg9a; 660 const __u8 *reg9a;
681 static const __u8 reg9a_def[] = 661 static const __u8 reg9a_def[] =
682 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; 662 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
683 static const __u8 reg9a_sn9c120[] = /* from win trace */
684 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
685 static const __u8 reg9a_sn9c325[] = 663 static const __u8 reg9a_sn9c325[] =
686 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; 664 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
665 static const __u8 regd4[] = {0x60, 0x00, 0x00};
687 666
688 reg_w1(gspca_dev, 0xf1, 0x00); 667 reg_w1(gspca_dev, 0xf1, 0x00);
689 reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/ 668 reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/
690 669
691 /* configure gpio */ 670 /* configure gpio */
692 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 671 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
@@ -696,25 +675,17 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
696 case BRIDGE_SN9C325: 675 case BRIDGE_SN9C325:
697 reg9a = reg9a_sn9c325; 676 reg9a = reg9a_sn9c325;
698 break; 677 break;
699 case BRIDGE_SN9C120:
700 reg9a = reg9a_sn9c120;
701 break;
702 default: 678 default:
703 reg9a = reg9a_def; 679 reg9a = reg9a_def;
704 break; 680 break;
705 } 681 }
706 reg_w(gspca_dev, 0x9a, reg9a, 6); 682 reg_w(gspca_dev, 0x9a, reg9a, 6);
707 683
708 reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */ 684 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
709 685
710 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); 686 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
711 687
712 switch (sd->bridge) { 688 switch (sd->bridge) {
713 case BRIDGE_SN9C120: /* from win trace */
714 reg_w1(gspca_dev, 0x01, 0x61);
715 reg_w1(gspca_dev, 0x17, 0x20);
716 reg_w1(gspca_dev, 0x01, 0x60);
717 break;
718 case BRIDGE_SN9C325: 689 case BRIDGE_SN9C325:
719 reg_w1(gspca_dev, 0x01, 0x43); 690 reg_w1(gspca_dev, 0x01, 0x43);
720 reg_w1(gspca_dev, 0x17, 0xae); 691 reg_w1(gspca_dev, 0x17, 0xae);
@@ -810,6 +781,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
810 sd->contrast = CONTRAST_DEF; 781 sd->contrast = CONTRAST_DEF;
811 sd->colors = COLOR_DEF; 782 sd->colors = COLOR_DEF;
812 sd->autogain = AUTOGAIN_DEF; 783 sd->autogain = AUTOGAIN_DEF;
784 sd->ag_cnt = -1;
785
813 return 0; 786 return 0;
814} 787}
815 788
@@ -823,10 +796,11 @@ static int sd_open(struct gspca_dev *gspca_dev)
823 796
824 /* setup a selector by bridge */ 797 /* setup a selector by bridge */
825 reg_w1(gspca_dev, 0xf1, 0x01); 798 reg_w1(gspca_dev, 0xf1, 0x01);
826 reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */
827 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
828 reg_r(gspca_dev, 0x00, 1); 799 reg_r(gspca_dev, 0x00, 1);
800 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
801 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
829 regF1 = gspca_dev->usb_buf[0]; 802 regF1 = gspca_dev->usb_buf[0];
803 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
830 switch (sd->bridge) { 804 switch (sd->bridge) {
831 case BRIDGE_SN9C102P: 805 case BRIDGE_SN9C102P:
832 if (regF1 != 0x11) 806 if (regF1 != 0x11)
@@ -937,15 +911,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
937 sd->exposure = setexposure(gspca_dev, expo); 911 sd->exposure = setexposure(gspca_dev, expo);
938 break; 912 break;
939 case SENSOR_MI0360: 913 case SENSOR_MI0360:
940 expo = sd->brightness >> 4;
941 sd->exposure = setexposure(gspca_dev, expo);
942 break;
943 case SENSOR_MO4000: 914 case SENSOR_MO4000:
944 expo = sd->brightness >> 4; 915 expo = sd->brightness >> 4;
945 sd->exposure = setexposure(gspca_dev, expo); 916 sd->exposure = setexposure(gspca_dev, expo);
946 break; 917 break;
947 case SENSOR_OV7660:
948 return; /*jfm??*/
949 } 918 }
950 919
951 k2 = sd->brightness >> 10; 920 k2 = sd->brightness >> 10;
@@ -958,8 +927,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
958 __u8 k2; 927 __u8 k2;
959 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; 928 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
960 929
961 if (sd->sensor == SENSOR_OV7660)
962 return; /*jfm??*/
963 k2 = sd->contrast; 930 k2 = sd->contrast;
964 contrast[2] = k2; 931 contrast[2] = k2;
965 contrast[0] = (k2 + 1) >> 1; 932 contrast[0] = (k2 + 1) >> 1;
@@ -981,20 +948,32 @@ static void setcolors(struct gspca_dev *gspca_dev)
981 reg_w1(gspca_dev, 0x05, data); 948 reg_w1(gspca_dev, 0x05, data);
982} 949}
983 950
951static void setautogain(struct gspca_dev *gspca_dev)
952{
953 struct sd *sd = (struct sd *) gspca_dev;
954
955 switch (sd->sensor) {
956 case SENSOR_HV7131R:
957 case SENSOR_MO4000:
958 case SENSOR_MI0360:
959 if (sd->autogain)
960 sd->ag_cnt = AG_CNT_START;
961 else
962 sd->ag_cnt = -1;
963 break;
964 }
965}
966
984/* -- start the camera -- */ 967/* -- start the camera -- */
985static void sd_start(struct gspca_dev *gspca_dev) 968static void sd_start(struct gspca_dev *gspca_dev)
986{ 969{
987 struct sd *sd = (struct sd *) gspca_dev; 970 struct sd *sd = (struct sd *) gspca_dev;
988 int i; 971 int i;
989 __u8 data; 972 __u8 reg1, reg17, reg18;
990 __u8 reg1;
991 __u8 reg17;
992 const __u8 *sn9c1xx; 973 const __u8 *sn9c1xx;
993 int mode; 974 int mode;
994 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; 975 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
995 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 976 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
996 static const __u8 CA_sn9c120[] =
997 { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */
998 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ 977 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
999 static const __u8 CE_sn9c325[] = 978 static const __u8 CE_sn9c325[] =
1000 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ 979 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */
@@ -1002,9 +981,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
1002 sn9c1xx = sn_tb[(int) sd->sensor]; 981 sn9c1xx = sn_tb[(int) sd->sensor];
1003 configure_gpio(gspca_dev, sn9c1xx); 982 configure_gpio(gspca_dev, sn9c1xx);
1004 983
1005/*fixme:jfm this sequence should appear at end of sd_start */ 984/* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/
1006/* with
1007 reg_w1(gspca_dev, 0x01, 0x44); */
1008 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); 985 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1009 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); 986 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1010 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); 987 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
@@ -1016,20 +993,16 @@ static void sd_start(struct gspca_dev *gspca_dev)
1016 reg_w1(gspca_dev, 0xc7, 0x00); 993 reg_w1(gspca_dev, 0xc7, 0x00);
1017 reg_w1(gspca_dev, 0xc8, 0x50); 994 reg_w1(gspca_dev, 0xc8, 0x50);
1018 reg_w1(gspca_dev, 0xc9, 0x3c); 995 reg_w1(gspca_dev, 0xc9, 0x3c);
1019/*fixme:jfm end of ending sequence */
1020 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 996 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1021 switch (sd->bridge) { 997 switch (sd->bridge) {
1022 case BRIDGE_SN9C325: 998 case BRIDGE_SN9C325:
1023 data = 0xae; 999 reg17 = 0xae;
1024 break;
1025 case BRIDGE_SN9C120:
1026 data = 0xa0;
1027 break; 1000 break;
1028 default: 1001 default:
1029 data = 0x60; 1002 reg17 = 0x60;
1030 break; 1003 break;
1031 } 1004 }
1032 reg_w1(gspca_dev, 0x17, data); 1005 reg_w1(gspca_dev, 0x17, reg17);
1033 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); 1006 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1034 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); 1007 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1035 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); 1008 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
@@ -1044,20 +1017,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
1044 reg_w1(gspca_dev, 0x9a, 0x0a); 1017 reg_w1(gspca_dev, 0x9a, 0x0a);
1045 reg_w1(gspca_dev, 0x99, 0x60); 1018 reg_w1(gspca_dev, 0x99, 0x60);
1046 break; 1019 break;
1047 case BRIDGE_SN9C120:
1048 reg_w(gspca_dev, 0x20, regsn20_sn9c120,
1049 sizeof regsn20_sn9c120);
1050 for (i = 0; i < 2; i++)
1051 reg_w(gspca_dev, 0x84, reg84_sn9c120_1,
1052 sizeof reg84_sn9c120_1);
1053 for (i = 0; i < 6; i++)
1054 reg_w(gspca_dev, 0x84, reg84_sn9c120_2,
1055 sizeof reg84_sn9c120_2);
1056 reg_w(gspca_dev, 0x84, reg84_sn9c120_3,
1057 sizeof reg84_sn9c120_3);
1058 reg_w1(gspca_dev, 0x9a, 0x05);
1059 reg_w1(gspca_dev, 0x99, 0x5b);
1060 break;
1061 default: 1020 default:
1062 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); 1021 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1063 for (i = 0; i < 8; i++) 1022 for (i = 0; i < 8; i++)
@@ -1107,22 +1066,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
1107/* reg1 = 0x44; */ 1066/* reg1 = 0x44; */
1108/* reg1 = 0x46; (done) */ 1067/* reg1 = 0x46; (done) */
1109 } else { 1068 } else {
1110 reg17 = 0xa2; /* 640 */ 1069 reg17 = 0x22; /* 640 MCKSIZE */
1111 reg1 = 0x40; 1070 reg1 = 0x06;
1112 } 1071 }
1113 break; 1072 break;
1114 } 1073 }
1115 reg_w(gspca_dev, 0xc0, C0, 6); 1074 reg_w(gspca_dev, 0xc0, C0, 6);
1075 reg_w(gspca_dev, 0xca, CA, 4);
1116 switch (sd->bridge) { 1076 switch (sd->bridge) {
1117 case BRIDGE_SN9C120: /*jfm ?? */
1118 reg_w(gspca_dev, 0xca, CA_sn9c120, 4);
1119 break;
1120 default:
1121 reg_w(gspca_dev, 0xca, CA, 4);
1122 break;
1123 }
1124 switch (sd->bridge) {
1125 case BRIDGE_SN9C120: /*jfm ?? */
1126 case BRIDGE_SN9C325: 1077 case BRIDGE_SN9C325:
1127 reg_w(gspca_dev, 0xce, CE_sn9c325, 4); 1078 reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
1128 break; 1079 break;
@@ -1133,19 +1084,19 @@ static void sd_start(struct gspca_dev *gspca_dev)
1133 } 1084 }
1134 1085
1135 /* here change size mode 0 -> VGA; 1 -> CIF */ 1086 /* here change size mode 0 -> VGA; 1 -> CIF */
1136 data = 0x40 | sn9c1xx[0x18] | (mode << 4); 1087 reg18 = sn9c1xx[0x18] | (mode << 4);
1137 reg_w1(gspca_dev, 0x18, data); 1088 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1138 1089
1139 reg_w(gspca_dev, 0x100, qtable4, 0x40); 1090 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1140 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); 1091 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1141 1092
1142 data = sn9c1xx[0x18] | (mode << 4); 1093 reg_w1(gspca_dev, 0x18, reg18);
1143 reg_w1(gspca_dev, 0x18, data);
1144 1094
1145 reg_w1(gspca_dev, 0x17, reg17); 1095 reg_w1(gspca_dev, 0x17, reg17);
1146 reg_w1(gspca_dev, 0x01, reg1); 1096 reg_w1(gspca_dev, 0x01, reg1);
1147 setbrightness(gspca_dev); 1097 setbrightness(gspca_dev);
1148 setcontrast(gspca_dev); 1098 setcontrast(gspca_dev);
1099 setautogain(gspca_dev);
1149} 1100}
1150 1101
1151static void sd_stopN(struct gspca_dev *gspca_dev) 1102static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -1168,12 +1119,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1168 i2c_w8(gspca_dev, stopmi0360); 1119 i2c_w8(gspca_dev, stopmi0360);
1169 data = 0x29; 1120 data = 0x29;
1170 break; 1121 break;
1171 case SENSOR_MO4000:
1172 break;
1173 case SENSOR_OV7648: 1122 case SENSOR_OV7648:
1174 data = 0x29; 1123 data = 0x29;
1175 break; 1124 break;
1176 default: 1125 default:
1126/* case SENSOR_MO4000: */
1177/* case SENSOR_OV7660: */ 1127/* case SENSOR_OV7660: */
1178 break; 1128 break;
1179 } 1129 }
@@ -1193,16 +1143,23 @@ static void sd_close(struct gspca_dev *gspca_dev)
1193{ 1143{
1194} 1144}
1195 1145
1196static void setautogain(struct gspca_dev *gspca_dev) 1146static void do_autogain(struct gspca_dev *gspca_dev)
1197{ 1147{
1198 struct sd *sd = (struct sd *) gspca_dev; 1148 struct sd *sd = (struct sd *) gspca_dev;
1199 /* Thanks S., without your advice, autobright should not work :) */
1200 int delta; 1149 int delta;
1201 int expotimes = 0; 1150 int expotimes;
1202 __u8 luma_mean = 130; 1151 __u8 luma_mean = 130;
1203 __u8 luma_delta = 20; 1152 __u8 luma_delta = 20;
1204 1153
1205 delta = sd->avg_lum; 1154 /* Thanks S., without your advice, autobright should not work :) */
1155 if (sd->ag_cnt < 0)
1156 return;
1157 if (--sd->ag_cnt >= 0)
1158 return;
1159 sd->ag_cnt = AG_CNT_START;
1160
1161 delta = atomic_read(&sd->avg_lum);
1162 PDEBUG(D_FRAM, "mean lum %d", delta);
1206 if (delta < luma_mean - luma_delta || 1163 if (delta < luma_mean - luma_delta ||
1207 delta > luma_mean + luma_delta) { 1164 delta > luma_mean + luma_delta) {
1208 switch (sd->sensor) { 1165 switch (sd->sensor) {
@@ -1214,8 +1171,9 @@ static void setautogain(struct gspca_dev *gspca_dev)
1214 sd->exposure = setexposure(gspca_dev, 1171 sd->exposure = setexposure(gspca_dev,
1215 (unsigned int) (expotimes << 8)); 1172 (unsigned int) (expotimes << 8));
1216 break; 1173 break;
1217 case SENSOR_MO4000: 1174 default:
1218 case SENSOR_MI0360: 1175/* case SENSOR_MO4000: */
1176/* case SENSOR_MI0360: */
1219 expotimes = sd->exposure; 1177 expotimes = sd->exposure;
1220 expotimes += (luma_mean - delta) >> 6; 1178 expotimes += (luma_mean - delta) >> 6;
1221 if (expotimes < 0) 1179 if (expotimes < 0)
@@ -1228,6 +1186,8 @@ static void setautogain(struct gspca_dev *gspca_dev)
1228 } 1186 }
1229} 1187}
1230 1188
1189/* scan the URB packets */
1190/* This function is run at interrupt level. */
1231static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1191static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1232 struct gspca_frame *frame, /* target */ 1192 struct gspca_frame *frame, /* target */
1233 __u8 *data, /* isoc packet */ 1193 __u8 *data, /* isoc packet */
@@ -1244,9 +1204,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1244 frame, data, sof + 2); 1204 frame, data, sof + 2);
1245 if (sd->ag_cnt < 0) 1205 if (sd->ag_cnt < 0)
1246 return; 1206 return;
1247 if (--sd->ag_cnt >= 0)
1248 return;
1249 sd->ag_cnt = AG_CNT_START;
1250/* w1 w2 w3 */ 1207/* w1 w2 w3 */
1251/* w4 w5 w6 */ 1208/* w4 w5 w6 */
1252/* w7 w8 */ 1209/* w7 w8 */
@@ -1261,9 +1218,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1261/* w5 */ 1218/* w5 */
1262 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; 1219 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1263 avg_lum >>= 4; 1220 avg_lum >>= 4;
1264 sd->avg_lum = avg_lum; 1221 atomic_set(&sd->avg_lum, avg_lum);
1265 PDEBUG(D_PACK, "mean lum %d", avg_lum);
1266 setautogain(gspca_dev);
1267 return; 1222 return;
1268 } 1223 }
1269 if (gspca_dev->last_packet_type == LAST_PACKET) { 1224 if (gspca_dev->last_packet_type == LAST_PACKET) {
@@ -1300,6 +1255,7 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev)
1300 (hexpo << 10) | (mexpo << 2) | lexpo); 1255 (hexpo << 10) | (mexpo << 2) | lexpo);
1301 return (hexpo << 10) | (mexpo << 2) | lexpo; 1256 return (hexpo << 10) | (mexpo << 2) | lexpo;
1302 default: 1257 default:
1258/* case SENSOR_OV7648: * jfm: is it ok for 7648? */
1303/* case SENSOR_OV7660: */ 1259/* case SENSOR_OV7660: */
1304 /* read sensor exposure */ 1260 /* read sensor exposure */
1305 i2c_r5(gspca_dev, 0x04); 1261 i2c_r5(gspca_dev, 0x04);
@@ -1318,14 +1274,12 @@ static void getbrightness(struct gspca_dev *gspca_dev)
1318 /* hardcoded registers seem not readable */ 1274 /* hardcoded registers seem not readable */
1319 switch (sd->sensor) { 1275 switch (sd->sensor) {
1320 case SENSOR_HV7131R: 1276 case SENSOR_HV7131R:
1321/* sd->brightness = 0x7fff; */
1322 sd->brightness = getexposure(gspca_dev) >> 4; 1277 sd->brightness = getexposure(gspca_dev) >> 4;
1323 break; 1278 break;
1324 case SENSOR_MI0360: 1279 case SENSOR_MI0360:
1325 sd->brightness = getexposure(gspca_dev) << 4; 1280 sd->brightness = getexposure(gspca_dev) << 4;
1326 break; 1281 break;
1327 case SENSOR_MO4000: 1282 case SENSOR_MO4000:
1328/* sd->brightness = 0x1fff; */
1329 sd->brightness = getexposure(gspca_dev) << 4; 1283 sd->brightness = getexposure(gspca_dev) << 4;
1330 break; 1284 break;
1331 } 1285 }
@@ -1391,10 +1345,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1391 struct sd *sd = (struct sd *) gspca_dev; 1345 struct sd *sd = (struct sd *) gspca_dev;
1392 1346
1393 sd->autogain = val; 1347 sd->autogain = val;
1394 if (val) 1348 if (gspca_dev->streaming)
1395 sd->ag_cnt = AG_CNT_START; 1349 setautogain(gspca_dev);
1396 else
1397 sd->ag_cnt = -1;
1398 return 0; 1350 return 0;
1399} 1351}
1400 1352
@@ -1418,6 +1370,7 @@ static const struct sd_desc sd_desc = {
1418 .stop0 = sd_stop0, 1370 .stop0 = sd_stop0,
1419 .close = sd_close, 1371 .close = sd_close,
1420 .pkt_scan = sd_pkt_scan, 1372 .pkt_scan = sd_pkt_scan,
1373 .dq_callback = do_autogain,
1421}; 1374};
1422 1375
1423/* -- module initialisation -- */ 1376/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 3c2be80cbd65..eda29d609359 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -61,27 +61,27 @@ static struct ctrl sd_ctrls[] = {
61 61
62static struct v4l2_pix_format vga_mode[] = { 62static struct v4l2_pix_format vga_mode[] = {
63 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 63 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
64 .bytesperline = 160 * 3, 64 .bytesperline = 160,
65 .sizeimage = 160 * 120 * 3 / 2, 65 .sizeimage = 160 * 120 * 3 / 2,
66 .colorspace = V4L2_COLORSPACE_SRGB, 66 .colorspace = V4L2_COLORSPACE_SRGB,
67 .priv = 5}, 67 .priv = 5},
68 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 68 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
69 .bytesperline = 176 * 3, 69 .bytesperline = 176,
70 .sizeimage = 176 * 144 * 3 / 2, 70 .sizeimage = 176 * 144 * 3 / 2,
71 .colorspace = V4L2_COLORSPACE_SRGB, 71 .colorspace = V4L2_COLORSPACE_SRGB,
72 .priv = 4}, 72 .priv = 4},
73 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 73 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
74 .bytesperline = 320 * 3, 74 .bytesperline = 320,
75 .sizeimage = 320 * 240 * 3 / 2, 75 .sizeimage = 320 * 240 * 3 / 2,
76 .colorspace = V4L2_COLORSPACE_SRGB, 76 .colorspace = V4L2_COLORSPACE_SRGB,
77 .priv = 2}, 77 .priv = 2},
78 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 78 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
79 .bytesperline = 352 * 3, 79 .bytesperline = 352,
80 .sizeimage = 352 * 288 * 3 / 2, 80 .sizeimage = 352 * 288 * 3 / 2,
81 .colorspace = V4L2_COLORSPACE_SRGB, 81 .colorspace = V4L2_COLORSPACE_SRGB,
82 .priv = 1}, 82 .priv = 1},
83 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 83 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
84 .bytesperline = 640 * 3, 84 .bytesperline = 640,
85 .sizeimage = 640 * 480 * 3 / 2, 85 .sizeimage = 640 * 480 * 3 / 2,
86 .colorspace = V4L2_COLORSPACE_SRGB, 86 .colorspace = V4L2_COLORSPACE_SRGB,
87 .priv = 0}, 87 .priv = 0},
@@ -776,7 +776,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
776 default: 776 default:
777 data += 1; 777 data += 1;
778 len -= 1; 778 len -= 1;
779 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 779 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
780 data, len); 780 data, len);
781 break; 781 break;
782 } 782 }
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 6fe715c80ad2..f622fa75766d 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -112,27 +112,27 @@ static struct ctrl sd_ctrls[] = {
112 112
113static struct v4l2_pix_format vga_mode[] = { 113static struct v4l2_pix_format vga_mode[] = {
114 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 114 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
115 .bytesperline = 160 * 3, 115 .bytesperline = 160,
116 .sizeimage = 160 * 120 * 3 / 2, 116 .sizeimage = 160 * 120 * 3 / 2,
117 .colorspace = V4L2_COLORSPACE_SRGB, 117 .colorspace = V4L2_COLORSPACE_SRGB,
118 .priv = 5}, 118 .priv = 5},
119 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 119 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
120 .bytesperline = 176 * 3, 120 .bytesperline = 176,
121 .sizeimage = 176 * 144 * 3 / 2, 121 .sizeimage = 176 * 144 * 3 / 2,
122 .colorspace = V4L2_COLORSPACE_SRGB, 122 .colorspace = V4L2_COLORSPACE_SRGB,
123 .priv = 4}, 123 .priv = 4},
124 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 124 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
125 .bytesperline = 320 * 3, 125 .bytesperline = 320,
126 .sizeimage = 320 * 240 * 3 / 2, 126 .sizeimage = 320 * 240 * 3 / 2,
127 .colorspace = V4L2_COLORSPACE_SRGB, 127 .colorspace = V4L2_COLORSPACE_SRGB,
128 .priv = 2}, 128 .priv = 2},
129 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 129 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
130 .bytesperline = 352 * 3, 130 .bytesperline = 352,
131 .sizeimage = 352 * 288 * 3 / 2, 131 .sizeimage = 352 * 288 * 3 / 2,
132 .colorspace = V4L2_COLORSPACE_SRGB, 132 .colorspace = V4L2_COLORSPACE_SRGB,
133 .priv = 1}, 133 .priv = 1},
134 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 134 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
135 .bytesperline = 640 * 3, 135 .bytesperline = 640,
136 .sizeimage = 640 * 480 * 3 / 2, 136 .sizeimage = 640 * 480 * 3 / 2,
137 .colorspace = V4L2_COLORSPACE_SRGB, 137 .colorspace = V4L2_COLORSPACE_SRGB,
138 .priv = 0}, 138 .priv = 0},
@@ -588,7 +588,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
588 default: 588 default:
589 data += 1; 589 data += 1;
590 len -= 1; 590 len -= 1;
591 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 591 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
592 data, len); 592 data, len);
593 break; 593 break;
594 } 594 }
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index b608a27ad115..699340c17dea 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -63,23 +63,23 @@ static struct ctrl sd_ctrls[] = {
63}; 63};
64 64
65static struct v4l2_pix_format sif_mode[] = { 65static struct v4l2_pix_format sif_mode[] = {
66 {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 66 {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
67 .bytesperline = 160 * 3, 67 .bytesperline = 160,
68 .sizeimage = 160 * 120 * 3 / 2, 68 .sizeimage = 160 * 120 * 3 / 2,
69 .colorspace = V4L2_COLORSPACE_SRGB, 69 .colorspace = V4L2_COLORSPACE_SRGB,
70 .priv = 3}, 70 .priv = 3},
71 {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 71 {176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
72 .bytesperline = 176 * 3, 72 .bytesperline = 176,
73 .sizeimage = 176 * 144 * 3 / 2, 73 .sizeimage = 176 * 144 * 3 / 2,
74 .colorspace = V4L2_COLORSPACE_SRGB, 74 .colorspace = V4L2_COLORSPACE_SRGB,
75 .priv = 2}, 75 .priv = 2},
76 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 76 {320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
77 .bytesperline = 320 * 3, 77 .bytesperline = 320,
78 .sizeimage = 320 * 240 * 3 / 2, 78 .sizeimage = 320 * 240 * 3 / 2,
79 .colorspace = V4L2_COLORSPACE_SRGB, 79 .colorspace = V4L2_COLORSPACE_SRGB,
80 .priv = 1}, 80 .priv = 1},
81 {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 81 {352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
82 .bytesperline = 352 * 3, 82 .bytesperline = 352,
83 .sizeimage = 352 * 288 * 3 / 2, 83 .sizeimage = 352 * 288 * 3 / 2,
84 .colorspace = V4L2_COLORSPACE_SRGB, 84 .colorspace = V4L2_COLORSPACE_SRGB,
85 .priv = 0}, 85 .priv = 0},
@@ -1583,7 +1583,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1583 default: 1583 default:
1584 data += 1; 1584 data += 1;
1585 len -= 1; 1585 len -= 1;
1586 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1586 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1587 data, len); 1587 data, len);
1588 break; 1588 break;
1589 } 1589 }
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index a26174508cb9..1073ac3d2ec6 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -644,6 +644,18 @@ static void setcontrast(struct gspca_dev *gspca_dev)
644 } 644 }
645} 645}
646 646
647static void setautogain(struct gspca_dev *gspca_dev)
648{
649 struct sd *sd = (struct sd *) gspca_dev;
650
651 if (sd->chip_revision == Rev072A) {
652 if (sd->autogain)
653 sd->ag_cnt = AG_CNT_START;
654 else
655 sd->ag_cnt = -1;
656 }
657}
658
647static void sd_start(struct gspca_dev *gspca_dev) 659static void sd_start(struct gspca_dev *gspca_dev)
648{ 660{
649 struct sd *sd = (struct sd *) gspca_dev; 661 struct sd *sd = (struct sd *) gspca_dev;
@@ -671,6 +683,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
671 reg_w_val(dev, 0x8500, mode); /* mode */ 683 reg_w_val(dev, 0x8500, mode); /* mode */
672 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ 684 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
673 reg_w_val(dev, 0x8112, 0x10 | 0x20); 685 reg_w_val(dev, 0x8112, 0x10 | 0x20);
686 setautogain(gspca_dev);
674 break; 687 break;
675 default: 688 default:
676/* case Rev012A: */ 689/* case Rev012A: */
@@ -720,18 +733,24 @@ static void sd_close(struct gspca_dev *gspca_dev)
720 reg_w_val(gspca_dev->dev, 0x8114, 0); 733 reg_w_val(gspca_dev->dev, 0x8114, 0);
721} 734}
722 735
723static void setautogain(struct gspca_dev *gspca_dev) 736static void do_autogain(struct gspca_dev *gspca_dev)
724{ 737{
725 struct sd *sd = (struct sd *) gspca_dev; 738 struct sd *sd = (struct sd *) gspca_dev;
726 int expotimes = 0; 739 int expotimes;
727 int pixelclk = 0; 740 int pixelclk;
728 int gainG = 0; 741 int gainG;
729 __u8 R, Gr, Gb, B; 742 __u8 R, Gr, Gb, B;
730 int y; 743 int y;
731 __u8 luma_mean = 110; 744 __u8 luma_mean = 110;
732 __u8 luma_delta = 20; 745 __u8 luma_delta = 20;
733 __u8 spring = 4; 746 __u8 spring = 4;
734 747
748 if (sd->ag_cnt < 0)
749 return;
750 if (--sd->ag_cnt >= 0)
751 return;
752 sd->ag_cnt = AG_CNT_START;
753
735 switch (sd->chip_revision) { 754 switch (sd->chip_revision) {
736 case Rev072A: 755 case Rev072A:
737 reg_r(gspca_dev, 0x8621, 1); 756 reg_r(gspca_dev, 0x8621, 1);
@@ -795,18 +814,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
795 __u8 *data, /* isoc packet */ 814 __u8 *data, /* isoc packet */
796 int len) /* iso packet length */ 815 int len) /* iso packet length */
797{ 816{
798 struct sd *sd = (struct sd *) gspca_dev;
799
800 switch (data[0]) { 817 switch (data[0]) {
801 case 0: /* start of frame */ 818 case 0: /* start of frame */
802 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 819 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
803 data, 0); 820 data, 0);
804 if (sd->ag_cnt >= 0) {
805 if (--sd->ag_cnt < 0) {
806 sd->ag_cnt = AG_CNT_START;
807 setautogain(gspca_dev);
808 }
809 }
810 data += SPCA561_OFFSET_DATA; 821 data += SPCA561_OFFSET_DATA;
811 len -= SPCA561_OFFSET_DATA; 822 len -= SPCA561_OFFSET_DATA;
812 if (data[1] & 0x10) { 823 if (data[1] & 0x10) {
@@ -944,10 +955,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
944 struct sd *sd = (struct sd *) gspca_dev; 955 struct sd *sd = (struct sd *) gspca_dev;
945 956
946 sd->autogain = val; 957 sd->autogain = val;
947 if (val) 958 if (gspca_dev->streaming)
948 sd->ag_cnt = AG_CNT_START; 959 setautogain(gspca_dev);
949 else
950 sd->ag_cnt = -1;
951 return 0; 960 return 0;
952} 961}
953 962
@@ -971,6 +980,7 @@ static const struct sd_desc sd_desc = {
971 .stop0 = sd_stop0, 980 .stop0 = sd_stop0,
972 .close = sd_close, 981 .close = sd_close,
973 .pkt_scan = sd_pkt_scan, 982 .pkt_scan = sd_pkt_scan,
983 .dq_callback = do_autogain,
974}; 984};
975 985
976/* -- module initialisation -- */ 986/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index a4221753e1bf..f4a52956e0d9 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -88,12 +88,12 @@ static struct ctrl sd_ctrls[] = {
88 88
89static struct v4l2_pix_format vc0321_mode[] = { 89static struct v4l2_pix_format vc0321_mode[] = {
90 {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, 90 {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
91 .bytesperline = 320 * 2, 91 .bytesperline = 320,
92 .sizeimage = 320 * 240 * 2, 92 .sizeimage = 320 * 240 * 2,
93 .colorspace = V4L2_COLORSPACE_SRGB, 93 .colorspace = V4L2_COLORSPACE_SRGB,
94 .priv = 1}, 94 .priv = 1},
95 {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, 95 {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
96 .bytesperline = 640 * 2, 96 .bytesperline = 640,
97 .sizeimage = 640 * 480 * 2, 97 .sizeimage = 640 * 480 * 2,
98 .colorspace = V4L2_COLORSPACE_SRGB, 98 .colorspace = V4L2_COLORSPACE_SRGB,
99 .priv = 0}, 99 .priv = 0},
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 22a994ccb1d5..bc7d0eedcd81 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -6469,7 +6469,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6469 NULL, Tgradient_1, Tgradient_2, 6469 NULL, Tgradient_1, Tgradient_2,
6470 Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 6470 Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6
6471 }; 6471 };
6472#ifdef CONFIG_VIDEO_ADV_DEBUG 6472#ifdef GSPCA_DEBUG
6473 __u8 v[16]; 6473 __u8 v[16];
6474#endif 6474#endif
6475 6475
@@ -6487,7 +6487,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6487 else if (g <= 0) 6487 else if (g <= 0)
6488 g = 1; 6488 g = 1;
6489 reg_w(dev, g, 0x0120 + i); /* gamma */ 6489 reg_w(dev, g, 0x0120 + i); /* gamma */
6490#ifdef CONFIG_VIDEO_ADV_DEBUG 6490#ifdef GSPCA_DEBUG
6491 if (gspca_debug & D_CONF) 6491 if (gspca_debug & D_CONF)
6492 v[i] = g; 6492 v[i] = g;
6493#endif 6493#endif
@@ -6507,7 +6507,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6507 g = 1; 6507 g = 1;
6508 } 6508 }
6509 reg_w(dev, g, 0x0130 + i); /* gradient */ 6509 reg_w(dev, g, 0x0130 + i); /* gradient */
6510#ifdef CONFIG_VIDEO_ADV_DEBUG 6510#ifdef GSPCA_DEBUG
6511 if (gspca_debug & D_CONF) 6511 if (gspca_debug & D_CONF)
6512 v[i] = g; 6512 v[i] = g;
6513#endif 6513#endif
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 5e7ebca1968e..388cf94055d3 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -128,6 +128,8 @@ struct pxa_camera_dev {
128 128
129 struct pxa_buffer *active; 129 struct pxa_buffer *active;
130 struct pxa_dma_desc *sg_tail[3]; 130 struct pxa_dma_desc *sg_tail[3];
131
132 u32 save_cicr[5];
131}; 133};
132 134
133static const char *pxa_cam_driver_description = "PXA_Camera"; 135static const char *pxa_cam_driver_description = "PXA_Camera";
@@ -997,10 +999,64 @@ static int pxa_camera_querycap(struct soc_camera_host *ici,
997 return 0; 999 return 0;
998} 1000}
999 1001
1002static int pxa_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
1003{
1004 struct soc_camera_host *ici =
1005 to_soc_camera_host(icd->dev.parent);
1006 struct pxa_camera_dev *pcdev = ici->priv;
1007 int i = 0, ret = 0;
1008
1009 pcdev->save_cicr[i++] = CICR0;
1010 pcdev->save_cicr[i++] = CICR1;
1011 pcdev->save_cicr[i++] = CICR2;
1012 pcdev->save_cicr[i++] = CICR3;
1013 pcdev->save_cicr[i++] = CICR4;
1014
1015 if ((pcdev->icd) && (pcdev->icd->ops->suspend))
1016 ret = pcdev->icd->ops->suspend(pcdev->icd, state);
1017
1018 return ret;
1019}
1020
1021static int pxa_camera_resume(struct soc_camera_device *icd)
1022{
1023 struct soc_camera_host *ici =
1024 to_soc_camera_host(icd->dev.parent);
1025 struct pxa_camera_dev *pcdev = ici->priv;
1026 int i = 0, ret = 0;
1027
1028 DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD;
1029 DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD;
1030 DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD;
1031
1032 CICR0 = pcdev->save_cicr[i++] & ~CICR0_ENB;
1033 CICR1 = pcdev->save_cicr[i++];
1034 CICR2 = pcdev->save_cicr[i++];
1035 CICR3 = pcdev->save_cicr[i++];
1036 CICR4 = pcdev->save_cicr[i++];
1037
1038 if ((pcdev->icd) && (pcdev->icd->ops->resume))
1039 ret = pcdev->icd->ops->resume(pcdev->icd);
1040
1041 /* Restart frame capture if active buffer exists */
1042 if (!ret && pcdev->active) {
1043 /* Reset the FIFOs */
1044 CIFR |= CIFR_RESET_F;
1045 /* Enable End-Of-Frame Interrupt */
1046 CICR0 &= ~CICR0_EOFM;
1047 /* Restart the Capture Interface */
1048 CICR0 |= CICR0_ENB;
1049 }
1050
1051 return ret;
1052}
1053
1000static struct soc_camera_host_ops pxa_soc_camera_host_ops = { 1054static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
1001 .owner = THIS_MODULE, 1055 .owner = THIS_MODULE,
1002 .add = pxa_camera_add_device, 1056 .add = pxa_camera_add_device,
1003 .remove = pxa_camera_remove_device, 1057 .remove = pxa_camera_remove_device,
1058 .suspend = pxa_camera_suspend,
1059 .resume = pxa_camera_resume,
1004 .set_fmt_cap = pxa_camera_set_fmt_cap, 1060 .set_fmt_cap = pxa_camera_set_fmt_cap,
1005 .try_fmt_cap = pxa_camera_try_fmt_cap, 1061 .try_fmt_cap = pxa_camera_try_fmt_cap,
1006 .init_videobuf = pxa_camera_init_videobuf, 1062 .init_videobuf = pxa_camera_init_videobuf,
@@ -1198,7 +1254,7 @@ static int __devinit pxa_camera_init(void)
1198 1254
1199static void __exit pxa_camera_exit(void) 1255static void __exit pxa_camera_exit(void)
1200{ 1256{
1201 return platform_driver_unregister(&pxa_camera_driver); 1257 platform_driver_unregister(&pxa_camera_driver);
1202} 1258}
1203 1259
1204module_init(pxa_camera_init); 1260module_init(pxa_camera_init);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index f7ca3cb9340a..318754e73132 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -647,7 +647,7 @@ static int __init sh_mobile_ceu_init(void)
647 647
648static void __exit sh_mobile_ceu_exit(void) 648static void __exit sh_mobile_ceu_exit(void)
649{ 649{
650 return platform_driver_unregister(&sh_mobile_ceu_driver); 650 platform_driver_unregister(&sh_mobile_ceu_driver);
651} 651}
652 652
653module_init(sh_mobile_ceu_init); 653module_init(sh_mobile_ceu_init);
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index b6be5ee678b6..66ebe5956a87 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -732,10 +732,36 @@ static int soc_camera_remove(struct device *dev)
732 return 0; 732 return 0;
733} 733}
734 734
735static int soc_camera_suspend(struct device *dev, pm_message_t state)
736{
737 struct soc_camera_device *icd = to_soc_camera_dev(dev);
738 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
739 int ret = 0;
740
741 if (ici->ops->suspend)
742 ret = ici->ops->suspend(icd, state);
743
744 return ret;
745}
746
747static int soc_camera_resume(struct device *dev)
748{
749 struct soc_camera_device *icd = to_soc_camera_dev(dev);
750 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
751 int ret = 0;
752
753 if (ici->ops->resume)
754 ret = ici->ops->resume(icd);
755
756 return ret;
757}
758
735static struct bus_type soc_camera_bus_type = { 759static struct bus_type soc_camera_bus_type = {
736 .name = "soc-camera", 760 .name = "soc-camera",
737 .probe = soc_camera_probe, 761 .probe = soc_camera_probe,
738 .remove = soc_camera_remove, 762 .remove = soc_camera_remove,
763 .suspend = soc_camera_suspend,
764 .resume = soc_camera_resume,
739}; 765};
740 766
741static struct device_driver ic_drv = { 767static struct device_driver ic_drv = {
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index eefb0327ebb6..1adc257ebdb9 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -187,7 +187,7 @@ static int __init soc_camera_platform_module_init(void)
187 187
188static void __exit soc_camera_platform_module_exit(void) 188static void __exit soc_camera_platform_module_exit(void)
189{ 189{
190 return platform_driver_unregister(&soc_camera_platform_driver); 190 platform_driver_unregister(&soc_camera_platform_driver);
191} 191}
192 192
193module_init(soc_camera_platform_module_init); 193module_init(soc_camera_platform_module_init);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 626f4ad7e876..6ef3e5297de8 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -585,13 +585,17 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
585 struct uvc_control_mapping *mapping; 585 struct uvc_control_mapping *mapping;
586 struct uvc_menu_info *menu; 586 struct uvc_menu_info *menu;
587 unsigned int i; 587 unsigned int i;
588 __u8 data[8]; 588 __u8 *data;
589 int ret; 589 int ret;
590 590
591 ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); 591 ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping);
592 if (ctrl == NULL) 592 if (ctrl == NULL)
593 return -EINVAL; 593 return -EINVAL;
594 594
595 data = kmalloc(8, GFP_KERNEL);
596 if (data == NULL)
597 return -ENOMEM;
598
595 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); 599 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
596 v4l2_ctrl->id = mapping->id; 600 v4l2_ctrl->id = mapping->id;
597 v4l2_ctrl->type = mapping->v4l2_type; 601 v4l2_ctrl->type = mapping->v4l2_type;
@@ -604,8 +608,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
604 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { 608 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
605 if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, 609 if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id,
606 video->dev->intfnum, ctrl->info->selector, 610 video->dev->intfnum, ctrl->info->selector,
607 &data, ctrl->info->size)) < 0) 611 data, ctrl->info->size)) < 0)
608 return ret; 612 goto out;
609 v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); 613 v4l2_ctrl->default_value = uvc_get_le_value(data, mapping);
610 } 614 }
611 615
@@ -623,13 +627,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
623 } 627 }
624 } 628 }
625 629
626 return 0; 630 ret = 0;
631 goto out;
627 632
628 case V4L2_CTRL_TYPE_BOOLEAN: 633 case V4L2_CTRL_TYPE_BOOLEAN:
629 v4l2_ctrl->minimum = 0; 634 v4l2_ctrl->minimum = 0;
630 v4l2_ctrl->maximum = 1; 635 v4l2_ctrl->maximum = 1;
631 v4l2_ctrl->step = 1; 636 v4l2_ctrl->step = 1;
632 return 0; 637 ret = 0;
638 goto out;
633 639
634 default: 640 default:
635 break; 641 break;
@@ -638,26 +644,29 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
638 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { 644 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
639 if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, 645 if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id,
640 video->dev->intfnum, ctrl->info->selector, 646 video->dev->intfnum, ctrl->info->selector,
641 &data, ctrl->info->size)) < 0) 647 data, ctrl->info->size)) < 0)
642 return ret; 648 goto out;
643 v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); 649 v4l2_ctrl->minimum = uvc_get_le_value(data, mapping);
644 } 650 }
645 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { 651 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
646 if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, 652 if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id,
647 video->dev->intfnum, ctrl->info->selector, 653 video->dev->intfnum, ctrl->info->selector,
648 &data, ctrl->info->size)) < 0) 654 data, ctrl->info->size)) < 0)
649 return ret; 655 goto out;
650 v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); 656 v4l2_ctrl->maximum = uvc_get_le_value(data, mapping);
651 } 657 }
652 if (ctrl->info->flags & UVC_CONTROL_GET_RES) { 658 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
653 if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, 659 if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id,
654 video->dev->intfnum, ctrl->info->selector, 660 video->dev->intfnum, ctrl->info->selector,
655 &data, ctrl->info->size)) < 0) 661 data, ctrl->info->size)) < 0)
656 return ret; 662 goto out;
657 v4l2_ctrl->step = uvc_get_le_value(data, mapping); 663 v4l2_ctrl->step = uvc_get_le_value(data, mapping);
658 } 664 }
659 665
660 return 0; 666 ret = 0;
667out:
668 kfree(data);
669 return ret;
661} 670}
662 671
663 672
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index b3c4d75e8490..7e102034d38d 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1884,7 +1884,7 @@ static struct usb_device_id uvc_ids[] = {
1884 .bInterfaceSubClass = 1, 1884 .bInterfaceSubClass = 1,
1885 .bInterfaceProtocol = 0, 1885 .bInterfaceProtocol = 0,
1886 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1886 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1887 /* Packard Bell OEM Webcam */ 1887 /* Packard Bell OEM Webcam - Bison Electronics */
1888 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1888 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1889 | USB_DEVICE_ID_MATCH_INT_INFO, 1889 | USB_DEVICE_ID_MATCH_INT_INFO,
1890 .idVendor = 0x5986, 1890 .idVendor = 0x5986,
@@ -1893,7 +1893,7 @@ static struct usb_device_id uvc_ids[] = {
1893 .bInterfaceSubClass = 1, 1893 .bInterfaceSubClass = 1,
1894 .bInterfaceProtocol = 0, 1894 .bInterfaceProtocol = 0,
1895 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1895 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1896 /* Acer Crystal Eye webcam */ 1896 /* Acer Crystal Eye webcam - Bison Electronics */
1897 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1897 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1898 | USB_DEVICE_ID_MATCH_INT_INFO, 1898 | USB_DEVICE_ID_MATCH_INT_INFO,
1899 .idVendor = 0x5986, 1899 .idVendor = 0x5986,
@@ -1902,7 +1902,7 @@ static struct usb_device_id uvc_ids[] = {
1902 .bInterfaceSubClass = 1, 1902 .bInterfaceSubClass = 1,
1903 .bInterfaceProtocol = 0, 1903 .bInterfaceProtocol = 0,
1904 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1904 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1905 /* Medion Akoya Mini E1210 */ 1905 /* Medion Akoya Mini E1210 - Bison Electronics */
1906 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1906 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1907 | USB_DEVICE_ID_MATCH_INT_INFO, 1907 | USB_DEVICE_ID_MATCH_INT_INFO,
1908 .idVendor = 0x5986, 1908 .idVendor = 0x5986,
@@ -1911,7 +1911,7 @@ static struct usb_device_id uvc_ids[] = {
1911 .bInterfaceSubClass = 1, 1911 .bInterfaceSubClass = 1,
1912 .bInterfaceProtocol = 0, 1912 .bInterfaceProtocol = 0,
1913 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1913 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1914 /* Acer OrbiCam - Unknown vendor */ 1914 /* Acer OrbiCam - Bison Electronics */
1915 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1915 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1916 | USB_DEVICE_ID_MATCH_INT_INFO, 1916 | USB_DEVICE_ID_MATCH_INT_INFO,
1917 .idVendor = 0x5986, 1917 .idVendor = 0x5986,
@@ -1920,6 +1920,24 @@ static struct usb_device_id uvc_ids[] = {
1920 .bInterfaceSubClass = 1, 1920 .bInterfaceSubClass = 1,
1921 .bInterfaceProtocol = 0, 1921 .bInterfaceProtocol = 0,
1922 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1922 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1923 /* Bison Electronics */
1924 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1925 | USB_DEVICE_ID_MATCH_INT_INFO,
1926 .idVendor = 0x5986,
1927 .idProduct = 0x0300,
1928 .bInterfaceClass = USB_CLASS_VIDEO,
1929 .bInterfaceSubClass = 1,
1930 .bInterfaceProtocol = 0,
1931 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1932 /* Clevo M570TU - Bison Electronics */
1933 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1934 | USB_DEVICE_ID_MATCH_INT_INFO,
1935 .idVendor = 0x5986,
1936 .idProduct = 0x0303,
1937 .bInterfaceClass = USB_CLASS_VIDEO,
1938 .bInterfaceSubClass = 1,
1939 .bInterfaceProtocol = 0,
1940 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1923 /* Generic USB Video Class */ 1941 /* Generic USB Video Class */
1924 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, 1942 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
1925 {} 1943 {}
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index ad63794fda77..6854ac78a161 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -90,17 +90,20 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video,
90static int uvc_get_video_ctrl(struct uvc_video_device *video, 90static int uvc_get_video_ctrl(struct uvc_video_device *video,
91 struct uvc_streaming_control *ctrl, int probe, __u8 query) 91 struct uvc_streaming_control *ctrl, int probe, __u8 query)
92{ 92{
93 __u8 data[34]; 93 __u8 *data;
94 __u8 size; 94 __u16 size;
95 int ret; 95 int ret;
96 96
97 size = video->dev->uvc_version >= 0x0110 ? 34 : 26; 97 size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
98 data = kmalloc(size, GFP_KERNEL);
99 if (data == NULL)
100 return -ENOMEM;
101
98 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, 102 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
99 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, 103 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
100 UVC_CTRL_STREAMING_TIMEOUT); 104 UVC_CTRL_STREAMING_TIMEOUT);
101
102 if (ret < 0) 105 if (ret < 0)
103 return ret; 106 goto out;
104 107
105 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); 108 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
106 ctrl->bFormatIndex = data[2]; 109 ctrl->bFormatIndex = data[2];
@@ -136,17 +139,22 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
136 */ 139 */
137 uvc_fixup_buffer_size(video, ctrl); 140 uvc_fixup_buffer_size(video, ctrl);
138 141
139 return 0; 142out:
143 kfree(data);
144 return ret;
140} 145}
141 146
142int uvc_set_video_ctrl(struct uvc_video_device *video, 147int uvc_set_video_ctrl(struct uvc_video_device *video,
143 struct uvc_streaming_control *ctrl, int probe) 148 struct uvc_streaming_control *ctrl, int probe)
144{ 149{
145 __u8 data[34]; 150 __u8 *data;
146 __u8 size; 151 __u16 size;
152 int ret;
147 153
148 size = video->dev->uvc_version >= 0x0110 ? 34 : 26; 154 size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
149 memset(data, 0, sizeof data); 155 data = kzalloc(size, GFP_KERNEL);
156 if (data == NULL)
157 return -ENOMEM;
150 158
151 *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint); 159 *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint);
152 data[2] = ctrl->bFormatIndex; 160 data[2] = ctrl->bFormatIndex;
@@ -174,10 +182,13 @@ int uvc_set_video_ctrl(struct uvc_video_device *video,
174 data[33] = ctrl->bMaxVersion; 182 data[33] = ctrl->bMaxVersion;
175 } 183 }
176 184
177 return __uvc_query_ctrl(video->dev, SET_CUR, 0, 185 ret = __uvc_query_ctrl(video->dev, SET_CUR, 0,
178 video->streaming->intfnum, 186 video->streaming->intfnum,
179 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, 187 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
180 UVC_CTRL_STREAMING_TIMEOUT); 188 UVC_CTRL_STREAMING_TIMEOUT);
189
190 kfree(data);
191 return ret;
181} 192}
182 193
183int uvc_probe_video(struct uvc_video_device *video, 194int uvc_probe_video(struct uvc_video_device *video,
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 556615fe93de..6f36006aecda 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -222,11 +222,13 @@ int video_register_device(struct video_device *vfd, int type, int nr)
222EXPORT_SYMBOL(video_register_device); 222EXPORT_SYMBOL(video_register_device);
223 223
224/** 224/**
225 * video_register_device - register video4linux devices 225 * video_register_device_index - register video4linux devices
226 * @vfd: video device structure we want to register 226 * @vfd: video device structure we want to register
227 * @type: type of device to register 227 * @type: type of device to register
228 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... 228 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
229 * -1 == first free) 229 * -1 == first free)
230 * @index: stream number based on parent device;
231 * -1 if auto assign, requested number otherwise
230 * 232 *
231 * The registration code assigns minor numbers based on the type 233 * The registration code assigns minor numbers based on the type
232 * requested. -ENFILE is returned in all the device slots for this 234 * requested. -ENFILE is returned in all the device slots for this
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index ef7572cbc4ab..1edda456fc64 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -41,6 +41,7 @@
41#include <linux/videodev2.h> 41#include <linux/videodev2.h>
42#include <media/v4l2-ioctl.h> 42#include <media/v4l2-ioctl.h>
43#include <media/v4l2-common.h> 43#include <media/v4l2-common.h>
44#include <media/v4l2-ioctl.h>
44#include <linux/video_decoder.h> 45#include <linux/video_decoder.h>
45#include <linux/mutex.h> 46#include <linux/mutex.h>
46 47