aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/Kconfig23
-rw-r--r--drivers/media/video/gspca/Makefile4
-rw-r--r--drivers/media/video/gspca/conex.c2
-rw-r--r--drivers/media/video/gspca/etoms.c4
-rw-r--r--drivers/media/video/gspca/finepix.c5
-rw-r--r--drivers/media/video/gspca/gspca.c210
-rw-r--r--drivers/media/video/gspca/gspca.h25
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h119
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c100
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c135
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h14
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c316
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h195
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c166
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h10
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c235
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h47
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c213
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h25
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h14
-rw-r--r--drivers/media/video/gspca/mars.c4
-rw-r--r--drivers/media/video/gspca/ov519.c172
-rw-r--r--drivers/media/video/gspca/ov534.c601
-rw-r--r--drivers/media/video/gspca/pac207.c8
-rw-r--r--drivers/media/video/gspca/pac7311.c5
-rw-r--r--drivers/media/video/gspca/sonixb.c25
-rw-r--r--drivers/media/video/gspca/sonixj.c508
-rw-r--r--drivers/media/video/gspca/spca500.c8
-rw-r--r--drivers/media/video/gspca/spca501.c148
-rw-r--r--drivers/media/video/gspca/spca505.c2
-rw-r--r--drivers/media/video/gspca/spca506.c2
-rw-r--r--drivers/media/video/gspca/spca508.c2
-rw-r--r--drivers/media/video/gspca/spca561.c522
-rw-r--r--drivers/media/video/gspca/stk014.c8
-rw-r--r--drivers/media/video/gspca/stv06xx/Kconfig9
-rw-r--r--drivers/media/video/gspca/stv06xx/Makefile9
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c522
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.h107
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c535
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h263
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c430
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h275
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h92
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c251
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h315
-rw-r--r--drivers/media/video/gspca/sunplus.c6
-rw-r--r--drivers/media/video/gspca/t613.c4
-rw-r--r--drivers/media/video/gspca/tv8532.c142
-rw-r--r--drivers/media/video/gspca/vc032x.c819
-rw-r--r--drivers/media/video/gspca/zc3xx-reg.h8
-rw-r--r--drivers/media/video/gspca/zc3xx.c1012
51 files changed, 6358 insertions, 2318 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 6b557c057fac..ee6a691dff22 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -12,12 +12,13 @@ menuconfig USB_GSPCA
12 "Video For Linux" to use this driver. 12 "Video For Linux" to use this driver.
13 13
14 To compile this driver as modules, choose M here: the 14 To compile this driver as modules, choose M here: the
15 modules will be called gspca_main. 15 module will be called gspca_main.
16 16
17 17
18if USB_GSPCA && VIDEO_V4L2 18if USB_GSPCA && VIDEO_V4L2
19 19
20source "drivers/media/video/gspca/m5602/Kconfig" 20source "drivers/media/video/gspca/m5602/Kconfig"
21source "drivers/media/video/gspca/stv06xx/Kconfig"
21 22
22config USB_GSPCA_CONEX 23config USB_GSPCA_CONEX
23 tristate "Conexant Camera Driver" 24 tristate "Conexant Camera Driver"
@@ -64,6 +65,16 @@ config USB_GSPCA_OV519
64 To compile this driver as a module, choose M here: the 65 To compile this driver as a module, choose M here: the
65 module will be called gspca_ov519. 66 module will be called gspca_ov519.
66 67
68config USB_GSPCA_OV534
69 tristate "OV534 USB Camera Driver"
70 depends on VIDEO_V4L2 && USB_GSPCA
71 help
72 Say Y here if you want support for cameras based on the OV534 chip.
73 (e.g. Sony Playstation EYE)
74
75 To compile this driver as a module, choose M here: the
76 module will be called gspca_ov534.
77
67config USB_GSPCA_PAC207 78config USB_GSPCA_PAC207
68 tristate "Pixart PAC207 USB Camera Driver" 79 tristate "Pixart PAC207 USB Camera Driver"
69 depends on VIDEO_V4L2 && USB_GSPCA 80 depends on VIDEO_V4L2 && USB_GSPCA
@@ -83,10 +94,11 @@ config USB_GSPCA_PAC7311
83 module will be called gspca_pac7311. 94 module will be called gspca_pac7311.
84 95
85config USB_GSPCA_SONIXB 96config USB_GSPCA_SONIXB
86 tristate "SN9C102 USB Camera Driver" 97 tristate "SONIX Bayer USB Camera Driver"
87 depends on VIDEO_V4L2 && USB_GSPCA 98 depends on VIDEO_V4L2 && USB_GSPCA
88 help 99 help
89 Say Y here if you want support for cameras based on the SONIXB chip. 100 Say Y here if you want support for cameras based on the Sonix
101 chips with Bayer format (SN9C101, SN9C102 and SN9C103).
90 102
91 To compile this driver as a module, choose M here: the 103 To compile this driver as a module, choose M here: the
92 module will be called gspca_sonixb. 104 module will be called gspca_sonixb.
@@ -95,7 +107,8 @@ config USB_GSPCA_SONIXJ
95 tristate "SONIX JPEG USB Camera Driver" 107 tristate "SONIX JPEG USB Camera Driver"
96 depends on VIDEO_V4L2 && USB_GSPCA 108 depends on VIDEO_V4L2 && USB_GSPCA
97 help 109 help
98 Say Y here if you want support for cameras based on the SONIXJ chip. 110 Say Y here if you want support for cameras based on the Sonix
111 chips with JPEG format (SN9C102P, SN9C105 and >= SN9C110).
99 112
100 To compile this driver as a module, choose M here: the 113 To compile this driver as a module, choose M here: the
101 module will be called gspca_sonixj 114 module will be called gspca_sonixj
@@ -171,7 +184,7 @@ config USB_GSPCA_SUNPLUS
171 SPCA504(abc) SPCA533 SPCA536 chips. 184 SPCA504(abc) SPCA533 SPCA536 chips.
172 185
173 To compile this driver as a module, choose M here: the 186 To compile this driver as a module, choose M here: the
174 module will be called gspca_spca5xx. 187 module will be called gspca_sunplus.
175 188
176config USB_GSPCA_T613 189config USB_GSPCA_T613
177 tristate "T613 (JPEG Compliance) USB Camera Driver" 190 tristate "T613 (JPEG Compliance) USB Camera Driver"
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 22734f5a6c32..bd8d9ee40504 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
4obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o 4obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
5obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o 5obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
6obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 6obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
7obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
7obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o 8obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
8obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o 9obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
9obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o 10obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
@@ -27,6 +28,7 @@ gspca_etoms-objs := etoms.o
27gspca_finepix-objs := finepix.o 28gspca_finepix-objs := finepix.o
28gspca_mars-objs := mars.o 29gspca_mars-objs := mars.o
29gspca_ov519-objs := ov519.o 30gspca_ov519-objs := ov519.o
31gspca_ov534-objs := ov534.o
30gspca_pac207-objs := pac207.o 32gspca_pac207-objs := pac207.o
31gspca_pac7311-objs := pac7311.o 33gspca_pac7311-objs := pac7311.o
32gspca_sonixb-objs := sonixb.o 34gspca_sonixb-objs := sonixb.o
@@ -45,4 +47,4 @@ gspca_vc032x-objs := vc032x.o
45gspca_zc3xx-objs := zc3xx.o 47gspca_zc3xx-objs := zc3xx.o
46 48
47obj-$(CONFIG_USB_M5602) += m5602/ 49obj-$(CONFIG_USB_M5602) += m5602/
48 50obj-$(CONFIG_USB_STV06XX) += stv06xx/
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index de28354ea5ba..1753f5bb3544 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -93,7 +93,7 @@ static struct ctrl sd_ctrls[] = {
93 }, 93 },
94}; 94};
95 95
96static struct v4l2_pix_format vga_mode[] = { 96static const struct v4l2_pix_format vga_mode[] = {
97 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 97 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
98 .bytesperline = 176, 98 .bytesperline = 176,
99 .sizeimage = 176 * 144 * 3 / 8 + 590, 99 .sizeimage = 176 * 144 * 3 / 8 + 590,
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 3be30b420a26..f3cd8ff5cc92 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -112,7 +112,7 @@ static struct ctrl sd_ctrls[] = {
112 }, 112 },
113}; 113};
114 114
115static struct v4l2_pix_format vga_mode[] = { 115static const struct v4l2_pix_format vga_mode[] = {
116 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 116 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
117 .bytesperline = 320, 117 .bytesperline = 320,
118 .sizeimage = 320 * 240, 118 .sizeimage = 320 * 240,
@@ -125,7 +125,7 @@ static struct v4l2_pix_format vga_mode[] = {
125 .priv = 0}, */ 125 .priv = 0}, */
126}; 126};
127 127
128static struct v4l2_pix_format sif_mode[] = { 128static const struct v4l2_pix_format sif_mode[] = {
129 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 129 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
130 .bytesperline = 176, 130 .bytesperline = 176,
131 .sizeimage = 176 * 144, 131 .sizeimage = 176 * 144,
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 607942fd7970..afc8b2dd307b 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -72,7 +72,7 @@ struct usb_fpix {
72} 72}
73 73
74/* These cameras only support 320x200. */ 74/* These cameras only support 320x200. */
75static struct v4l2_pix_format fpix_mode[1] = { 75static const struct v4l2_pix_format fpix_mode[1] = {
76 { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 76 { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
77 .bytesperline = 320, 77 .bytesperline = 320,
78 .sizeimage = 320 * 240 * 3 / 8 + 590, 78 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -314,9 +314,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
314 int ret; 314 int ret;
315 int size_ret; 315 int size_ret;
316 316
317 /* Reset bulk in endpoint */
318 usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
319
320 /* Init the device */ 317 /* Init the device */
321 memset(gspca_dev->usb_buf, 0, 12); 318 memset(gspca_dev->usb_buf, 0, 12);
322 gspca_dev->usb_buf[0] = 0xc6; 319 gspca_dev->usb_buf[0] = 0xc6;
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 02a6e9ef0337..8b9f3bde5740 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -30,7 +30,6 @@
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/pagemap.h> 31#include <linux/pagemap.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/kref.h>
34#include <asm/page.h> 33#include <asm/page.h>
35#include <linux/uaccess.h> 34#include <linux/uaccess.h>
36#include <linux/jiffies.h> 35#include <linux/jiffies.h>
@@ -45,7 +44,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
45MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 44MODULE_DESCRIPTION("GSPCA USB Camera Driver");
46MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
47 46
48#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 3, 0) 47#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0)
49 48
50static int video_nr = -1; 49static int video_nr = -1;
51 50
@@ -150,8 +149,11 @@ static void fill_frame(struct gspca_dev *gspca_dev,
150 149
151 /* check the packet status and length */ 150 /* check the packet status and length */
152 len = urb->iso_frame_desc[i].actual_length; 151 len = urb->iso_frame_desc[i].actual_length;
153 if (len == 0) 152 if (len == 0) {
153 if (gspca_dev->empty_packet == 0)
154 gspca_dev->empty_packet = 1;
154 continue; 155 continue;
156 }
155 st = urb->iso_frame_desc[i].status; 157 st = urb->iso_frame_desc[i].status;
156 if (st) { 158 if (st) {
157 PDEBUG(D_ERR, 159 PDEBUG(D_ERR,
@@ -170,7 +172,6 @@ static void fill_frame(struct gspca_dev *gspca_dev,
170 } 172 }
171 173
172 /* resubmit the URB */ 174 /* resubmit the URB */
173 urb->status = 0;
174 st = usb_submit_urb(urb, GFP_ATOMIC); 175 st = usb_submit_urb(urb, GFP_ATOMIC);
175 if (st < 0) 176 if (st < 0)
176 PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st); 177 PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st);
@@ -200,11 +201,18 @@ static void bulk_irq(struct urb *urb
200{ 201{
201 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; 202 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
202 struct gspca_frame *frame; 203 struct gspca_frame *frame;
204 int st;
203 205
204 PDEBUG(D_PACK, "bulk irq"); 206 PDEBUG(D_PACK, "bulk irq");
205 if (!gspca_dev->streaming) 207 if (!gspca_dev->streaming)
206 return; 208 return;
207 if (urb->status != 0 && urb->status != -ECONNRESET) { 209 switch (urb->status) {
210 case 0:
211 break;
212 case -ECONNRESET:
213 urb->status = 0;
214 break;
215 default:
208#ifdef CONFIG_PM 216#ifdef CONFIG_PM
209 if (!gspca_dev->frozen) 217 if (!gspca_dev->frozen)
210#endif 218#endif
@@ -223,6 +231,13 @@ static void bulk_irq(struct urb *urb
223 urb->transfer_buffer, 231 urb->transfer_buffer,
224 urb->actual_length); 232 urb->actual_length);
225 } 233 }
234
235 /* resubmit the URB */
236 if (gspca_dev->cam.bulk_nurbs != 0) {
237 st = usb_submit_urb(urb, GFP_ATOMIC);
238 if (st < 0)
239 PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st);
240 }
226} 241}
227 242
228/* 243/*
@@ -285,7 +300,6 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
285 frame->v4l2_buf.bytesused = frame->data_end - frame->data; 300 frame->v4l2_buf.bytesused = frame->data_end - frame->data;
286 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; 301 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
287 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; 302 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
288 atomic_inc(&gspca_dev->nevent);
289 wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ 303 wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
290 i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; 304 i = (gspca_dev->fr_i + 1) % gspca_dev->nframes;
291 gspca_dev->fr_i = i; 305 gspca_dev->fr_i = i;
@@ -379,7 +393,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
379 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; 393 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
380 gspca_dev->last_packet_type = DISCARD_PACKET; 394 gspca_dev->last_packet_type = DISCARD_PACKET;
381 gspca_dev->sequence = 0; 395 gspca_dev->sequence = 0;
382 atomic_set(&gspca_dev->nevent, 0);
383 return 0; 396 return 0;
384} 397}
385 398
@@ -520,11 +533,14 @@ static int create_urbs(struct gspca_dev *gspca_dev,
520 nurbs = DEF_NURBS; 533 nurbs = DEF_NURBS;
521 } else { /* bulk */ 534 } else { /* bulk */
522 npkt = 0; 535 npkt = 0;
523 bsize = gspca_dev->cam. bulk_size; 536 bsize = gspca_dev->cam.bulk_size;
524 if (bsize == 0) 537 if (bsize == 0)
525 bsize = psize; 538 bsize = psize;
526 PDEBUG(D_STREAM, "bulk bsize:%d", bsize); 539 PDEBUG(D_STREAM, "bulk bsize:%d", bsize);
527 nurbs = 1; 540 if (gspca_dev->cam.bulk_nurbs != 0)
541 nurbs = gspca_dev->cam.bulk_nurbs;
542 else
543 nurbs = 1;
528 } 544 }
529 545
530 gspca_dev->nurbs = nurbs; 546 gspca_dev->nurbs = nurbs;
@@ -597,6 +613,12 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
597 if (ret < 0) 613 if (ret < 0)
598 goto out; 614 goto out;
599 615
616 /* clear the bulk endpoint */
617 if (gspca_dev->alt == 0) /* if bulk transfer */
618 usb_clear_halt(gspca_dev->dev,
619 usb_rcvintpipe(gspca_dev->dev,
620 gspca_dev->cam.epaddr));
621
600 /* start the cam */ 622 /* start the cam */
601 ret = gspca_dev->sd_desc->start(gspca_dev); 623 ret = gspca_dev->sd_desc->start(gspca_dev);
602 if (ret < 0) { 624 if (ret < 0) {
@@ -604,10 +626,9 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
604 goto out; 626 goto out;
605 } 627 }
606 gspca_dev->streaming = 1; 628 gspca_dev->streaming = 1;
607 atomic_set(&gspca_dev->nevent, 0);
608 629
609 /* bulk transfers are started by the subdriver */ 630 /* some bulk transfers are started by the subdriver */
610 if (gspca_dev->alt == 0) 631 if (gspca_dev->alt == 0 && gspca_dev->cam.bulk_nurbs == 0)
611 break; 632 break;
612 633
613 /* submit the URBs */ 634 /* submit the URBs */
@@ -618,8 +639,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
618 "usb_submit_urb [%d] err %d", n, ret); 639 "usb_submit_urb [%d] err %d", n, ret);
619 gspca_dev->streaming = 0; 640 gspca_dev->streaming = 0;
620 destroy_urbs(gspca_dev); 641 destroy_urbs(gspca_dev);
621 if (ret == -ENOSPC) 642 if (ret == -ENOSPC) {
643 msleep(20); /* wait for kill
644 * complete */
622 break; /* try the previous alt */ 645 break; /* try the previous alt */
646 }
623 goto out; 647 goto out;
624 } 648 }
625 } 649 }
@@ -637,7 +661,7 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
637 661
638 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); 662 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
639 if (ret < 0) 663 if (ret < 0)
640 PDEBUG(D_ERR|D_STREAM, "set interface 0 err %d", ret); 664 PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
641 return ret; 665 return ret;
642} 666}
643 667
@@ -645,7 +669,6 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
645static void gspca_stream_off(struct gspca_dev *gspca_dev) 669static void gspca_stream_off(struct gspca_dev *gspca_dev)
646{ 670{
647 gspca_dev->streaming = 0; 671 gspca_dev->streaming = 0;
648 atomic_set(&gspca_dev->nevent, 0);
649 if (gspca_dev->present 672 if (gspca_dev->present
650 && gspca_dev->sd_desc->stopN) 673 && gspca_dev->sd_desc->stopN)
651 gspca_dev->sd_desc->stopN(gspca_dev); 674 gspca_dev->sd_desc->stopN(gspca_dev);
@@ -727,7 +750,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
727 if (fmtdesc->index == index) 750 if (fmtdesc->index == index)
728 break; /* new format */ 751 break; /* new format */
729 index++; 752 index++;
730 if (index >= sizeof fmt_tb / sizeof fmt_tb[0]) 753 if (index >= ARRAY_SIZE(fmt_tb))
731 return -EINVAL; 754 return -EINVAL;
732 } 755 }
733 } 756 }
@@ -752,8 +775,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
752 struct gspca_dev *gspca_dev = priv; 775 struct gspca_dev *gspca_dev = priv;
753 int mode; 776 int mode;
754 777
755 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
756 return -EINVAL;
757 mode = gspca_dev->curr_mode; 778 mode = gspca_dev->curr_mode;
758 memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode], 779 memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode],
759 sizeof fmt->fmt.pix); 780 sizeof fmt->fmt.pix);
@@ -765,8 +786,6 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
765{ 786{
766 int w, h, mode, mode2; 787 int w, h, mode, mode2;
767 788
768 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
769 return -EINVAL;
770 w = fmt->fmt.pix.width; 789 w = fmt->fmt.pix.width;
771 h = fmt->fmt.pix.height; 790 h = fmt->fmt.pix.height;
772 791
@@ -846,11 +865,11 @@ out:
846 return ret; 865 return ret;
847} 866}
848 867
849static void gspca_delete(struct kref *kref) 868static void gspca_release(struct video_device *vfd)
850{ 869{
851 struct gspca_dev *gspca_dev = container_of(kref, struct gspca_dev, kref); 870 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
852 871
853 PDEBUG(D_STREAM, "device deleted"); 872 PDEBUG(D_STREAM, "device released");
854 873
855 kfree(gspca_dev->usb_buf); 874 kfree(gspca_dev->usb_buf);
856 kfree(gspca_dev); 875 kfree(gspca_dev);
@@ -862,7 +881,7 @@ static int dev_open(struct inode *inode, struct file *file)
862 int ret; 881 int ret;
863 882
864 PDEBUG(D_STREAM, "%s open", current->comm); 883 PDEBUG(D_STREAM, "%s open", current->comm);
865 gspca_dev = video_drvdata(file); 884 gspca_dev = (struct gspca_dev *) video_devdata(file);
866 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 885 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
867 return -ERESTARTSYS; 886 return -ERESTARTSYS;
868 if (!gspca_dev->present) { 887 if (!gspca_dev->present) {
@@ -883,17 +902,14 @@ static int dev_open(struct inode *inode, struct file *file)
883 902
884 gspca_dev->users++; 903 gspca_dev->users++;
885 904
886 /* one more user */
887 kref_get(&gspca_dev->kref);
888
889 file->private_data = gspca_dev; 905 file->private_data = gspca_dev;
890#ifdef GSPCA_DEBUG 906#ifdef GSPCA_DEBUG
891 /* activate the v4l2 debug */ 907 /* activate the v4l2 debug */
892 if (gspca_debug & D_V4L2) 908 if (gspca_debug & D_V4L2)
893 gspca_dev->vdev->debug |= V4L2_DEBUG_IOCTL 909 gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL
894 | V4L2_DEBUG_IOCTL_ARG; 910 | V4L2_DEBUG_IOCTL_ARG;
895 else 911 else
896 gspca_dev->vdev->debug &= ~(V4L2_DEBUG_IOCTL 912 gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
897 | V4L2_DEBUG_IOCTL_ARG); 913 | V4L2_DEBUG_IOCTL_ARG);
898#endif 914#endif
899 ret = 0; 915 ret = 0;
@@ -932,8 +948,6 @@ static int dev_close(struct inode *inode, struct file *file)
932 948
933 PDEBUG(D_STREAM, "close done"); 949 PDEBUG(D_STREAM, "close done");
934 950
935 kref_put(&gspca_dev->kref, gspca_delete);
936
937 return 0; 951 return 0;
938} 952}
939 953
@@ -1053,6 +1067,35 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1053 return -EINVAL; 1067 return -EINVAL;
1054} 1068}
1055 1069
1070/*fixme: have an audio flag in gspca_dev?*/
1071static int vidioc_s_audio(struct file *file, void *priv,
1072 struct v4l2_audio *audio)
1073{
1074 if (audio->index != 0)
1075 return -EINVAL;
1076 return 0;
1077}
1078
1079static int vidioc_g_audio(struct file *file, void *priv,
1080 struct v4l2_audio *audio)
1081{
1082 memset(audio, 0, sizeof *audio);
1083 strcpy(audio->name, "Microphone");
1084 return 0;
1085}
1086
1087static int vidioc_enumaudio(struct file *file, void *priv,
1088 struct v4l2_audio *audio)
1089{
1090 if (audio->index != 0)
1091 return -EINVAL;
1092
1093 strcpy(audio->name, "Microphone");
1094 audio->capability = 0;
1095 audio->mode = 0;
1096 return 0;
1097}
1098
1056static int vidioc_querymenu(struct file *file, void *priv, 1099static int vidioc_querymenu(struct file *file, void *priv,
1057 struct v4l2_querymenu *qmenu) 1100 struct v4l2_querymenu *qmenu)
1058{ 1101{
@@ -1096,8 +1139,6 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1096 struct gspca_dev *gspca_dev = priv; 1139 struct gspca_dev *gspca_dev = priv;
1097 int i, ret = 0; 1140 int i, ret = 0;
1098 1141
1099 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1100 return -EINVAL;
1101 switch (rb->memory) { 1142 switch (rb->memory) {
1102 case GSPCA_MEMORY_READ: /* (internal call) */ 1143 case GSPCA_MEMORY_READ: /* (internal call) */
1103 case V4L2_MEMORY_MMAP: 1144 case V4L2_MEMORY_MMAP:
@@ -1162,8 +1203,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
1162 struct gspca_dev *gspca_dev = priv; 1203 struct gspca_dev *gspca_dev = priv;
1163 struct gspca_frame *frame; 1204 struct gspca_frame *frame;
1164 1205
1165 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE 1206 if (v4l2_buf->index < 0
1166 || v4l2_buf->index < 0
1167 || v4l2_buf->index >= gspca_dev->nframes) 1207 || v4l2_buf->index >= gspca_dev->nframes)
1168 return -EINVAL; 1208 return -EINVAL;
1169 1209
@@ -1186,7 +1226,8 @@ static int vidioc_streamon(struct file *file, void *priv,
1186 ret = -ENODEV; 1226 ret = -ENODEV;
1187 goto out; 1227 goto out;
1188 } 1228 }
1189 if (gspca_dev->nframes == 0) { 1229 if (gspca_dev->nframes == 0
1230 || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {
1190 ret = -EINVAL; 1231 ret = -EINVAL;
1191 goto out; 1232 goto out;
1192 } 1233 }
@@ -1236,7 +1277,6 @@ static int vidioc_streamoff(struct file *file, void *priv,
1236 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; 1277 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
1237 gspca_dev->last_packet_type = DISCARD_PACKET; 1278 gspca_dev->last_packet_type = DISCARD_PACKET;
1238 gspca_dev->sequence = 0; 1279 gspca_dev->sequence = 0;
1239 atomic_set(&gspca_dev->nevent, 0);
1240 ret = 0; 1280 ret = 0;
1241out: 1281out:
1242 mutex_unlock(&gspca_dev->queue_lock); 1282 mutex_unlock(&gspca_dev->queue_lock);
@@ -1281,6 +1321,17 @@ static int vidioc_g_parm(struct file *filp, void *priv,
1281 memset(parm, 0, sizeof *parm); 1321 memset(parm, 0, sizeof *parm);
1282 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1322 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1283 parm->parm.capture.readbuffers = gspca_dev->nbufread; 1323 parm->parm.capture.readbuffers = gspca_dev->nbufread;
1324
1325 if (gspca_dev->sd_desc->get_streamparm) {
1326 int ret;
1327
1328 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1329 return -ERESTARTSYS;
1330 ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
1331 mutex_unlock(&gspca_dev->usb_lock);
1332 return ret;
1333 }
1334
1284 return 0; 1335 return 0;
1285} 1336}
1286 1337
@@ -1295,6 +1346,17 @@ static int vidioc_s_parm(struct file *filp, void *priv,
1295 parm->parm.capture.readbuffers = gspca_dev->nbufread; 1346 parm->parm.capture.readbuffers = gspca_dev->nbufread;
1296 else 1347 else
1297 gspca_dev->nbufread = n; 1348 gspca_dev->nbufread = n;
1349
1350 if (gspca_dev->sd_desc->set_streamparm) {
1351 int ret;
1352
1353 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1354 return -ERESTARTSYS;
1355 ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
1356 mutex_unlock(&gspca_dev->usb_lock);
1357 return ret;
1358 }
1359
1298 return 0; 1360 return 0;
1299} 1361}
1300 1362
@@ -1440,33 +1502,22 @@ static int frame_wait(struct gspca_dev *gspca_dev,
1440 i = gspca_dev->fr_o; 1502 i = gspca_dev->fr_o;
1441 j = gspca_dev->fr_queue[i]; 1503 j = gspca_dev->fr_queue[i];
1442 frame = &gspca_dev->frame[j]; 1504 frame = &gspca_dev->frame[j];
1443 if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) {
1444 atomic_dec(&gspca_dev->nevent);
1445 goto ok;
1446 }
1447 if (nonblock_ing) /* no frame yet */
1448 return -EAGAIN;
1449 1505
1450 /* wait till a frame is ready */ 1506 if (!(frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)) {
1451 for (;;) { 1507 if (nonblock_ing)
1508 return -EAGAIN;
1509
1510 /* wait till a frame is ready */
1452 ret = wait_event_interruptible_timeout(gspca_dev->wq, 1511 ret = wait_event_interruptible_timeout(gspca_dev->wq,
1453 atomic_read(&gspca_dev->nevent) > 0, 1512 (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) ||
1454 msecs_to_jiffies(3000)); 1513 !gspca_dev->streaming || !gspca_dev->present,
1455 if (ret <= 0) { 1514 msecs_to_jiffies(3000));
1456 if (ret < 0) 1515 if (ret < 0)
1457 return ret; /* interrupt */ 1516 return ret;
1458 return -EIO; /* timeout */ 1517 if (ret == 0 || !gspca_dev->streaming || !gspca_dev->present)
1459 }
1460 atomic_dec(&gspca_dev->nevent);
1461 if (!gspca_dev->streaming || !gspca_dev->present)
1462 return -EIO; 1518 return -EIO;
1463 i = gspca_dev->fr_o;
1464 j = gspca_dev->fr_queue[i];
1465 frame = &gspca_dev->frame[j];
1466 if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
1467 break;
1468 } 1519 }
1469ok: 1520
1470 gspca_dev->fr_o = (i + 1) % gspca_dev->nframes; 1521 gspca_dev->fr_o = (i + 1) % gspca_dev->nframes;
1471 PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d", 1522 PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d",
1472 gspca_dev->fr_q, 1523 gspca_dev->fr_q,
@@ -1494,8 +1545,6 @@ static int vidioc_dqbuf(struct file *file, void *priv,
1494 int i, ret; 1545 int i, ret;
1495 1546
1496 PDEBUG(D_FRAM, "dqbuf"); 1547 PDEBUG(D_FRAM, "dqbuf");
1497 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1498 return -EINVAL;
1499 if (v4l2_buf->memory != gspca_dev->memory) 1548 if (v4l2_buf->memory != gspca_dev->memory)
1500 return -EINVAL; 1549 return -EINVAL;
1501 1550
@@ -1550,8 +1599,6 @@ static int vidioc_qbuf(struct file *file, void *priv,
1550 int i, index, ret; 1599 int i, index, ret;
1551 1600
1552 PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index); 1601 PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index);
1553 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1554 return -EINVAL;
1555 1602
1556 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1603 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1557 return -ERESTARTSYS; 1604 return -ERESTARTSYS;
@@ -1761,7 +1808,7 @@ static struct file_operations dev_fops = {
1761 .release = dev_close, 1808 .release = dev_close,
1762 .read = dev_read, 1809 .read = dev_read,
1763 .mmap = dev_mmap, 1810 .mmap = dev_mmap,
1764 .ioctl = video_ioctl2, 1811 .unlocked_ioctl = __video_ioctl2,
1765#ifdef CONFIG_COMPAT 1812#ifdef CONFIG_COMPAT
1766 .compat_ioctl = v4l_compat_ioctl32, 1813 .compat_ioctl = v4l_compat_ioctl32,
1767#endif 1814#endif
@@ -1781,6 +1828,9 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
1781 .vidioc_queryctrl = vidioc_queryctrl, 1828 .vidioc_queryctrl = vidioc_queryctrl,
1782 .vidioc_g_ctrl = vidioc_g_ctrl, 1829 .vidioc_g_ctrl = vidioc_g_ctrl,
1783 .vidioc_s_ctrl = vidioc_s_ctrl, 1830 .vidioc_s_ctrl = vidioc_s_ctrl,
1831 .vidioc_g_audio = vidioc_g_audio,
1832 .vidioc_s_audio = vidioc_s_audio,
1833 .vidioc_enumaudio = vidioc_enumaudio,
1784 .vidioc_querymenu = vidioc_querymenu, 1834 .vidioc_querymenu = vidioc_querymenu,
1785 .vidioc_enum_input = vidioc_enum_input, 1835 .vidioc_enum_input = vidioc_enum_input,
1786 .vidioc_g_input = vidioc_g_input, 1836 .vidioc_g_input = vidioc_g_input,
@@ -1802,7 +1852,7 @@ static struct video_device gspca_template = {
1802 .name = "gspca main driver", 1852 .name = "gspca main driver",
1803 .fops = &dev_fops, 1853 .fops = &dev_fops,
1804 .ioctl_ops = &dev_ioctl_ops, 1854 .ioctl_ops = &dev_ioctl_ops,
1805 .release = video_device_release, 1855 .release = gspca_release,
1806 .minor = -1, 1856 .minor = -1,
1807}; 1857};
1808 1858
@@ -1840,7 +1890,6 @@ int gspca_dev_probe(struct usb_interface *intf,
1840 err("couldn't kzalloc gspca struct"); 1890 err("couldn't kzalloc gspca struct");
1841 return -ENOMEM; 1891 return -ENOMEM;
1842 } 1892 }
1843 kref_init(&gspca_dev->kref);
1844 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL); 1893 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
1845 if (!gspca_dev->usb_buf) { 1894 if (!gspca_dev->usb_buf) {
1846 err("out of memory"); 1895 err("out of memory");
@@ -1852,12 +1901,13 @@ int gspca_dev_probe(struct usb_interface *intf,
1852 gspca_dev->nbalt = intf->num_altsetting; 1901 gspca_dev->nbalt = intf->num_altsetting;
1853 gspca_dev->sd_desc = sd_desc; 1902 gspca_dev->sd_desc = sd_desc;
1854 gspca_dev->nbufread = 2; 1903 gspca_dev->nbufread = 2;
1904 gspca_dev->empty_packet = -1; /* don't check the empty packets */
1855 1905
1856 /* configure the subdriver and initialize the USB device */ 1906 /* configure the subdriver and initialize the USB device */
1857 ret = gspca_dev->sd_desc->config(gspca_dev, id); 1907 ret = sd_desc->config(gspca_dev, id);
1858 if (ret < 0) 1908 if (ret < 0)
1859 goto out; 1909 goto out;
1860 ret = gspca_dev->sd_desc->init(gspca_dev); 1910 ret = sd_desc->init(gspca_dev);
1861 if (ret < 0) 1911 if (ret < 0)
1862 goto out; 1912 goto out;
1863 ret = gspca_set_alt0(gspca_dev); 1913 ret = gspca_set_alt0(gspca_dev);
@@ -1871,18 +1921,15 @@ int gspca_dev_probe(struct usb_interface *intf,
1871 init_waitqueue_head(&gspca_dev->wq); 1921 init_waitqueue_head(&gspca_dev->wq);
1872 1922
1873 /* init video stuff */ 1923 /* init video stuff */
1874 gspca_dev->vdev = video_device_alloc(); 1924 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
1875 memcpy(gspca_dev->vdev, &gspca_template, sizeof gspca_template); 1925 gspca_dev->vdev.parent = &dev->dev;
1876 gspca_dev->vdev->parent = &dev->dev;
1877 gspca_dev->module = module; 1926 gspca_dev->module = module;
1878 gspca_dev->present = 1; 1927 gspca_dev->present = 1;
1879 video_set_drvdata(gspca_dev->vdev, gspca_dev); 1928 ret = video_register_device(&gspca_dev->vdev,
1880 ret = video_register_device(gspca_dev->vdev,
1881 VFL_TYPE_GRABBER, 1929 VFL_TYPE_GRABBER,
1882 video_nr); 1930 video_nr);
1883 if (ret < 0) { 1931 if (ret < 0) {
1884 err("video_register_device err %d", ret); 1932 err("video_register_device err %d", ret);
1885 video_device_release(gspca_dev->vdev);
1886 goto out; 1933 goto out;
1887 } 1934 }
1888 1935
@@ -1906,15 +1953,14 @@ void gspca_disconnect(struct usb_interface *intf)
1906{ 1953{
1907 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 1954 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
1908 1955
1909 usb_set_intfdata(intf, NULL);
1910
1911/* We don't want people trying to open up the device */
1912 video_unregister_device(gspca_dev->vdev);
1913
1914 gspca_dev->present = 0; 1956 gspca_dev->present = 0;
1915 gspca_dev->streaming = 0; 1957 gspca_dev->streaming = 0;
1916 1958
1917 kref_put(&gspca_dev->kref, gspca_delete); 1959 usb_set_intfdata(intf, NULL);
1960
1961 /* release the device */
1962 /* (this will call gspca_release() immediatly or on last close) */
1963 video_unregister_device(&gspca_dev->vdev);
1918 1964
1919 PDEBUG(D_PROBE, "disconnect complete"); 1965 PDEBUG(D_PROBE, "disconnect complete");
1920} 1966}
@@ -1992,7 +2038,7 @@ int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
1992 desired lumination fast (with the risc of a slight overshoot) */ 2038 desired lumination fast (with the risc of a slight overshoot) */
1993 steps = abs(desired_avg_lum - avg_lum) / deadzone; 2039 steps = abs(desired_avg_lum - avg_lum) / deadzone;
1994 2040
1995 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n", 2041 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
1996 avg_lum, desired_avg_lum, steps); 2042 avg_lum, desired_avg_lum, steps);
1997 2043
1998 for (i = 0; i < steps; i++) { 2044 for (i = 0; i < steps; i++) {
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index d25e8d69373b..c90af9cb1e07 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -56,8 +56,12 @@ extern int gspca_debug;
56/* device information - set at probe time */ 56/* device information - set at probe time */
57struct cam { 57struct cam {
58 int bulk_size; /* buffer size when image transfer by bulk */ 58 int bulk_size; /* buffer size when image transfer by bulk */
59 struct v4l2_pix_format *cam_mode; /* size nmodes */ 59 const struct v4l2_pix_format *cam_mode; /* size nmodes */
60 char nmodes; 60 char nmodes;
61 __u8 bulk_nurbs; /* number of URBs in bulk mode
62 * - cannot be > MAX_NURBS
63 * - when 0 and bulk_size != 0 means
64 * 1 URB and submit done by subdriver */
61 __u8 epaddr; 65 __u8 epaddr;
62}; 66};
63 67
@@ -70,6 +74,8 @@ typedef void (*cam_v_op) (struct gspca_dev *);
70typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); 74typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
71typedef int (*cam_jpg_op) (struct gspca_dev *, 75typedef int (*cam_jpg_op) (struct gspca_dev *,
72 struct v4l2_jpegcompression *); 76 struct v4l2_jpegcompression *);
77typedef int (*cam_streamparm_op) (struct gspca_dev *,
78 struct v4l2_streamparm *);
73typedef int (*cam_qmnu_op) (struct gspca_dev *, 79typedef int (*cam_qmnu_op) (struct gspca_dev *,
74 struct v4l2_querymenu *); 80 struct v4l2_querymenu *);
75typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, 81typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
@@ -102,6 +108,8 @@ struct sd_desc {
102 cam_jpg_op get_jcomp; 108 cam_jpg_op get_jcomp;
103 cam_jpg_op set_jcomp; 109 cam_jpg_op set_jcomp;
104 cam_qmnu_op querymenu; 110 cam_qmnu_op querymenu;
111 cam_streamparm_op get_streamparm;
112 cam_streamparm_op set_streamparm;
105}; 113};
106 114
107/* packet types when moving from iso buf to frame buf */ 115/* packet types when moving from iso buf to frame buf */
@@ -120,10 +128,9 @@ struct gspca_frame {
120}; 128};
121 129
122struct gspca_dev { 130struct gspca_dev {
123 struct video_device *vdev; 131 struct video_device vdev; /* !! must be the first item */
124 struct module *module; /* subdriver handling the device */ 132 struct module *module; /* subdriver handling the device */
125 struct usb_device *dev; 133 struct usb_device *dev;
126 struct kref kref;
127 struct file *capt_file; /* file doing video capture */ 134 struct file *capt_file; /* file doing video capture */
128 135
129 struct cam cam; /* device information */ 136 struct cam cam; /* device information */
@@ -142,22 +149,20 @@ struct gspca_dev {
142 char fr_q; /* next frame to queue */ 149 char fr_q; /* next frame to queue */
143 char fr_o; /* next frame to dequeue */ 150 char fr_o; /* next frame to dequeue */
144 signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */ 151 signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */
145 char last_packet_type; 152 __u8 last_packet_type;
153 __s8 empty_packet; /* if (-1) don't check empty packets */
154 __u8 streaming;
146 155
147 __u8 iface; /* USB interface number */
148 __u8 alt; /* USB alternate setting */
149 __u8 curr_mode; /* current camera mode */ 156 __u8 curr_mode; /* current camera mode */
150 __u32 pixfmt; /* current mode parameters */ 157 __u32 pixfmt; /* current mode parameters */
151 __u16 width; 158 __u16 width;
152 __u16 height; 159 __u16 height;
160 __u32 sequence; /* frame sequence number */
153 161
154 atomic_t nevent; /* number of frames done */
155 wait_queue_head_t wq; /* wait queue */ 162 wait_queue_head_t wq; /* wait queue */
156 struct mutex usb_lock; /* usb exchange protection */ 163 struct mutex usb_lock; /* usb exchange protection */
157 struct mutex read_lock; /* read protection */ 164 struct mutex read_lock; /* read protection */
158 struct mutex queue_lock; /* ISOC queue protection */ 165 struct mutex queue_lock; /* ISOC queue protection */
159 __u32 sequence; /* frame sequence number */
160 char streaming;
161#ifdef CONFIG_PM 166#ifdef CONFIG_PM
162 char frozen; /* suspend - resume */ 167 char frozen; /* suspend - resume */
163#endif 168#endif
@@ -166,6 +171,8 @@ struct gspca_dev {
166 char nbufread; /* number of buffers for read() */ 171 char nbufread; /* number of buffers for read() */
167 char nurbs; /* number of allocated URBs */ 172 char nurbs; /* number of allocated URBs */
168 char memory; /* memory type (V4L2_MEMORY_xxx) */ 173 char memory; /* memory type (V4L2_MEMORY_xxx) */
174 __u8 iface; /* USB interface number */
175 __u8 alt; /* USB alternate setting */
169 __u8 nbalt; /* number of USB alternate settings */ 176 __u8 nbalt; /* number of USB alternate settings */
170}; 177};
171 178
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index 1a37ae4bc82d..a3f3b7a0c7e7 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -25,59 +25,59 @@
25 25
26/*****************************************************************************/ 26/*****************************************************************************/
27 27
28#define M5602_XB_SENSOR_TYPE 0x00 28#define M5602_XB_SENSOR_TYPE 0x00
29#define M5602_XB_SENSOR_CTRL 0x01 29#define M5602_XB_SENSOR_CTRL 0x01
30#define M5602_XB_LINE_OF_FRAME_H 0x02 30#define M5602_XB_LINE_OF_FRAME_H 0x02
31#define M5602_XB_LINE_OF_FRAME_L 0x03 31#define M5602_XB_LINE_OF_FRAME_L 0x03
32#define M5602_XB_PIX_OF_LINE_H 0x04 32#define M5602_XB_PIX_OF_LINE_H 0x04
33#define M5602_XB_PIX_OF_LINE_L 0x05 33#define M5602_XB_PIX_OF_LINE_L 0x05
34#define M5602_XB_VSYNC_PARA 0x06 34#define M5602_XB_VSYNC_PARA 0x06
35#define M5602_XB_HSYNC_PARA 0x07 35#define M5602_XB_HSYNC_PARA 0x07
36#define M5602_XB_TEST_MODE_1 0x08 36#define M5602_XB_TEST_MODE_1 0x08
37#define M5602_XB_TEST_MODE_2 0x09 37#define M5602_XB_TEST_MODE_2 0x09
38#define M5602_XB_SIG_INI 0x0a 38#define M5602_XB_SIG_INI 0x0a
39#define M5602_XB_DS_PARA 0x0e 39#define M5602_XB_DS_PARA 0x0e
40#define M5602_XB_TRIG_PARA 0x0f 40#define M5602_XB_TRIG_PARA 0x0f
41#define M5602_XB_CLK_PD 0x10 41#define M5602_XB_CLK_PD 0x10
42#define M5602_XB_MCU_CLK_CTRL 0x12 42#define M5602_XB_MCU_CLK_CTRL 0x12
43#define M5602_XB_MCU_CLK_DIV 0x13 43#define M5602_XB_MCU_CLK_DIV 0x13
44#define M5602_XB_SEN_CLK_CTRL 0x14 44#define M5602_XB_SEN_CLK_CTRL 0x14
45#define M5602_XB_SEN_CLK_DIV 0x15 45#define M5602_XB_SEN_CLK_DIV 0x15
46#define M5602_XB_AUD_CLK_CTRL 0x16 46#define M5602_XB_AUD_CLK_CTRL 0x16
47#define M5602_XB_AUD_CLK_DIV 0x17 47#define M5602_XB_AUD_CLK_DIV 0x17
48#define M5602_XB_DEVCTR1 0x41 48#define M5602_XB_DEVCTR1 0x41
49#define M5602_XB_EPSETR0 0x42 49#define M5602_XB_EPSETR0 0x42
50#define M5602_XB_EPAFCTR 0x47 50#define M5602_XB_EPAFCTR 0x47
51#define M5602_XB_EPBFCTR 0x49 51#define M5602_XB_EPBFCTR 0x49
52#define M5602_XB_EPEFCTR 0x4f 52#define M5602_XB_EPEFCTR 0x4f
53#define M5602_XB_TEST_REG 0x53 53#define M5602_XB_TEST_REG 0x53
54#define M5602_XB_ALT2SIZE 0x54 54#define M5602_XB_ALT2SIZE 0x54
55#define M5602_XB_ALT3SIZE 0x55 55#define M5602_XB_ALT3SIZE 0x55
56#define M5602_XB_OBSFRAME 0x56 56#define M5602_XB_OBSFRAME 0x56
57#define M5602_XB_PWR_CTL 0x59 57#define M5602_XB_PWR_CTL 0x59
58#define M5602_XB_ADC_CTRL 0x60 58#define M5602_XB_ADC_CTRL 0x60
59#define M5602_XB_ADC_DATA 0x61 59#define M5602_XB_ADC_DATA 0x61
60#define M5602_XB_MISC_CTRL 0x62 60#define M5602_XB_MISC_CTRL 0x62
61#define M5602_XB_SNAPSHOT 0x63 61#define M5602_XB_SNAPSHOT 0x63
62#define M5602_XB_SCRATCH_1 0x64 62#define M5602_XB_SCRATCH_1 0x64
63#define M5602_XB_SCRATCH_2 0x65 63#define M5602_XB_SCRATCH_2 0x65
64#define M5602_XB_SCRATCH_3 0x66 64#define M5602_XB_SCRATCH_3 0x66
65#define M5602_XB_SCRATCH_4 0x67 65#define M5602_XB_SCRATCH_4 0x67
66#define M5602_XB_I2C_CTRL 0x68 66#define M5602_XB_I2C_CTRL 0x68
67#define M5602_XB_I2C_CLK_DIV 0x69 67#define M5602_XB_I2C_CLK_DIV 0x69
68#define M5602_XB_I2C_DEV_ADDR 0x6a 68#define M5602_XB_I2C_DEV_ADDR 0x6a
69#define M5602_XB_I2C_REG_ADDR 0x6b 69#define M5602_XB_I2C_REG_ADDR 0x6b
70#define M5602_XB_I2C_DATA 0x6c 70#define M5602_XB_I2C_DATA 0x6c
71#define M5602_XB_I2C_STATUS 0x6d 71#define M5602_XB_I2C_STATUS 0x6d
72#define M5602_XB_GPIO_DAT_H 0x70 72#define M5602_XB_GPIO_DAT_H 0x70
73#define M5602_XB_GPIO_DAT_L 0x71 73#define M5602_XB_GPIO_DAT_L 0x71
74#define M5602_XB_GPIO_DIR_H 0x72 74#define M5602_XB_GPIO_DIR_H 0x72
75#define M5602_XB_GPIO_DIR_L 0x73 75#define M5602_XB_GPIO_DIR_L 0x73
76#define M5602_XB_GPIO_EN_H 0x74 76#define M5602_XB_GPIO_EN_H 0x74
77#define M5602_XB_GPIO_EN_L 0x75 77#define M5602_XB_GPIO_EN_L 0x75
78#define M5602_XB_GPIO_DAT 0x76 78#define M5602_XB_GPIO_DAT 0x76
79#define M5602_XB_GPIO_DIR 0x77 79#define M5602_XB_GPIO_DIR 0x77
80#define M5602_XB_MISC_CTL 0x70 80#define M5602_XB_MISC_CTL 0x70
81 81
82#define I2C_BUSY 0x80 82#define I2C_BUSY 0x80
83 83
@@ -90,13 +90,7 @@
90#define M5602_ISOC_ENDPOINT_ADDR 0x81 90#define M5602_ISOC_ENDPOINT_ADDR 0x81
91#define M5602_INTR_ENDPOINT_ADDR 0x82 91#define M5602_INTR_ENDPOINT_ADDR 0x82
92 92
93#define M5602_MAX_FRAMES 32
94#define M5602_URBS 2
95#define M5602_ISOC_PACKETS 14
96
97#define M5602_URB_TIMEOUT msecs_to_jiffies(2 * M5602_ISOC_PACKETS)
98#define M5602_URB_MSG_TIMEOUT 5000 93#define M5602_URB_MSG_TIMEOUT 5000
99#define M5602_FRAME_TIMEOUT 2
100 94
101/*****************************************************************************/ 95/*****************************************************************************/
102 96
@@ -115,7 +109,6 @@ static const unsigned char sensor_urb_skeleton[] = {
115 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11 109 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11
116}; 110};
117 111
118/* m5602 device descriptor, currently it just wraps the m5602_camera struct */
119struct sd { 112struct sd {
120 struct gspca_dev gspca_dev; 113 struct gspca_dev gspca_dev;
121 114
@@ -140,4 +133,10 @@ int m5602_read_bridge(
140int m5602_write_bridge( 133int m5602_write_bridge(
141 struct sd *sd, u8 address, u8 i2c_data); 134 struct sd *sd, u8 address, u8 i2c_data);
142 135
136int m5602_write_sensor(struct sd *sd, const u8 address,
137 u8 *i2c_data, const u8 len);
138
139int m5602_read_sensor(struct sd *sd, const u8 address,
140 u8 *i2c_data, const u8 len);
141
143#endif 142#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index fd6ce384b487..ed906fe31287 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -24,7 +24,7 @@
24 24
25/* Kernel module parameters */ 25/* Kernel module parameters */
26int force_sensor; 26int force_sensor;
27int dump_bridge; 27static int dump_bridge;
28int dump_sensor; 28int dump_sensor;
29 29
30static const __devinitdata struct usb_device_id m5602_table[] = { 30static const __devinitdata struct usb_device_id m5602_table[] = {
@@ -80,6 +80,97 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
80 return (err < 0) ? err : 0; 80 return (err < 0) ? err : 0;
81} 81}
82 82
83int m5602_read_sensor(struct sd *sd, const u8 address,
84 u8 *i2c_data, const u8 len)
85{
86 int err, i;
87
88 if (!len || len > sd->sensor->i2c_regW)
89 return -EINVAL;
90
91 do {
92 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
93 } while ((*i2c_data & I2C_BUSY) && !err);
94 if (err < 0)
95 goto out;
96
97 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
98 sd->sensor->i2c_slave_id);
99 if (err < 0)
100 goto out;
101
102 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
103 if (err < 0)
104 goto out;
105
106 if (sd->sensor->i2c_regW == 1) {
107 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len);
108 if (err < 0)
109 goto out;
110
111 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
112 if (err < 0)
113 goto out;
114 } else {
115 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
116 if (err < 0)
117 goto out;
118 }
119
120 for (i = 0; (i < len) && !err; i++) {
121 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
122
123 PDEBUG(D_CONF, "Reading sensor register "
124 "0x%x containing 0x%x ", address, *i2c_data);
125 }
126out:
127 return err;
128}
129
130int m5602_write_sensor(struct sd *sd, const u8 address,
131 u8 *i2c_data, const u8 len)
132{
133 int err, i;
134 u8 *p;
135 struct usb_device *udev = sd->gspca_dev.dev;
136 __u8 *buf = sd->gspca_dev.usb_buf;
137
138 /* No sensor with a data width larger than 16 bits has yet been seen */
139 if (len > sd->sensor->i2c_regW || !len)
140 return -EINVAL;
141
142 memcpy(buf, sensor_urb_skeleton,
143 sizeof(sensor_urb_skeleton));
144
145 buf[11] = sd->sensor->i2c_slave_id;
146 buf[15] = address;
147
148 /* Special case larger sensor writes */
149 p = buf + 16;
150
151 /* Copy a four byte write sequence for each byte to be written to */
152 for (i = 0; i < len; i++) {
153 memcpy(p, sensor_urb_skeleton + 16, 4);
154 p[3] = i2c_data[i];
155 p += 4;
156 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
157 address, i2c_data[i]);
158 }
159
160 /* Copy the tailer */
161 memcpy(p, sensor_urb_skeleton + 20, 4);
162
163 /* Set the total length */
164 p[3] = 0x10 + len;
165
166 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
167 0x04, 0x40, 0x19,
168 0x0000, buf,
169 20 + len * 4, M5602_URB_MSG_TIMEOUT);
170
171 return (err < 0) ? err : 0;
172}
173
83/* Dump all the registers of the m5602 bridge, 174/* Dump all the registers of the m5602 bridge,
84 unfortunately this breaks the camera until it's power cycled */ 175 unfortunately this breaks the camera until it's power cycled */
85static void m5602_dump_bridge(struct sd *sd) 176static void m5602_dump_bridge(struct sd *sd)
@@ -150,11 +241,15 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
150 241
151 /* Send start command to the camera */ 242 /* Send start command to the camera */
152 const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01}; 243 const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01};
244
245 if (sd->sensor->start)
246 sd->sensor->start(sd);
247
153 memcpy(buf, buffer, sizeof(buffer)); 248 memcpy(buf, buffer, sizeof(buffer));
154 err = usb_control_msg(gspca_dev->dev, 249 err = usb_control_msg(gspca_dev->dev,
155 usb_sndctrlpipe(gspca_dev->dev, 0), 250 usb_sndctrlpipe(gspca_dev->dev, 0),
156 0x04, 0x40, 0x19, 0x0000, buf, 251 0x04, 0x40, 0x19, 0x0000, buf,
157 4, M5602_URB_MSG_TIMEOUT); 252 sizeof(buffer), M5602_URB_MSG_TIMEOUT);
158 253
159 PDEBUG(D_STREAM, "Transfer started"); 254 PDEBUG(D_STREAM, "Transfer started");
160 return (err < 0) ? err : 0; 255 return (err < 0) ? err : 0;
@@ -284,6 +379,7 @@ static int __init mod_m5602_init(void)
284 PDEBUG(D_PROBE, "registered"); 379 PDEBUG(D_PROBE, "registered");
285 return 0; 380 return 0;
286} 381}
382
287static void __exit mod_m5602_exit(void) 383static void __exit mod_m5602_exit(void)
288{ 384{
289 usb_deregister(&sd_driver); 385 usb_deregister(&sd_driver);
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index fb700c2d055a..c0e71c331454 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -18,6 +18,8 @@
18 18
19#include "m5602_mt9m111.h" 19#include "m5602_mt9m111.h"
20 20
21static void mt9m111_dump_registers(struct sd *sd);
22
21int mt9m111_probe(struct sd *sd) 23int mt9m111_probe(struct sd *sd)
22{ 24{
23 u8 data[2] = {0x00, 0x00}; 25 u8 data[2] = {0x00, 0x00};
@@ -44,12 +46,12 @@ int mt9m111_probe(struct sd *sd)
44 } else { 46 } else {
45 data[0] = preinit_mt9m111[i][2]; 47 data[0] = preinit_mt9m111[i][2];
46 data[1] = preinit_mt9m111[i][3]; 48 data[1] = preinit_mt9m111[i][3];
47 mt9m111_write_sensor(sd, 49 m5602_write_sensor(sd,
48 preinit_mt9m111[i][1], data, 2); 50 preinit_mt9m111[i][1], data, 2);
49 } 51 }
50 } 52 }
51 53
52 if (mt9m111_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2)) 54 if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2))
53 return -ENODEV; 55 return -ENODEV;
54 56
55 if ((data[0] == 0x14) && (data[1] == 0x3a)) { 57 if ((data[0] == 0x14) && (data[1] == 0x3a)) {
@@ -72,7 +74,7 @@ int mt9m111_init(struct sd *sd)
72 int i, err = 0; 74 int i, err = 0;
73 75
74 /* Init the sensor */ 76 /* Init the sensor */
75 for (i = 0; i < ARRAY_SIZE(init_mt9m111); i++) { 77 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
76 u8 data[2]; 78 u8 data[2];
77 79
78 if (init_mt9m111[i][0] == BRIDGE) { 80 if (init_mt9m111[i][0] == BRIDGE) {
@@ -82,7 +84,7 @@ int mt9m111_init(struct sd *sd)
82 } else { 84 } else {
83 data[0] = init_mt9m111[i][2]; 85 data[0] = init_mt9m111[i][2];
84 data[1] = init_mt9m111[i][3]; 86 data[1] = init_mt9m111[i][3];
85 err = mt9m111_write_sensor(sd, 87 err = m5602_write_sensor(sd,
86 init_mt9m111[i][1], data, 2); 88 init_mt9m111[i][1], data, 2);
87 } 89 }
88 } 90 }
@@ -104,12 +106,12 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
104 u8 data[2] = {0x00, 0x00}; 106 u8 data[2] = {0x00, 0x00};
105 struct sd *sd = (struct sd *) gspca_dev; 107 struct sd *sd = (struct sd *) gspca_dev;
106 108
107 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 109 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
108 data, 2); 110 data, 2);
109 *val = data[0] & MT9M111_RMB_MIRROR_ROWS; 111 *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
110 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 112 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
111 113
112 return (err < 0) ? err : 0; 114 return err;
113} 115}
114 116
115int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 117int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -121,19 +123,19 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
121 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 123 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
122 124
123 /* Set the correct page map */ 125 /* Set the correct page map */
124 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 126 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
125 if (err < 0) 127 if (err < 0)
126 goto out; 128 goto out;
127 129
128 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); 130 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
129 if (err < 0) 131 if (err < 0)
130 goto out; 132 goto out;
131 133
132 data[0] = (data[0] & 0xfe) | val; 134 data[0] = (data[0] & 0xfe) | val;
133 err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 135 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
134 data, 2); 136 data, 2);
135out: 137out:
136 return (err < 0) ? err : 0; 138 return err;
137} 139}
138 140
139int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 141int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -142,12 +144,12 @@ int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
142 u8 data[2] = {0x00, 0x00}; 144 u8 data[2] = {0x00, 0x00};
143 struct sd *sd = (struct sd *) gspca_dev; 145 struct sd *sd = (struct sd *) gspca_dev;
144 146
145 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 147 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
146 data, 2); 148 data, 2);
147 *val = data[0] & MT9M111_RMB_MIRROR_COLS; 149 *val = data[0] & MT9M111_RMB_MIRROR_COLS;
148 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 150 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
149 151
150 return (err < 0) ? err : 0; 152 return err;
151} 153}
152 154
153int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 155int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -159,19 +161,19 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
159 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 161 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
160 162
161 /* Set the correct page map */ 163 /* Set the correct page map */
162 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 164 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
163 if (err < 0) 165 if (err < 0)
164 goto out; 166 goto out;
165 167
166 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); 168 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
167 if (err < 0) 169 if (err < 0)
168 goto out; 170 goto out;
169 171
170 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); 172 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
171 err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 173 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
172 data, 2); 174 data, 2);
173out: 175out:
174 return (err < 0) ? err : 0; 176 return err;
175} 177}
176 178
177int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 179int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -180,7 +182,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
180 u8 data[2] = {0x00, 0x00}; 182 u8 data[2] = {0x00, 0x00};
181 struct sd *sd = (struct sd *) gspca_dev; 183 struct sd *sd = (struct sd *) gspca_dev;
182 184
183 err = mt9m111_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); 185 err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2);
184 tmp = ((data[1] << 8) | data[0]); 186 tmp = ((data[1] << 8) | data[0]);
185 187
186 *val = ((tmp & (1 << 10)) * 2) | 188 *val = ((tmp & (1 << 10)) * 2) |
@@ -190,7 +192,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
190 192
191 PDEBUG(D_V4L2, "Read gain %d", *val); 193 PDEBUG(D_V4L2, "Read gain %d", *val);
192 194
193 return (err < 0) ? err : 0; 195 return err;
194} 196}
195 197
196int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) 198int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -200,7 +202,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
200 struct sd *sd = (struct sd *) gspca_dev; 202 struct sd *sd = (struct sd *) gspca_dev;
201 203
202 /* Set the correct page map */ 204 /* Set the correct page map */
203 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 205 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
204 if (err < 0) 206 if (err < 0)
205 goto out; 207 goto out;
206 208
@@ -225,90 +227,13 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
225 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, 227 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
226 data[1], data[0]); 228 data[1], data[0]);
227 229
228 err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, 230 err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
229 data, 2); 231 data, 2);
230out: 232out:
231 return (err < 0) ? err : 0; 233 return err;
232}
233
234int mt9m111_read_sensor(struct sd *sd, const u8 address,
235 u8 *i2c_data, const u8 len) {
236 int err, i;
237
238 do {
239 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
240 } while ((*i2c_data & I2C_BUSY) && !err);
241 if (err < 0)
242 goto out;
243
244 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
245 sd->sensor->i2c_slave_id);
246 if (err < 0)
247 goto out;
248
249 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
250 if (err < 0)
251 goto out;
252
253 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x1a);
254 if (err < 0)
255 goto out;
256
257 for (i = 0; i < len && !err; i++) {
258 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
259
260 PDEBUG(D_CONF, "Reading sensor register "
261 "0x%x contains 0x%x ", address, *i2c_data);
262 }
263out:
264 return (err < 0) ? err : 0;
265}
266
267int mt9m111_write_sensor(struct sd *sd, const u8 address,
268 u8 *i2c_data, const u8 len)
269{
270 int err, i;
271 u8 *p;
272 struct usb_device *udev = sd->gspca_dev.dev;
273 __u8 *buf = sd->gspca_dev.usb_buf;
274
275 /* No sensor with a data width larger
276 than 16 bits has yet been seen, nor with 0 :p*/
277 if (len > 2 || !len)
278 return -EINVAL;
279
280 memcpy(buf, sensor_urb_skeleton,
281 sizeof(sensor_urb_skeleton));
282
283 buf[11] = sd->sensor->i2c_slave_id;
284 buf[15] = address;
285
286 p = buf + 16;
287
288 /* Copy a four byte write sequence for each byte to be written to */
289 for (i = 0; i < len; i++) {
290 memcpy(p, sensor_urb_skeleton + 16, 4);
291 p[3] = i2c_data[i];
292 p += 4;
293 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
294 address, i2c_data[i]);
295 }
296
297 /* Copy the tailer */
298 memcpy(p, sensor_urb_skeleton + 20, 4);
299
300 /* Set the total length */
301 p[3] = 0x10 + len;
302
303 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
304 0x04, 0x40, 0x19,
305 0x0000, buf,
306 20 + len * 4, M5602_URB_MSG_TIMEOUT);
307
308 return (err < 0) ? err : 0;
309} 234}
310 235
311void mt9m111_dump_registers(struct sd *sd) 236static void mt9m111_dump_registers(struct sd *sd)
312{ 237{
313 u8 address, value[2] = {0x00, 0x00}; 238 u8 address, value[2] = {0x00, 0x00};
314 239
@@ -316,27 +241,27 @@ void mt9m111_dump_registers(struct sd *sd)
316 241
317 info("Dumping the mt9m111 sensor core registers"); 242 info("Dumping the mt9m111 sensor core registers");
318 value[1] = MT9M111_SENSOR_CORE; 243 value[1] = MT9M111_SENSOR_CORE;
319 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); 244 m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
320 for (address = 0; address < 0xff; address++) { 245 for (address = 0; address < 0xff; address++) {
321 mt9m111_read_sensor(sd, address, value, 2); 246 m5602_read_sensor(sd, address, value, 2);
322 info("register 0x%x contains 0x%x%x", 247 info("register 0x%x contains 0x%x%x",
323 address, value[0], value[1]); 248 address, value[0], value[1]);
324 } 249 }
325 250
326 info("Dumping the mt9m111 color pipeline registers"); 251 info("Dumping the mt9m111 color pipeline registers");
327 value[1] = MT9M111_COLORPIPE; 252 value[1] = MT9M111_COLORPIPE;
328 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); 253 m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
329 for (address = 0; address < 0xff; address++) { 254 for (address = 0; address < 0xff; address++) {
330 mt9m111_read_sensor(sd, address, value, 2); 255 m5602_read_sensor(sd, address, value, 2);
331 info("register 0x%x contains 0x%x%x", 256 info("register 0x%x contains 0x%x%x",
332 address, value[0], value[1]); 257 address, value[0], value[1]);
333 } 258 }
334 259
335 info("Dumping the mt9m111 camera control registers"); 260 info("Dumping the mt9m111 camera control registers");
336 value[1] = MT9M111_CAMERA_CONTROL; 261 value[1] = MT9M111_CAMERA_CONTROL;
337 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); 262 m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
338 for (address = 0; address < 0xff; address++) { 263 for (address = 0; address < 0xff; address++) {
339 mt9m111_read_sensor(sd, address, value, 2); 264 m5602_read_sensor(sd, address, value, 2);
340 info("register 0x%x contains 0x%x%x", 265 info("register 0x%x contains 0x%x%x",
341 address, value[0], value[1]); 266 address, value[0], value[1]);
342 } 267 }
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 315209d5aeef..e795ab7a36c9 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -87,14 +87,6 @@ int mt9m111_probe(struct sd *sd);
87int mt9m111_init(struct sd *sd); 87int mt9m111_init(struct sd *sd);
88int mt9m111_power_down(struct sd *sd); 88int mt9m111_power_down(struct sd *sd);
89 89
90int mt9m111_read_sensor(struct sd *sd, const u8 address,
91 u8 *i2c_data, const u8 len);
92
93int mt9m111_write_sensor(struct sd *sd, const u8 address,
94 u8 *i2c_data, const u8 len);
95
96void mt9m111_dump_registers(struct sd *sd);
97
98int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 90int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
99int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 91int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
100int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 92int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -106,14 +98,12 @@ static struct m5602_sensor mt9m111 = {
106 .name = "MT9M111", 98 .name = "MT9M111",
107 99
108 .i2c_slave_id = 0xba, 100 .i2c_slave_id = 0xba,
101 .i2c_regW = 2,
109 102
110 .probe = mt9m111_probe, 103 .probe = mt9m111_probe,
111 .init = mt9m111_init, 104 .init = mt9m111_init,
112 .power_down = mt9m111_power_down, 105 .power_down = mt9m111_power_down,
113 106
114 .read_sensor = mt9m111_read_sensor,
115 .write_sensor = mt9m111_write_sensor,
116
117 .nctrls = 3, 107 .nctrls = 3,
118 .ctrls = { 108 .ctrls = {
119 { 109 {
@@ -1003,7 +993,7 @@ static const unsigned char init_mt9m111[][4] =
1003 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, 993 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
1004 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 994 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
1005 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 995 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
1006 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, 996 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/
1007 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, 997 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
1008 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 998 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
1009 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 999 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 837c7e47661c..c908a8d6970a 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -18,77 +18,57 @@
18 18
19#include "m5602_ov9650.h" 19#include "m5602_ov9650.h"
20 20
21int ov9650_read_sensor(struct sd *sd, const u8 address, 21/* Vertically and horizontally flips the image if matched, needed for machines
22 u8 *i2c_data, const u8 len) 22 where the sensor is mounted upside down */
23{ 23static
24 int err, i; 24 const
25 25 struct dmi_system_id ov9650_flip_dmi_table[] = {
26 /* The ov9650 registers have a max depth of one byte */ 26 {
27 if (len > 1 || !len) 27 .ident = "ASUS A6VC",
28 return -EINVAL; 28 .matches = {
29 29 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
30 do { 30 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
31 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); 31 }
32 } while ((*i2c_data & I2C_BUSY) && !err); 32 },
33 33 {
34 m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, 34 .ident = "ASUS A6VM",
35 ov9650.i2c_slave_id); 35 .matches = {
36 m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); 36 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
37 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len); 37 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
38 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); 38 }
39 39 },
40 for (i = 0; i < len; i++) { 40 {
41 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); 41 .ident = "ASUS A6JC",
42 42 .matches = {
43 PDEBUG(D_CONF, "Reading sensor register " 43 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
44 "0x%x containing 0x%x ", address, *i2c_data); 44 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
45 } 45 }
46 return (err < 0) ? err : 0; 46 },
47} 47 {
48 48 .ident = "ASUS A6Ja",
49int ov9650_write_sensor(struct sd *sd, const u8 address, 49 .matches = {
50 u8 *i2c_data, const u8 len) 50 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
51{ 51 DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
52 int err, i; 52 }
53 u8 *p; 53 },
54 struct usb_device *udev = sd->gspca_dev.dev; 54 {
55 __u8 *buf = sd->gspca_dev.usb_buf; 55 .ident = "ASUS A6Kt",
56 56 .matches = {
57 /* The ov9650 only supports one byte writes */ 57 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
58 if (len > 1 || !len) 58 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
59 return -EINVAL; 59 }
60 60 },
61 memcpy(buf, sensor_urb_skeleton, 61 {
62 sizeof(sensor_urb_skeleton)); 62 .ident = "Alienware Aurora m9700",
63 63 .matches = {
64 buf[11] = sd->sensor->i2c_slave_id; 64 DMI_MATCH(DMI_SYS_VENDOR, "alienware"),
65 buf[15] = address; 65 DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
66 66 }
67 /* Special case larger sensor writes */ 67 },
68 p = buf + 16; 68 { }
69 69};
70 /* Copy a four byte write sequence for each byte to be written to */
71 for (i = 0; i < len; i++) {
72 memcpy(p, sensor_urb_skeleton + 16, 4);
73 p[3] = i2c_data[i];
74 p += 4;
75 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
76 address, i2c_data[i]);
77 }
78
79 /* Copy the tailer */
80 memcpy(p, sensor_urb_skeleton + 20, 4);
81
82 /* Set the total length */
83 p[3] = 0x10 + len;
84
85 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
86 0x04, 0x40, 0x19,
87 0x0000, buf,
88 20 + len * 4, M5602_URB_MSG_TIMEOUT);
89 70
90 return (err < 0) ? err : 0; 71static void ov9650_dump_registers(struct sd *sd);
91}
92 72
93int ov9650_probe(struct sd *sd) 73int ov9650_probe(struct sd *sd)
94{ 74{
@@ -110,16 +90,16 @@ int ov9650_probe(struct sd *sd)
110 for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) { 90 for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) {
111 u8 data = preinit_ov9650[i][2]; 91 u8 data = preinit_ov9650[i][2];
112 if (preinit_ov9650[i][0] == SENSOR) 92 if (preinit_ov9650[i][0] == SENSOR)
113 ov9650_write_sensor(sd, 93 m5602_write_sensor(sd,
114 preinit_ov9650[i][1], &data, 1); 94 preinit_ov9650[i][1], &data, 1);
115 else 95 else
116 m5602_write_bridge(sd, preinit_ov9650[i][1], data); 96 m5602_write_bridge(sd, preinit_ov9650[i][1], data);
117 } 97 }
118 98
119 if (ov9650_read_sensor(sd, OV9650_PID, &prod_id, 1)) 99 if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
120 return -ENODEV; 100 return -ENODEV;
121 101
122 if (ov9650_read_sensor(sd, OV9650_VER, &ver_id, 1)) 102 if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1))
123 return -ENODEV; 103 return -ENODEV;
124 104
125 if ((prod_id == 0x96) && (ver_id == 0x52)) { 105 if ((prod_id == 0x96) && (ver_id == 0x52)) {
@@ -148,34 +128,90 @@ int ov9650_init(struct sd *sd)
148 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) { 128 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) {
149 data = init_ov9650[i][2]; 129 data = init_ov9650[i][2];
150 if (init_ov9650[i][0] == SENSOR) 130 if (init_ov9650[i][0] == SENSOR)
151 err = ov9650_write_sensor(sd, init_ov9650[i][1], 131 err = m5602_write_sensor(sd, init_ov9650[i][1],
152 &data, 1); 132 &data, 1);
153 else 133 else
154 err = m5602_write_bridge(sd, init_ov9650[i][1], data); 134 err = m5602_write_bridge(sd, init_ov9650[i][1], data);
155 } 135 }
156 136
157 if (!err && dmi_check_system(ov9650_flip_dmi_table)) { 137 if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
158 info("vflip quirk active"); 138 info("vflip quirk active");
159 data = 0x30; 139 data = 0x30;
160 err = ov9650_write_sensor(sd, OV9650_MVFP, &data, 1); 140 err = m5602_write_sensor(sd, OV9650_MVFP, &data, 1);
161 } 141 }
142 return err;
143}
144
145int ov9650_start(struct sd *sd)
146{
147 int i, err = 0;
148 struct cam *cam = &sd->gspca_dev.cam;
162 149
163 return (err < 0) ? err : 0; 150 for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
151 u8 data = res_init_ov9650[i][1];
152 err = m5602_write_bridge(sd, res_init_ov9650[i][0], data);
153 }
154 if (err < 0)
155 return err;
156
157 switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
158 {
159 case 640:
160 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
161
162 for (i = 0; i < ARRAY_SIZE(VGA_ov9650) && !err; i++) {
163 u8 data = VGA_ov9650[i][2];
164 if (VGA_ov9650[i][0] == SENSOR)
165 err = m5602_write_sensor(sd,
166 VGA_ov9650[i][1], &data, 1);
167 else
168 err = m5602_write_bridge(sd, VGA_ov9650[i][1], data);
169 }
170 break;
171
172 case 352:
173 PDEBUG(D_V4L2, "Configuring camera for CIF mode");
174
175 for (i = 0; i < ARRAY_SIZE(CIF_ov9650) && !err; i++) {
176 u8 data = CIF_ov9650[i][2];
177 if (CIF_ov9650[i][0] == SENSOR)
178 err = m5602_write_sensor(sd,
179 CIF_ov9650[i][1], &data, 1);
180 else
181 err = m5602_write_bridge(sd, CIF_ov9650[i][1], data);
182 }
183 break;
184
185 case 320:
186 PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
187
188 for (i = 0; i < ARRAY_SIZE(QVGA_ov9650) && !err; i++) {
189 u8 data = QVGA_ov9650[i][2];
190 if (QVGA_ov9650[i][0] == SENSOR)
191 err = m5602_write_sensor(sd,
192 QVGA_ov9650[i][1], &data, 1);
193 else
194 err = m5602_write_bridge(sd, QVGA_ov9650[i][1], data);
195 }
196 break;
197 }
198 return err;
164} 199}
165 200
166int ov9650_power_down(struct sd *sd) 201int ov9650_power_down(struct sd *sd)
167{ 202{
168 int i; 203 int i, err = 0;
169 for (i = 0; i < ARRAY_SIZE(power_down_ov9650); i++) { 204 for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) {
170 u8 data = power_down_ov9650[i][2]; 205 u8 data = power_down_ov9650[i][2];
171 if (power_down_ov9650[i][0] == SENSOR) 206 if (power_down_ov9650[i][0] == SENSOR)
172 ov9650_write_sensor(sd, 207 err = m5602_write_sensor(sd,
173 power_down_ov9650[i][1], &data, 1); 208 power_down_ov9650[i][1], &data, 1);
174 else 209 else
175 m5602_write_bridge(sd, power_down_ov9650[i][1], data); 210 err = m5602_write_bridge(sd, power_down_ov9650[i][1],
211 data);
176 } 212 }
177 213
178 return 0; 214 return err;
179} 215}
180 216
181int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 217int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -184,24 +220,24 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
184 u8 i2c_data; 220 u8 i2c_data;
185 int err; 221 int err;
186 222
187 err = ov9650_read_sensor(sd, OV9650_COM1, &i2c_data, 1); 223 err = m5602_read_sensor(sd, OV9650_COM1, &i2c_data, 1);
188 if (err < 0) 224 if (err < 0)
189 goto out; 225 goto out;
190 *val = i2c_data & 0x03; 226 *val = i2c_data & 0x03;
191 227
192 err = ov9650_read_sensor(sd, OV9650_AECH, &i2c_data, 1); 228 err = m5602_read_sensor(sd, OV9650_AECH, &i2c_data, 1);
193 if (err < 0) 229 if (err < 0)
194 goto out; 230 goto out;
195 *val |= (i2c_data << 2); 231 *val |= (i2c_data << 2);
196 232
197 err = ov9650_read_sensor(sd, OV9650_AECHM, &i2c_data, 1); 233 err = m5602_read_sensor(sd, OV9650_AECHM, &i2c_data, 1);
198 if (err < 0) 234 if (err < 0)
199 goto out; 235 goto out;
200 *val |= (i2c_data & 0x3f) << 10; 236 *val |= (i2c_data & 0x3f) << 10;
201 237
202 PDEBUG(D_V4L2, "Read exposure %d", *val); 238 PDEBUG(D_V4L2, "Read exposure %d", *val);
203out: 239out:
204 return (err < 0) ? err : 0; 240 return err;
205} 241}
206 242
207int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 243int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
@@ -215,24 +251,24 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
215 251
216 /* The 6 MSBs */ 252 /* The 6 MSBs */
217 i2c_data = (val >> 10) & 0x3f; 253 i2c_data = (val >> 10) & 0x3f;
218 err = ov9650_write_sensor(sd, OV9650_AECHM, 254 err = m5602_write_sensor(sd, OV9650_AECHM,
219 &i2c_data, 1); 255 &i2c_data, 1);
220 if (err < 0) 256 if (err < 0)
221 goto out; 257 goto out;
222 258
223 /* The 8 middle bits */ 259 /* The 8 middle bits */
224 i2c_data = (val >> 2) & 0xff; 260 i2c_data = (val >> 2) & 0xff;
225 err = ov9650_write_sensor(sd, OV9650_AECH, 261 err = m5602_write_sensor(sd, OV9650_AECH,
226 &i2c_data, 1); 262 &i2c_data, 1);
227 if (err < 0) 263 if (err < 0)
228 goto out; 264 goto out;
229 265
230 /* The 2 LSBs */ 266 /* The 2 LSBs */
231 i2c_data = val & 0x03; 267 i2c_data = val & 0x03;
232 err = ov9650_write_sensor(sd, OV9650_COM1, &i2c_data, 1); 268 err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
233 269
234out: 270out:
235 return (err < 0) ? err : 0; 271 return err;
236} 272}
237 273
238int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 274int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -241,13 +277,13 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
241 u8 i2c_data; 277 u8 i2c_data;
242 struct sd *sd = (struct sd *) gspca_dev; 278 struct sd *sd = (struct sd *) gspca_dev;
243 279
244 ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 280 m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
245 *val = (i2c_data & 0x03) << 8; 281 *val = (i2c_data & 0x03) << 8;
246 282
247 err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); 283 err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
248 *val |= i2c_data; 284 *val |= i2c_data;
249 PDEBUG(D_V4L2, "Read gain %d", *val); 285 PDEBUG(D_V4L2, "Read gain %d", *val);
250 return (err < 0) ? err : 0; 286 return err;
251} 287}
252 288
253int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) 289int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -259,16 +295,16 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
259 /* The 2 MSB */ 295 /* The 2 MSB */
260 /* Read the OV9650_VREF register first to avoid 296 /* Read the OV9650_VREF register first to avoid
261 corrupting the VREF high and low bits */ 297 corrupting the VREF high and low bits */
262 ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 298 m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
263 /* Mask away all uninteresting bits */ 299 /* Mask away all uninteresting bits */
264 i2c_data = ((val & 0x0300) >> 2) | 300 i2c_data = ((val & 0x0300) >> 2) |
265 (i2c_data & 0x3F); 301 (i2c_data & 0x3F);
266 err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1); 302 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
267 303
268 /* The 8 LSBs */ 304 /* The 8 LSBs */
269 i2c_data = val & 0xff; 305 i2c_data = val & 0xff;
270 err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); 306 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
271 return (err < 0) ? err : 0; 307 return err;
272} 308}
273 309
274int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 310int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -277,12 +313,12 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
277 u8 i2c_data; 313 u8 i2c_data;
278 struct sd *sd = (struct sd *) gspca_dev; 314 struct sd *sd = (struct sd *) gspca_dev;
279 315
280 err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1); 316 err = m5602_read_sensor(sd, OV9650_RED, &i2c_data, 1);
281 *val = i2c_data; 317 *val = i2c_data;
282 318
283 PDEBUG(D_V4L2, "Read red gain %d", *val); 319 PDEBUG(D_V4L2, "Read red gain %d", *val);
284 320
285 return (err < 0) ? err : 0; 321 return err;
286} 322}
287 323
288int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 324int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -295,9 +331,9 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
295 val & 0xff); 331 val & 0xff);
296 332
297 i2c_data = val & 0xff; 333 i2c_data = val & 0xff;
298 err = ov9650_write_sensor(sd, OV9650_RED, &i2c_data, 1); 334 err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
299 335
300 return (err < 0) ? err : 0; 336 return err;
301} 337}
302 338
303int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 339int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -306,12 +342,12 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
306 u8 i2c_data; 342 u8 i2c_data;
307 struct sd *sd = (struct sd *) gspca_dev; 343 struct sd *sd = (struct sd *) gspca_dev;
308 344
309 err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1); 345 err = m5602_read_sensor(sd, OV9650_BLUE, &i2c_data, 1);
310 *val = i2c_data; 346 *val = i2c_data;
311 347
312 PDEBUG(D_V4L2, "Read blue gain %d", *val); 348 PDEBUG(D_V4L2, "Read blue gain %d", *val);
313 349
314 return (err < 0) ? err : 0; 350 return err;
315} 351}
316 352
317int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 353int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -324,9 +360,9 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
324 val & 0xff); 360 val & 0xff);
325 361
326 i2c_data = val & 0xff; 362 i2c_data = val & 0xff;
327 err = ov9650_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); 363 err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
328 364
329 return (err < 0) ? err : 0; 365 return err;
330} 366}
331 367
332int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 368int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -335,14 +371,14 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
335 u8 i2c_data; 371 u8 i2c_data;
336 struct sd *sd = (struct sd *) gspca_dev; 372 struct sd *sd = (struct sd *) gspca_dev;
337 373
338 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 374 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
339 if (dmi_check_system(ov9650_flip_dmi_table)) 375 if (dmi_check_system(ov9650_flip_dmi_table))
340 *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1; 376 *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1;
341 else 377 else
342 *val = (i2c_data & OV9650_HFLIP) >> 5; 378 *val = (i2c_data & OV9650_HFLIP) >> 5;
343 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 379 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
344 380
345 return (err < 0) ? err : 0; 381 return err;
346} 382}
347 383
348int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 384int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -352,20 +388,20 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
352 struct sd *sd = (struct sd *) gspca_dev; 388 struct sd *sd = (struct sd *) gspca_dev;
353 389
354 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 390 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
355 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 391 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
356 if (err < 0) 392 if (err < 0)
357 goto out; 393 goto out;
358 394
359 if (dmi_check_system(ov9650_flip_dmi_table)) 395 if (dmi_check_system(ov9650_flip_dmi_table))
360 i2c_data = ((i2c_data & 0xdf) | 396 i2c_data = ((i2c_data & 0xdf) |
361 (((val ? 0 : 1) & 0x01) << 5)); 397 (((val ? 0 : 1) & 0x01) << 5));
362 else 398 else
363 i2c_data = ((i2c_data & 0xdf) | 399 i2c_data = ((i2c_data & 0xdf) |
364 ((val & 0x01) << 5)); 400 ((val & 0x01) << 5));
365 401
366 err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 402 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
367out: 403out:
368 return (err < 0) ? err : 0; 404 return err;
369} 405}
370 406
371int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 407int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -374,14 +410,14 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
374 u8 i2c_data; 410 u8 i2c_data;
375 struct sd *sd = (struct sd *) gspca_dev; 411 struct sd *sd = (struct sd *) gspca_dev;
376 412
377 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 413 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
378 if (dmi_check_system(ov9650_flip_dmi_table)) 414 if (dmi_check_system(ov9650_flip_dmi_table))
379 *val = ((i2c_data & 0x10) >> 4) ? 0 : 1; 415 *val = ((i2c_data & 0x10) >> 4) ? 0 : 1;
380 else 416 else
381 *val = (i2c_data & 0x10) >> 4; 417 *val = (i2c_data & 0x10) >> 4;
382 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 418 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
383 419
384 return (err < 0) ? err : 0; 420 return err;
385} 421}
386 422
387int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 423int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -391,7 +427,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
391 struct sd *sd = (struct sd *) gspca_dev; 427 struct sd *sd = (struct sd *) gspca_dev;
392 428
393 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 429 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
394 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 430 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
395 if (err < 0) 431 if (err < 0)
396 goto out; 432 goto out;
397 433
@@ -402,9 +438,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
402 i2c_data = ((i2c_data & 0xef) | 438 i2c_data = ((i2c_data & 0xef) |
403 ((val & 0x01) << 4)); 439 ((val & 0x01) << 4));
404 440
405 err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 441 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
406out: 442out:
407 return (err < 0) ? err : 0; 443 return err;
408} 444}
409 445
410int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 446int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -413,16 +449,16 @@ int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
413 u8 i2c_data; 449 u8 i2c_data;
414 struct sd *sd = (struct sd *) gspca_dev; 450 struct sd *sd = (struct sd *) gspca_dev;
415 451
416 err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 452 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
417 if (err < 0) 453 if (err < 0)
418 goto out; 454 goto out;
419 *val = (i2c_data & 0x03) << 8; 455 *val = (i2c_data & 0x03) << 8;
420 456
421 err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); 457 err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
422 *val |= i2c_data; 458 *val |= i2c_data;
423 PDEBUG(D_V4L2, "Read gain %d", *val); 459 PDEBUG(D_V4L2, "Read gain %d", *val);
424out: 460out:
425 return (err < 0) ? err : 0; 461 return err;
426} 462}
427 463
428int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 464int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -435,22 +471,22 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
435 471
436 /* Read the OV9650_VREF register first to avoid 472 /* Read the OV9650_VREF register first to avoid
437 corrupting the VREF high and low bits */ 473 corrupting the VREF high and low bits */
438 err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 474 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
439 if (err < 0) 475 if (err < 0)
440 goto out; 476 goto out;
441 477
442 /* Mask away all uninteresting bits */ 478 /* Mask away all uninteresting bits */
443 i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F); 479 i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
444 err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1); 480 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
445 if (err < 0) 481 if (err < 0)
446 goto out; 482 goto out;
447 483
448 /* The 8 LSBs */ 484 /* The 8 LSBs */
449 i2c_data = val & 0xff; 485 i2c_data = val & 0xff;
450 err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); 486 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
451 487
452out: 488out:
453 return (err < 0) ? err : 0; 489 return err;
454} 490}
455 491
456int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) 492int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -459,11 +495,11 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
459 u8 i2c_data; 495 u8 i2c_data;
460 struct sd *sd = (struct sd *) gspca_dev; 496 struct sd *sd = (struct sd *) gspca_dev;
461 497
462 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 498 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
463 *val = (i2c_data & OV9650_AWB_EN) >> 1; 499 *val = (i2c_data & OV9650_AWB_EN) >> 1;
464 PDEBUG(D_V4L2, "Read auto white balance %d", *val); 500 PDEBUG(D_V4L2, "Read auto white balance %d", *val);
465 501
466 return (err < 0) ? err : 0; 502 return err;
467} 503}
468 504
469int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) 505int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -473,14 +509,14 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
473 struct sd *sd = (struct sd *) gspca_dev; 509 struct sd *sd = (struct sd *) gspca_dev;
474 510
475 PDEBUG(D_V4L2, "Set auto white balance to %d", val); 511 PDEBUG(D_V4L2, "Set auto white balance to %d", val);
476 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 512 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
477 if (err < 0) 513 if (err < 0)
478 goto out; 514 goto out;
479 515
480 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); 516 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
481 err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 517 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
482out: 518out:
483 return (err < 0) ? err : 0; 519 return err;
484} 520}
485 521
486int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) 522int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -489,11 +525,11 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
489 u8 i2c_data; 525 u8 i2c_data;
490 struct sd *sd = (struct sd *) gspca_dev; 526 struct sd *sd = (struct sd *) gspca_dev;
491 527
492 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 528 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
493 *val = (i2c_data & OV9650_AGC_EN) >> 2; 529 *val = (i2c_data & OV9650_AGC_EN) >> 2;
494 PDEBUG(D_V4L2, "Read auto gain control %d", *val); 530 PDEBUG(D_V4L2, "Read auto gain control %d", *val);
495 531
496 return (err < 0) ? err : 0; 532 return err;
497} 533}
498 534
499int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 535int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -503,23 +539,23 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
503 struct sd *sd = (struct sd *) gspca_dev; 539 struct sd *sd = (struct sd *) gspca_dev;
504 540
505 PDEBUG(D_V4L2, "Set auto gain control to %d", val); 541 PDEBUG(D_V4L2, "Set auto gain control to %d", val);
506 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 542 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
507 if (err < 0) 543 if (err < 0)
508 goto out; 544 goto out;
509 545
510 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 546 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
511 err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 547 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
512out: 548out:
513 return (err < 0) ? err : 0; 549 return err;
514} 550}
515 551
516void ov9650_dump_registers(struct sd *sd) 552static void ov9650_dump_registers(struct sd *sd)
517{ 553{
518 int address; 554 int address;
519 info("Dumping the ov9650 register state"); 555 info("Dumping the ov9650 register state");
520 for (address = 0; address < 0xa9; address++) { 556 for (address = 0; address < 0xa9; address++) {
521 u8 value; 557 u8 value;
522 ov9650_read_sensor(sd, address, &value, 1); 558 m5602_read_sensor(sd, address, &value, 1);
523 info("register 0x%x contains 0x%x", 559 info("register 0x%x contains 0x%x",
524 address, value); 560 address, value);
525 } 561 }
@@ -531,9 +567,9 @@ void ov9650_dump_registers(struct sd *sd)
531 u8 old_value, ctrl_value; 567 u8 old_value, ctrl_value;
532 u8 test_value[2] = {0xff, 0xff}; 568 u8 test_value[2] = {0xff, 0xff};
533 569
534 ov9650_read_sensor(sd, address, &old_value, 1); 570 m5602_read_sensor(sd, address, &old_value, 1);
535 ov9650_write_sensor(sd, address, test_value, 1); 571 m5602_write_sensor(sd, address, test_value, 1);
536 ov9650_read_sensor(sd, address, &ctrl_value, 1); 572 m5602_read_sensor(sd, address, &ctrl_value, 1);
537 573
538 if (ctrl_value == test_value[0]) 574 if (ctrl_value == test_value[0])
539 info("register 0x%x is writeable", address); 575 info("register 0x%x is writeable", address);
@@ -541,6 +577,6 @@ void ov9650_dump_registers(struct sd *sd)
541 info("register 0x%x is read only", address); 577 info("register 0x%x is read only", address);
542 578
543 /* Restore original value */ 579 /* Restore original value */
544 ov9650_write_sensor(sd, address, &old_value, 1); 580 m5602_write_sensor(sd, address, &old_value, 1);
545 } 581 }
546} 582}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index 065632f0378e..f4b33b8e8dae 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -20,7 +20,6 @@
20#define M5602_OV9650_H_ 20#define M5602_OV9650_H_
21 21
22#include <linux/dmi.h> 22#include <linux/dmi.h>
23
24#include "m5602_sensor.h" 23#include "m5602_sensor.h"
25 24
26/*****************************************************************************/ 25/*****************************************************************************/
@@ -36,6 +35,7 @@
36#define OV9650_PID 0x0a 35#define OV9650_PID 0x0a
37#define OV9650_VER 0x0b 36#define OV9650_VER 0x0b
38#define OV9650_COM3 0x0c 37#define OV9650_COM3 0x0c
38#define OV9650_COM4 0x0d
39#define OV9650_COM5 0x0e 39#define OV9650_COM5 0x0e
40#define OV9650_COM6 0x0f 40#define OV9650_COM6 0x0f
41#define OV9650_AECH 0x10 41#define OV9650_AECH 0x10
@@ -94,6 +94,8 @@
94 94
95#define OV9650_REGISTER_RESET (1 << 7) 95#define OV9650_REGISTER_RESET (1 << 7)
96#define OV9650_VGA_SELECT (1 << 6) 96#define OV9650_VGA_SELECT (1 << 6)
97#define OV9650_CIF_SELECT (1 << 5)
98#define OV9650_QVGA_SELECT (1 << 4)
97#define OV9650_RGB_SELECT (1 << 2) 99#define OV9650_RGB_SELECT (1 << 2)
98#define OV9650_RAW_RGB_SELECT (1 << 0) 100#define OV9650_RAW_RGB_SELECT (1 << 0)
99 101
@@ -108,6 +110,8 @@
108#define OV9650_SYSTEM_CLK_SEL (1 << 7) 110#define OV9650_SYSTEM_CLK_SEL (1 << 7)
109#define OV9650_SLAM_MODE (1 << 4) 111#define OV9650_SLAM_MODE (1 << 4)
110 112
113#define OV9650_QVGA_VARIOPIXEL (1 << 7)
114
111#define OV9650_VFLIP (1 << 4) 115#define OV9650_VFLIP (1 << 4)
112#define OV9650_HFLIP (1 << 5) 116#define OV9650_HFLIP (1 << 5)
113 117
@@ -124,15 +128,9 @@ extern int dump_sensor;
124 128
125int ov9650_probe(struct sd *sd); 129int ov9650_probe(struct sd *sd);
126int ov9650_init(struct sd *sd); 130int ov9650_init(struct sd *sd);
131int ov9650_start(struct sd *sd);
127int ov9650_power_down(struct sd *sd); 132int ov9650_power_down(struct sd *sd);
128 133
129int ov9650_read_sensor(struct sd *sd, const u8 address,
130 u8 *i2c_data, const u8 len);
131int ov9650_write_sensor(struct sd *sd, const u8 address,
132 u8 *i2c_data, const u8 len);
133
134void ov9650_dump_registers(struct sd *sd);
135
136int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 134int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
137int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 135int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
138int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 136int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -155,11 +153,11 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
155static struct m5602_sensor ov9650 = { 153static struct m5602_sensor ov9650 = {
156 .name = "OV9650", 154 .name = "OV9650",
157 .i2c_slave_id = 0x60, 155 .i2c_slave_id = 0x60,
156 .i2c_regW = 1,
158 .probe = ov9650_probe, 157 .probe = ov9650_probe,
159 .init = ov9650_init, 158 .init = ov9650_init,
159 .start = ov9650_start,
160 .power_down = ov9650_power_down, 160 .power_down = ov9650_power_down,
161 .read_sensor = ov9650_read_sensor,
162 .write_sensor = ov9650_write_sensor,
163 161
164 .nctrls = 8, 162 .nctrls = 8,
165 .ctrls = { 163 .ctrls = {
@@ -264,18 +262,38 @@ static struct m5602_sensor ov9650 = {
264 } 262 }
265 }, 263 },
266 264
267 .nmodes = 1, 265 .nmodes = 3,
268 .modes = { 266 .modes = {
269 { 267 {
270 M5602_DEFAULT_FRAME_WIDTH, 268 320,
271 M5602_DEFAULT_FRAME_HEIGHT, 269 240,
270 V4L2_PIX_FMT_SBGGR8,
271 V4L2_FIELD_NONE,
272 .sizeimage =
273 320 * 240,
274 .bytesperline = 320,
275 .colorspace = V4L2_COLORSPACE_SRGB,
276 .priv = 0
277 }, {
278 352,
279 288,
280 V4L2_PIX_FMT_SBGGR8,
281 V4L2_FIELD_NONE,
282 .sizeimage =
283 352 * 288,
284 .bytesperline = 352,
285 .colorspace = V4L2_COLORSPACE_SRGB,
286 .priv = 0
287 }, {
288 640,
289 480,
272 V4L2_PIX_FMT_SBGGR8, 290 V4L2_PIX_FMT_SBGGR8,
273 V4L2_FIELD_NONE, 291 V4L2_FIELD_NONE,
274 .sizeimage = 292 .sizeimage =
275 M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT, 293 640 * 480,
276 .bytesperline = M5602_DEFAULT_FRAME_WIDTH, 294 .bytesperline = 640,
277 .colorspace = V4L2_COLORSPACE_SRGB, 295 .colorspace = V4L2_COLORSPACE_SRGB,
278 .priv = 1 296 .priv = 0
279 } 297 }
280 } 298 }
281}; 299};
@@ -324,6 +342,7 @@ static const unsigned char init_ov9650[][3] =
324 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, 342 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
325 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 343 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
326 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a}, 344 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
345
327 /* Reset chip */ 346 /* Reset chip */
328 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 347 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
329 /* Enable double clock */ 348 /* Enable double clock */
@@ -331,8 +350,6 @@ static const unsigned char init_ov9650[][3] =
331 /* Do something out of spec with the power */ 350 /* Do something out of spec with the power */
332 {SENSOR, OV9650_OFON, 0x40}, 351 {SENSOR, OV9650_OFON, 0x40},
333 352
334 /* Set QQVGA */
335 {SENSOR, OV9650_COM1, 0x20},
336 /* Set fast AGC/AEC algorithm with unlimited step size */ 353 /* Set fast AGC/AEC algorithm with unlimited step size */
337 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | 354 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
338 OV9650_AEC_UNLIM_STEP_SIZE | 355 OV9650_AEC_UNLIM_STEP_SIZE |
@@ -343,7 +360,7 @@ static const unsigned char init_ov9650[][3] =
343 {SENSOR, OV9650_ACOM38, 0x81}, 360 {SENSOR, OV9650_ACOM38, 0x81},
344 /* Turn off color matrix coefficient double option */ 361 /* Turn off color matrix coefficient double option */
345 {SENSOR, OV9650_COM16, 0x00}, 362 {SENSOR, OV9650_COM16, 0x00},
346 /* Enable color matrix for RGB/YUV, Delay Y channel, 363 /* Enable color matrix for RGB/YUV, Delay Y channel,
347 set output Y/UV delay to 1 */ 364 set output Y/UV delay to 1 */
348 {SENSOR, OV9650_COM13, 0x19}, 365 {SENSOR, OV9650_COM13, 0x19},
349 /* Enable digital BLC, Set output mode to U Y V Y */ 366 /* Enable digital BLC, Set output mode to U Y V Y */
@@ -352,7 +369,7 @@ static const unsigned char init_ov9650[][3] =
352 {SENSOR, OV9650_COM24, 0x00}, 369 {SENSOR, OV9650_COM24, 0x00},
353 /* Enable HREF and some out of spec things */ 370 /* Enable HREF and some out of spec things */
354 {SENSOR, OV9650_COM12, 0x73}, 371 {SENSOR, OV9650_COM12, 0x73},
355 /* Set all DBLC offset signs to positive and 372 /* Set all DBLC offset signs to positive and
356 do some out of spec stuff */ 373 do some out of spec stuff */
357 {SENSOR, OV9650_DBLC1, 0xdf}, 374 {SENSOR, OV9650_DBLC1, 0xdf},
358 {SENSOR, OV9650_COM21, 0x06}, 375 {SENSOR, OV9650_COM21, 0x06},
@@ -364,7 +381,7 @@ static const unsigned char init_ov9650[][3] =
364 {SENSOR, OV9650_RSVD96, 0x04}, 381 {SENSOR, OV9650_RSVD96, 0x04},
365 /* Enable full range output */ 382 /* Enable full range output */
366 {SENSOR, OV9650_COM15, 0x0}, 383 {SENSOR, OV9650_COM15, 0x0},
367 /* Enable HREF at optical black, enable ADBLC bias, 384 /* Enable HREF at optical black, enable ADBLC bias,
368 enable ADBLC, reset timings at format change */ 385 enable ADBLC, reset timings at format change */
369 {SENSOR, OV9650_COM6, 0x4b}, 386 {SENSOR, OV9650_COM6, 0x4b},
370 /* Subtract 32 from the B channel bias */ 387 /* Subtract 32 from the B channel bias */
@@ -385,7 +402,7 @@ static const unsigned char init_ov9650[][3] =
385 {SENSOR, OV9650_AEB, 0x5c}, 402 {SENSOR, OV9650_AEB, 0x5c},
386 /* Set the high and low limit nibbles to 3 */ 403 /* Set the high and low limit nibbles to 3 */
387 {SENSOR, OV9650_VPT, 0xc3}, 404 {SENSOR, OV9650_VPT, 0xc3},
388 /* Set the Automatic Gain Ceiling (AGC) to 128x, 405 /* Set the Automatic Gain Ceiling (AGC) to 128x,
389 drop VSYNC at frame drop, 406 drop VSYNC at frame drop,
390 limit exposure timing, 407 limit exposure timing,
391 drop frame when the AEC step is larger than the exposure gap */ 408 drop frame when the AEC step is larger than the exposure gap */
@@ -394,9 +411,9 @@ static const unsigned char init_ov9650[][3] =
394 and set PWDN to SLVS (slave mode vertical sync) */ 411 and set PWDN to SLVS (slave mode vertical sync) */
395 {SENSOR, OV9650_COM10, 0x42}, 412 {SENSOR, OV9650_COM10, 0x42},
396 /* Set horizontal column start high to default value */ 413 /* Set horizontal column start high to default value */
397 {SENSOR, OV9650_HSTART, 0x1a}, 414 {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
398 /* Set horizontal column end */ 415 /* Set horizontal column end */
399 {SENSOR, OV9650_HSTOP, 0xbf}, 416 {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
400 /* Complementing register to the two writes above */ 417 /* Complementing register to the two writes above */
401 {SENSOR, OV9650_HREF, 0xb2}, 418 {SENSOR, OV9650_HREF, 0xb2},
402 /* Set vertical row start high bits */ 419 /* Set vertical row start high bits */
@@ -405,10 +422,6 @@ static const unsigned char init_ov9650[][3] =
405 {SENSOR, OV9650_VSTOP, 0x7e}, 422 {SENSOR, OV9650_VSTOP, 0x7e},
406 /* Set complementing vertical frame control */ 423 /* Set complementing vertical frame control */
407 {SENSOR, OV9650_VREF, 0x10}, 424 {SENSOR, OV9650_VREF, 0x10},
408 /* Set raw RGB output format with VGA resolution */
409 {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
410 OV9650_RGB_SELECT |
411 OV9650_RAW_RGB_SELECT},
412 {SENSOR, OV9650_ADC, 0x04}, 425 {SENSOR, OV9650_ADC, 0x04},
413 {SENSOR, OV9650_HV, 0x40}, 426 {SENSOR, OV9650_HV, 0x40},
414 /* Enable denoise, and white-pixel erase */ 427 /* Enable denoise, and white-pixel erase */
@@ -417,30 +430,15 @@ static const unsigned char init_ov9650[][3] =
417 /* Set the high bits of the exposure value */ 430 /* Set the high bits of the exposure value */
418 {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)}, 431 {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)},
419 432
433 /* Enable VARIOPIXEL */
434 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
435 {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
436
420 /* Set the low bits of the exposure value */ 437 /* Set the low bits of the exposure value */
421 {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)}, 438 {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)},
422 {SENSOR, OV9650_GAIN, GAIN_DEFAULT}, 439 {SENSOR, OV9650_GAIN, GAIN_DEFAULT},
423 {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT}, 440 {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT},
424 {SENSOR, OV9650_RED, RED_GAIN_DEFAULT}, 441 {SENSOR, OV9650_RED, RED_GAIN_DEFAULT},
425
426 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
427 {SENSOR, OV9650_COM5, OV9650_SYSTEM_CLK_SEL},
428
429 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
430 {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
431 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
432 {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
433 {BRIDGE, M5602_XB_SIG_INI, 0x01},
434 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
435 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
436 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
437 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
438 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0},
439 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
440 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
441 {BRIDGE, M5602_XB_HSYNC_PARA, 0x5e},
442 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
443 {BRIDGE, M5602_XB_HSYNC_PARA, 0xde}
444}; 442};
445 443
446static const unsigned char power_down_ov9650[][3] = 444static const unsigned char power_down_ov9650[][3] =
@@ -460,43 +458,76 @@ static const unsigned char power_down_ov9650[][3] =
460 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06}, 458 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
461 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, 459 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
462 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, 460 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
463 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0} 461 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
464}; 462};
465 463
466/* Vertically and horizontally flips the image if matched, needed for machines 464static const unsigned char res_init_ov9650[][2] =
467 where the sensor is mounted upside down */ 465{
468static 466 {M5602_XB_LINE_OF_FRAME_H, 0x82},
469 const 467 {M5602_XB_LINE_OF_FRAME_L, 0x00},
470 struct dmi_system_id ov9650_flip_dmi_table[] = { 468 {M5602_XB_PIX_OF_LINE_H, 0x82},
471 { 469 {M5602_XB_PIX_OF_LINE_L, 0x00},
472 .ident = "ASUS A6VC", 470 {M5602_XB_SIG_INI, 0x01}
473 .matches = { 471};
474 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 472
475 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") 473static const unsigned char VGA_ov9650[][3] =
476 } 474{
477 }, 475 /* Moves the view window in a vertical orientation */
478 { 476 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
479 .ident = "ASUS A6VM", 477 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
480 .matches = { 478 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
481 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 479 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
482 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") 480 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
483 } 481 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
484 }, 482 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
485 { 483 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
486 .ident = "ASUS A6JC", 484 {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
487 .matches = { 485 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, /* 640 + 98 */
488 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 486 {BRIDGE, M5602_XB_HSYNC_PARA, 0xe2},
489 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") 487
490 } 488 {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
491 }, 489 OV9650_RGB_SELECT |
492 { 490 OV9650_RAW_RGB_SELECT},
493 .ident = "ASUS A6Kt", 491};
494 .matches = { 492
495 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 493static const unsigned char CIF_ov9650[][3] =
496 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") 494{
497 } 495 /* Moves the view window in a vertical orientation */
498 }, 496 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
499 { } 497 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
498 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
499 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
500 {BRIDGE, M5602_XB_VSYNC_PARA, 0x20}, /* 288 */
501 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
502 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
503 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
504 {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
505 {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 352 + 98 */
506 {BRIDGE, M5602_XB_HSYNC_PARA, 0xc2},
507
508 {SENSOR, OV9650_COM7, OV9650_CIF_SELECT |
509 OV9650_RGB_SELECT |
510 OV9650_RAW_RGB_SELECT},
511};
512
513static const unsigned char QVGA_ov9650[][3] =
514{
515 /* Moves the view window in a vertical orientation */
516 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
517 {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
518 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
519 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
520 {BRIDGE, M5602_XB_VSYNC_PARA, 0xf0}, /* 240 */
521 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
522 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
523 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
524 {BRIDGE, M5602_XB_HSYNC_PARA, 0x31}, /* 50 */
525 {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 320 + 50 */
526 {BRIDGE, M5602_XB_HSYNC_PARA, 0x71},
527
528 {SENSOR, OV9650_COM7, OV9650_QVGA_SELECT |
529 OV9650_RGB_SELECT |
530 OV9650_RAW_RGB_SELECT},
500}; 531};
501 532
502#endif 533#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index d17ac52566e6..2e7fb91673cf 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -18,6 +18,8 @@
18 18
19#include "m5602_po1030.h" 19#include "m5602_po1030.h"
20 20
21static void po1030_dump_registers(struct sd *sd);
22
21int po1030_probe(struct sd *sd) 23int po1030_probe(struct sd *sd)
22{ 24{
23 u8 prod_id = 0, ver_id = 0, i; 25 u8 prod_id = 0, ver_id = 0, i;
@@ -38,16 +40,16 @@ int po1030_probe(struct sd *sd)
38 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { 40 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
39 u8 data = preinit_po1030[i][2]; 41 u8 data = preinit_po1030[i][2];
40 if (preinit_po1030[i][0] == SENSOR) 42 if (preinit_po1030[i][0] == SENSOR)
41 po1030_write_sensor(sd, 43 m5602_write_sensor(sd,
42 preinit_po1030[i][1], &data, 1); 44 preinit_po1030[i][1], &data, 1);
43 else 45 else
44 m5602_write_bridge(sd, preinit_po1030[i][1], data); 46 m5602_write_bridge(sd, preinit_po1030[i][1], data);
45 } 47 }
46 48
47 if (po1030_read_sensor(sd, 0x3, &prod_id, 1)) 49 if (m5602_read_sensor(sd, 0x3, &prod_id, 1))
48 return -ENODEV; 50 return -ENODEV;
49 51
50 if (po1030_read_sensor(sd, 0x4, &ver_id, 1)) 52 if (m5602_read_sensor(sd, 0x4, &ver_id, 1))
51 return -ENODEV; 53 return -ENODEV;
52 54
53 if ((prod_id == 0x02) && (ver_id == 0xef)) { 55 if ((prod_id == 0x02) && (ver_id == 0xef)) {
@@ -64,78 +66,12 @@ sensor_found:
64 return 0; 66 return 0;
65} 67}
66 68
67int po1030_read_sensor(struct sd *sd, const u8 address,
68 u8 *i2c_data, const u8 len)
69{
70 int err, i;
71
72 do {
73 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
74 } while ((*i2c_data & I2C_BUSY) && !err);
75
76 m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
77 sd->sensor->i2c_slave_id);
78 m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
79 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len);
80 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
81
82 for (i = 0; i < len; i++) {
83 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
84
85 PDEBUG(D_CONF, "Reading sensor register "
86 "0x%x containing 0x%x ", address, *i2c_data);
87 }
88 return (err < 0) ? err : 0;
89}
90
91int po1030_write_sensor(struct sd *sd, const u8 address,
92 u8 *i2c_data, const u8 len)
93{
94 int err, i;
95 u8 *p;
96 struct usb_device *udev = sd->gspca_dev.dev;
97 __u8 *buf = sd->gspca_dev.usb_buf;
98
99 /* The po1030 only supports one byte writes */
100 if (len > 1 || !len)
101 return -EINVAL;
102
103 memcpy(buf, sensor_urb_skeleton, sizeof(sensor_urb_skeleton));
104
105 buf[11] = sd->sensor->i2c_slave_id;
106 buf[15] = address;
107
108 p = buf + 16;
109
110 /* Copy a four byte write sequence for each byte to be written to */
111 for (i = 0; i < len; i++) {
112 memcpy(p, sensor_urb_skeleton + 16, 4);
113 p[3] = i2c_data[i];
114 p += 4;
115 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
116 address, i2c_data[i]);
117 }
118
119 /* Copy the footer */
120 memcpy(p, sensor_urb_skeleton + 20, 4);
121
122 /* Set the total length */
123 p[3] = 0x10 + len;
124
125 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
126 0x04, 0x40, 0x19,
127 0x0000, buf,
128 20 + len * 4, M5602_URB_MSG_TIMEOUT);
129
130 return (err < 0) ? err : 0;
131}
132
133int po1030_init(struct sd *sd) 69int po1030_init(struct sd *sd)
134{ 70{
135 int i, err = 0; 71 int i, err = 0;
136 72
137 /* Init the sensor */ 73 /* Init the sensor */
138 for (i = 0; i < ARRAY_SIZE(init_po1030); i++) { 74 for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
139 u8 data[2] = {0x00, 0x00}; 75 u8 data[2] = {0x00, 0x00};
140 76
141 switch (init_po1030[i][0]) { 77 switch (init_po1030[i][0]) {
@@ -147,16 +83,10 @@ int po1030_init(struct sd *sd)
147 83
148 case SENSOR: 84 case SENSOR:
149 data[0] = init_po1030[i][2]; 85 data[0] = init_po1030[i][2];
150 err = po1030_write_sensor(sd, 86 err = m5602_write_sensor(sd,
151 init_po1030[i][1], data, 1); 87 init_po1030[i][1], data, 1);
152 break; 88 break;
153 89
154 case SENSOR_LONG:
155 data[0] = init_po1030[i][2];
156 data[1] = init_po1030[i][3];
157 err = po1030_write_sensor(sd,
158 init_po1030[i][1], data, 2);
159 break;
160 default: 90 default:
161 info("Invalid stream command, exiting init"); 91 info("Invalid stream command, exiting init");
162 return -EINVAL; 92 return -EINVAL;
@@ -166,7 +96,7 @@ int po1030_init(struct sd *sd)
166 if (dump_sensor) 96 if (dump_sensor)
167 po1030_dump_registers(sd); 97 po1030_dump_registers(sd);
168 98
169 return (err < 0) ? err : 0; 99 return err;
170} 100}
171 101
172int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 102int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -175,19 +105,19 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
175 u8 i2c_data; 105 u8 i2c_data;
176 int err; 106 int err;
177 107
178 err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_H, 108 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H,
179 &i2c_data, 1); 109 &i2c_data, 1);
180 if (err < 0) 110 if (err < 0)
181 goto out; 111 goto out;
182 *val = (i2c_data << 8); 112 *val = (i2c_data << 8);
183 113
184 err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_M, 114 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M,
185 &i2c_data, 1); 115 &i2c_data, 1);
186 *val |= i2c_data; 116 *val |= i2c_data;
187 117
188 PDEBUG(D_V4L2, "Exposure read as %d", *val); 118 PDEBUG(D_V4L2, "Exposure read as %d", *val);
189out: 119out:
190 return (err < 0) ? err : 0; 120 return err;
191} 121}
192 122
193int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 123int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
@@ -202,7 +132,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
202 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", 132 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
203 i2c_data); 133 i2c_data);
204 134
205 err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H, 135 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
206 &i2c_data, 1); 136 &i2c_data, 1);
207 if (err < 0) 137 if (err < 0)
208 goto out; 138 goto out;
@@ -210,11 +140,11 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
210 i2c_data = (val & 0xff); 140 i2c_data = (val & 0xff);
211 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", 141 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
212 i2c_data); 142 i2c_data);
213 err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M, 143 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
214 &i2c_data, 1); 144 &i2c_data, 1);
215 145
216out: 146out:
217 return (err < 0) ? err : 0; 147 return err;
218} 148}
219 149
220int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 150int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -223,12 +153,12 @@ int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
223 u8 i2c_data; 153 u8 i2c_data;
224 int err; 154 int err;
225 155
226 err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, 156 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
227 &i2c_data, 1); 157 &i2c_data, 1);
228 *val = i2c_data; 158 *val = i2c_data;
229 PDEBUG(D_V4L2, "Read global gain %d", *val); 159 PDEBUG(D_V4L2, "Read global gain %d", *val);
230 160
231 return (err < 0) ? err : 0; 161 return err;
232} 162}
233 163
234int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 164int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -237,14 +167,14 @@ int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
237 u8 i2c_data; 167 u8 i2c_data;
238 int err; 168 int err;
239 169
240 err = po1030_read_sensor(sd, PO1030_REG_CONTROL2, 170 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2,
241 &i2c_data, 1); 171 &i2c_data, 1);
242 172
243 *val = (i2c_data >> 7) & 0x01 ; 173 *val = (i2c_data >> 7) & 0x01 ;
244 174
245 PDEBUG(D_V4L2, "Read hflip %d", *val); 175 PDEBUG(D_V4L2, "Read hflip %d", *val);
246 176
247 return (err < 0) ? err : 0; 177 return err;
248} 178}
249 179
250int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 180int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -254,13 +184,17 @@ int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
254 int err; 184 int err;
255 185
256 PDEBUG(D_V4L2, "Set hflip %d", val); 186 PDEBUG(D_V4L2, "Set hflip %d", val);
187 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
188 if (err < 0)
189 goto out;
257 190
258 i2c_data = (val & 0x01) << 7; 191 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
259 192
260 err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, 193 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
261 &i2c_data, 1); 194 &i2c_data, 1);
262 195
263 return (err < 0) ? err : 0; 196out:
197 return err;
264} 198}
265 199
266int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 200int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -269,14 +203,14 @@ int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
269 u8 i2c_data; 203 u8 i2c_data;
270 int err; 204 int err;
271 205
272 err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, 206 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
273 &i2c_data, 1); 207 &i2c_data, 1);
274 208
275 *val = (i2c_data >> 6) & 0x01; 209 *val = (i2c_data >> 6) & 0x01;
276 210
277 PDEBUG(D_V4L2, "Read vflip %d", *val); 211 PDEBUG(D_V4L2, "Read vflip %d", *val);
278 212
279 return (err < 0) ? err : 0; 213 return err;
280} 214}
281 215
282int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 216int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -286,13 +220,17 @@ int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
286 int err; 220 int err;
287 221
288 PDEBUG(D_V4L2, "Set vflip %d", val); 222 PDEBUG(D_V4L2, "Set vflip %d", val);
223 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
224 if (err < 0)
225 goto out;
289 226
290 i2c_data = (val & 0x01) << 6; 227 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
291 228
292 err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, 229 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
293 &i2c_data, 1); 230 &i2c_data, 1);
294 231
295 return (err < 0) ? err : 0; 232out:
233 return err;
296} 234}
297 235
298int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) 236int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -303,9 +241,9 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
303 241
304 i2c_data = val & 0xff; 242 i2c_data = val & 0xff;
305 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); 243 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
306 err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN, 244 err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
307 &i2c_data, 1); 245 &i2c_data, 1);
308 return (err < 0) ? err : 0; 246 return err;
309} 247}
310 248
311int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 249int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -314,11 +252,11 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
314 u8 i2c_data; 252 u8 i2c_data;
315 int err; 253 int err;
316 254
317 err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN, 255 err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN,
318 &i2c_data, 1); 256 &i2c_data, 1);
319 *val = i2c_data; 257 *val = i2c_data;
320 PDEBUG(D_V4L2, "Read red gain %d", *val); 258 PDEBUG(D_V4L2, "Read red gain %d", *val);
321 return (err < 0) ? err : 0; 259 return err;
322} 260}
323 261
324int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 262int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -329,9 +267,9 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
329 267
330 i2c_data = val & 0xff; 268 i2c_data = val & 0xff;
331 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); 269 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
332 err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN, 270 err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
333 &i2c_data, 1); 271 &i2c_data, 1);
334 return (err < 0) ? err : 0; 272 return err;
335} 273}
336 274
337int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 275int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -340,12 +278,12 @@ int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
340 u8 i2c_data; 278 u8 i2c_data;
341 int err; 279 int err;
342 280
343 err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN, 281 err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN,
344 &i2c_data, 1); 282 &i2c_data, 1);
345 *val = i2c_data; 283 *val = i2c_data;
346 PDEBUG(D_V4L2, "Read blue gain %d", *val); 284 PDEBUG(D_V4L2, "Read blue gain %d", *val);
347 285
348 return (err < 0) ? err : 0; 286 return err;
349} 287}
350 288
351int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 289int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -355,10 +293,10 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
355 int err; 293 int err;
356 i2c_data = val & 0xff; 294 i2c_data = val & 0xff;
357 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); 295 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
358 err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN, 296 err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
359 &i2c_data, 1); 297 &i2c_data, 1);
360 298
361 return (err < 0) ? err : 0; 299 return err;
362} 300}
363 301
364int po1030_power_down(struct sd *sd) 302int po1030_power_down(struct sd *sd)
@@ -366,14 +304,14 @@ int po1030_power_down(struct sd *sd)
366 return 0; 304 return 0;
367} 305}
368 306
369void po1030_dump_registers(struct sd *sd) 307static void po1030_dump_registers(struct sd *sd)
370{ 308{
371 int address; 309 int address;
372 u8 value = 0; 310 u8 value = 0;
373 311
374 info("Dumping the po1030 sensor core registers"); 312 info("Dumping the po1030 sensor core registers");
375 for (address = 0; address < 0x7f; address++) { 313 for (address = 0; address < 0x7f; address++) {
376 po1030_read_sensor(sd, address, &value, 1); 314 m5602_read_sensor(sd, address, &value, 1);
377 info("register 0x%x contains 0x%x", 315 info("register 0x%x contains 0x%x",
378 address, value); 316 address, value);
379 } 317 }
@@ -385,9 +323,9 @@ void po1030_dump_registers(struct sd *sd)
385 u8 old_value, ctrl_value; 323 u8 old_value, ctrl_value;
386 u8 test_value[2] = {0xff, 0xff}; 324 u8 test_value[2] = {0xff, 0xff};
387 325
388 po1030_read_sensor(sd, address, &old_value, 1); 326 m5602_read_sensor(sd, address, &old_value, 1);
389 po1030_write_sensor(sd, address, test_value, 1); 327 m5602_write_sensor(sd, address, test_value, 1);
390 po1030_read_sensor(sd, address, &ctrl_value, 1); 328 m5602_read_sensor(sd, address, &ctrl_value, 1);
391 329
392 if (ctrl_value == test_value[0]) 330 if (ctrl_value == test_value[0])
393 info("register 0x%x is writeable", address); 331 info("register 0x%x is writeable", address);
@@ -395,6 +333,6 @@ void po1030_dump_registers(struct sd *sd)
395 info("register 0x%x is read only", address); 333 info("register 0x%x is read only", address);
396 334
397 /* Restore original value */ 335 /* Restore original value */
398 po1030_write_sensor(sd, address, &old_value, 1); 336 m5602_write_sensor(sd, address, &old_value, 1);
399 } 337 }
400} 338}
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index a0b75ff61d79..def39d5bcec6 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -10,7 +10,7 @@
10 * v4l2 interface modeled after the V4L2 driver 10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers 11 * for SN9C10x PC Camera Controllers
12 * 12 *
13 * Register defines taken from Pascal Stangs Proxycon Armlib 13 * Register defines taken from Pascal Stangs Procyon Armlib
14 * 14 *
15 * This program is free software; you can redistribute it and/or 15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as 16 * modify it under the terms of the GNU General Public License as
@@ -128,13 +128,6 @@ int po1030_probe(struct sd *sd);
128int po1030_init(struct sd *sd); 128int po1030_init(struct sd *sd);
129int po1030_power_down(struct sd *sd); 129int po1030_power_down(struct sd *sd);
130 130
131void po1030_dump_registers(struct sd *sd);
132
133int po1030_read_sensor(struct sd *sd, const u8 address,
134 u8 *i2c_data, const u8 len);
135int po1030_write_sensor(struct sd *sd, const u8 address,
136 u8 *i2c_data, const u8 len);
137
138int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 131int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
139int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 132int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
140int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 133int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -152,6 +145,7 @@ static struct m5602_sensor po1030 = {
152 .name = "PO1030", 145 .name = "PO1030",
153 146
154 .i2c_slave_id = 0xdc, 147 .i2c_slave_id = 0xdc,
148 .i2c_regW = 1,
155 149
156 .probe = po1030_probe, 150 .probe = po1030_probe,
157 .init = po1030_init, 151 .init = po1030_init,
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 14b1eac5b812..e564a61a72d7 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -18,6 +18,40 @@
18 18
19#include "m5602_s5k4aa.h" 19#include "m5602_s5k4aa.h"
20 20
21static
22 const
23 struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
24 {
25 .ident = "Fujitsu-Siemens Amilo Xa 2528",
26 .matches = {
27 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
28 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
29 }
30 }, {
31 .ident = "Fujitsu-Siemens Amilo Xi 2550",
32 .matches = {
33 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
34 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
35 }
36 }, {
37 .ident = "MSI GX700",
38 .matches = {
39 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
40 DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
41 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
42 }
43 }, {
44 .ident = "MSI GX700/GX705/EX700",
45 .matches = {
46 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
47 DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700")
48 }
49 },
50 { }
51};
52
53static void s5k4aa_dump_registers(struct sd *sd);
54
21int s5k4aa_probe(struct sd *sd) 55int s5k4aa_probe(struct sd *sd)
22{ 56{
23 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 57 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -49,7 +83,7 @@ int s5k4aa_probe(struct sd *sd)
49 83
50 case SENSOR: 84 case SENSOR:
51 data[0] = preinit_s5k4aa[i][2]; 85 data[0] = preinit_s5k4aa[i][2];
52 err = s5k4aa_write_sensor(sd, 86 err = m5602_write_sensor(sd,
53 preinit_s5k4aa[i][1], 87 preinit_s5k4aa[i][1],
54 data, 1); 88 data, 1);
55 break; 89 break;
@@ -57,7 +91,7 @@ int s5k4aa_probe(struct sd *sd)
57 case SENSOR_LONG: 91 case SENSOR_LONG:
58 data[0] = preinit_s5k4aa[i][2]; 92 data[0] = preinit_s5k4aa[i][2];
59 data[1] = preinit_s5k4aa[i][3]; 93 data[1] = preinit_s5k4aa[i][3];
60 err = s5k4aa_write_sensor(sd, 94 err = m5602_write_sensor(sd,
61 preinit_s5k4aa[i][1], 95 preinit_s5k4aa[i][1],
62 data, 2); 96 data, 2);
63 break; 97 break;
@@ -68,13 +102,14 @@ int s5k4aa_probe(struct sd *sd)
68 } 102 }
69 103
70 /* Test some registers, but we don't know their exact meaning yet */ 104 /* Test some registers, but we don't know their exact meaning yet */
71 if (s5k4aa_read_sensor(sd, 0x00, prod_id, sizeof(prod_id))) 105 if (m5602_read_sensor(sd, 0x00, prod_id, sizeof(prod_id)))
72 return -ENODEV; 106 return -ENODEV;
73 107
74 if (memcmp(prod_id, expected_prod_id, sizeof(prod_id))) 108 if (memcmp(prod_id, expected_prod_id, sizeof(prod_id)))
75 return -ENODEV; 109 return -ENODEV;
76 else 110 else
77 info("Detected a s5k4aa sensor"); 111 info("Detected a s5k4aa sensor");
112
78sensor_found: 113sensor_found:
79 sd->gspca_dev.cam.cam_mode = s5k4aa.modes; 114 sd->gspca_dev.cam.cam_mode = s5k4aa.modes;
80 sd->gspca_dev.cam.nmodes = s5k4aa.nmodes; 115 sd->gspca_dev.cam.nmodes = s5k4aa.nmodes;
@@ -84,90 +119,6 @@ sensor_found:
84 return 0; 119 return 0;
85} 120}
86 121
87int s5k4aa_read_sensor(struct sd *sd, const u8 address,
88 u8 *i2c_data, const u8 len)
89{
90 int err, i;
91
92 do {
93 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
94 } while ((*i2c_data & I2C_BUSY) && !err);
95 if (err < 0)
96 goto out;
97
98 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
99 sd->sensor->i2c_slave_id);
100 if (err < 0)
101 goto out;
102
103 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
104 if (err < 0)
105 goto out;
106
107 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
108 if (err < 0)
109 goto out;
110
111 do {
112 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
113 } while ((*i2c_data & I2C_BUSY) && !err);
114 if (err < 0)
115 goto out;
116
117 for (i = 0; (i < len) & !err; i++) {
118 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
119
120 PDEBUG(D_CONF, "Reading sensor register "
121 "0x%x containing 0x%x ", address, *i2c_data);
122 }
123out:
124 return (err < 0) ? err : 0;
125}
126
127int s5k4aa_write_sensor(struct sd *sd, const u8 address,
128 u8 *i2c_data, const u8 len)
129{
130 int err, i;
131 u8 *p;
132 struct usb_device *udev = sd->gspca_dev.dev;
133 __u8 *buf = sd->gspca_dev.usb_buf;
134
135 /* No sensor with a data width larger than 16 bits has yet been seen */
136 if (len > 2 || !len)
137 return -EINVAL;
138
139 memcpy(buf, sensor_urb_skeleton,
140 sizeof(sensor_urb_skeleton));
141
142 buf[11] = sd->sensor->i2c_slave_id;
143 buf[15] = address;
144
145 /* Special case larger sensor writes */
146 p = buf + 16;
147
148 /* Copy a four byte write sequence for each byte to be written to */
149 for (i = 0; i < len; i++) {
150 memcpy(p, sensor_urb_skeleton + 16, 4);
151 p[3] = i2c_data[i];
152 p += 4;
153 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
154 address, i2c_data[i]);
155 }
156
157 /* Copy the tailer */
158 memcpy(p, sensor_urb_skeleton + 20, 4);
159
160 /* Set the total length */
161 p[3] = 0x10 + len;
162
163 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
164 0x04, 0x40, 0x19,
165 0x0000, buf,
166 20 + len * 4, M5602_URB_MSG_TIMEOUT);
167
168 return (err < 0) ? err : 0;
169}
170
171int s5k4aa_init(struct sd *sd) 122int s5k4aa_init(struct sd *sd)
172{ 123{
173 int i, err = 0; 124 int i, err = 0;
@@ -184,14 +135,14 @@ int s5k4aa_init(struct sd *sd)
184 135
185 case SENSOR: 136 case SENSOR:
186 data[0] = init_s5k4aa[i][2]; 137 data[0] = init_s5k4aa[i][2];
187 err = s5k4aa_write_sensor(sd, 138 err = m5602_write_sensor(sd,
188 init_s5k4aa[i][1], data, 1); 139 init_s5k4aa[i][1], data, 1);
189 break; 140 break;
190 141
191 case SENSOR_LONG: 142 case SENSOR_LONG:
192 data[0] = init_s5k4aa[i][2]; 143 data[0] = init_s5k4aa[i][2];
193 data[1] = init_s5k4aa[i][3]; 144 data[1] = init_s5k4aa[i][3];
194 err = s5k4aa_write_sensor(sd, 145 err = m5602_write_sensor(sd,
195 init_s5k4aa[i][1], data, 2); 146 init_s5k4aa[i][1], data, 2);
196 break; 147 break;
197 default: 148 default:
@@ -206,21 +157,21 @@ int s5k4aa_init(struct sd *sd)
206 if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) { 157 if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) {
207 u8 data = 0x02; 158 u8 data = 0x02;
208 info("vertical flip quirk active"); 159 info("vertical flip quirk active");
209 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 160 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
210 s5k4aa_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); 161 m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
211 data |= S5K4AA_RM_V_FLIP; 162 data |= S5K4AA_RM_V_FLIP;
212 data &= ~S5K4AA_RM_H_FLIP; 163 data &= ~S5K4AA_RM_H_FLIP;
213 s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 164 m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
214 165
215 /* Decrement COLSTART to preserve color order (BGGR) */ 166 /* Decrement COLSTART to preserve color order (BGGR) */
216 s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 167 m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
217 data--; 168 data--;
218 s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 169 m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
219 170
220 /* Increment ROWSTART to preserve color order (BGGR) */ 171 /* Increment ROWSTART to preserve color order (BGGR) */
221 s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 172 m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
222 data++; 173 data++;
223 s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 174 m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
224 } 175 }
225 176
226 return (err < 0) ? err : 0; 177 return (err < 0) ? err : 0;
@@ -237,20 +188,20 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
237 u8 data = S5K4AA_PAGE_MAP_2; 188 u8 data = S5K4AA_PAGE_MAP_2;
238 int err; 189 int err;
239 190
240 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 191 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
241 if (err < 0) 192 if (err < 0)
242 goto out; 193 goto out;
243 194
244 err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); 195 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
245 if (err < 0) 196 if (err < 0)
246 goto out; 197 goto out;
247 198
248 *val = data << 8; 199 *val = data << 8;
249 err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); 200 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
250 *val |= data; 201 *val |= data;
251 PDEBUG(D_V4L2, "Read exposure %d", *val); 202 PDEBUG(D_V4L2, "Read exposure %d", *val);
252out: 203out:
253 return (err < 0) ? err : 0; 204 return err;
254} 205}
255 206
256int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 207int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
@@ -260,17 +211,17 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
260 int err; 211 int err;
261 212
262 PDEBUG(D_V4L2, "Set exposure to %d", val); 213 PDEBUG(D_V4L2, "Set exposure to %d", val);
263 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 214 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
264 if (err < 0) 215 if (err < 0)
265 goto out; 216 goto out;
266 data = (val >> 8) & 0xff; 217 data = (val >> 8) & 0xff;
267 err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); 218 err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
268 if (err < 0) 219 if (err < 0)
269 goto out; 220 goto out;
270 data = val & 0xff; 221 data = val & 0xff;
271 err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); 222 err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
272out: 223out:
273 return (err < 0) ? err : 0; 224 return err;
274} 225}
275 226
276int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 227int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -279,16 +230,16 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
279 u8 data = S5K4AA_PAGE_MAP_2; 230 u8 data = S5K4AA_PAGE_MAP_2;
280 int err; 231 int err;
281 232
282 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 233 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
283 if (err < 0) 234 if (err < 0)
284 goto out; 235 goto out;
285 236
286 err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 237 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
287 *val = (data & S5K4AA_RM_V_FLIP) >> 7; 238 *val = (data & S5K4AA_RM_V_FLIP) >> 7;
288 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 239 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
289 240
290out: 241out:
291 return (err < 0) ? err : 0; 242 return err;
292} 243}
293 244
294int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 245int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -298,35 +249,35 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
298 int err; 249 int err;
299 250
300 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 251 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
301 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 252 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
302 if (err < 0) 253 if (err < 0)
303 goto out; 254 goto out;
304 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 255 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
305 if (err < 0) 256 if (err < 0)
306 goto out; 257 goto out;
307 data = ((data & ~S5K4AA_RM_V_FLIP) 258 data = ((data & ~S5K4AA_RM_V_FLIP)
308 | ((val & 0x01) << 7)); 259 | ((val & 0x01) << 7));
309 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 260 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
310 if (err < 0) 261 if (err < 0)
311 goto out; 262 goto out;
312 263
313 if (val) { 264 if (val) {
314 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 265 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
315 if (err < 0) 266 if (err < 0)
316 goto out; 267 goto out;
317 268
318 data++; 269 data++;
319 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 270 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
320 } else { 271 } else {
321 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 272 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
322 if (err < 0) 273 if (err < 0)
323 goto out; 274 goto out;
324 275
325 data--; 276 data--;
326 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 277 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
327 } 278 }
328out: 279out:
329 return (err < 0) ? err : 0; 280 return err;
330} 281}
331 282
332int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 283int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -335,15 +286,15 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
335 u8 data = S5K4AA_PAGE_MAP_2; 286 u8 data = S5K4AA_PAGE_MAP_2;
336 int err; 287 int err;
337 288
338 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 289 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
339 if (err < 0) 290 if (err < 0)
340 goto out; 291 goto out;
341 292
342 err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 293 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
343 *val = (data & S5K4AA_RM_H_FLIP) >> 6; 294 *val = (data & S5K4AA_RM_H_FLIP) >> 6;
344 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 295 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
345out: 296out:
346 return (err < 0) ? err : 0; 297 return err;
347} 298}
348 299
349int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 300int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -354,35 +305,35 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
354 305
355 PDEBUG(D_V4L2, "Set horizontal flip to %d", 306 PDEBUG(D_V4L2, "Set horizontal flip to %d",
356 val); 307 val);
357 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 308 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
358 if (err < 0) 309 if (err < 0)
359 goto out; 310 goto out;
360 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 311 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
361 if (err < 0) 312 if (err < 0)
362 goto out; 313 goto out;
363 314
364 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); 315 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
365 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 316 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
366 if (err < 0) 317 if (err < 0)
367 goto out; 318 goto out;
368 319
369 if (val) { 320 if (val) {
370 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 321 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
371 if (err < 0) 322 if (err < 0)
372 goto out; 323 goto out;
373 data++; 324 data++;
374 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 325 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
375 if (err < 0) 326 if (err < 0)
376 goto out; 327 goto out;
377 } else { 328 } else {
378 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 329 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
379 if (err < 0) 330 if (err < 0)
380 goto out; 331 goto out;
381 data--; 332 data--;
382 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 333 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
383 } 334 }
384out: 335out:
385 return (err < 0) ? err : 0; 336 return err;
386} 337}
387 338
388int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 339int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -391,16 +342,16 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
391 u8 data = S5K4AA_PAGE_MAP_2; 342 u8 data = S5K4AA_PAGE_MAP_2;
392 int err; 343 int err;
393 344
394 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 345 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
395 if (err < 0) 346 if (err < 0)
396 goto out; 347 goto out;
397 348
398 err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); 349 err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
399 *val = data; 350 *val = data;
400 PDEBUG(D_V4L2, "Read gain %d", *val); 351 PDEBUG(D_V4L2, "Read gain %d", *val);
401 352
402out: 353out:
403 return (err < 0) ? err : 0; 354 return err;
404} 355}
405 356
406int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) 357int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -410,28 +361,28 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
410 int err; 361 int err;
411 362
412 PDEBUG(D_V4L2, "Set gain to %d", val); 363 PDEBUG(D_V4L2, "Set gain to %d", val);
413 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 364 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
414 if (err < 0) 365 if (err < 0)
415 goto out; 366 goto out;
416 367
417 data = val & 0xff; 368 data = val & 0xff;
418 err = s5k4aa_write_sensor(sd, S5K4AA_GAIN_2, &data, 1); 369 err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1);
419 370
420out: 371out:
421 return (err < 0) ? err : 0; 372 return err;
422} 373}
423 374
424void s5k4aa_dump_registers(struct sd *sd) 375static void s5k4aa_dump_registers(struct sd *sd)
425{ 376{
426 int address; 377 int address;
427 u8 page, old_page; 378 u8 page, old_page;
428 s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); 379 m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
429 for (page = 0; page < 16; page++) { 380 for (page = 0; page < 16; page++) {
430 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); 381 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
431 info("Dumping the s5k4aa register state for page 0x%x", page); 382 info("Dumping the s5k4aa register state for page 0x%x", page);
432 for (address = 0; address <= 0xff; address++) { 383 for (address = 0; address <= 0xff; address++) {
433 u8 value = 0; 384 u8 value = 0;
434 s5k4aa_read_sensor(sd, address, &value, 1); 385 m5602_read_sensor(sd, address, &value, 1);
435 info("register 0x%x contains 0x%x", 386 info("register 0x%x contains 0x%x",
436 address, value); 387 address, value);
437 } 388 }
@@ -439,15 +390,15 @@ void s5k4aa_dump_registers(struct sd *sd)
439 info("s5k4aa register state dump complete"); 390 info("s5k4aa register state dump complete");
440 391
441 for (page = 0; page < 16; page++) { 392 for (page = 0; page < 16; page++) {
442 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); 393 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
443 info("Probing for which registers that are " 394 info("Probing for which registers that are "
444 "read/write for page 0x%x", page); 395 "read/write for page 0x%x", page);
445 for (address = 0; address <= 0xff; address++) { 396 for (address = 0; address <= 0xff; address++) {
446 u8 old_value, ctrl_value, test_value = 0xff; 397 u8 old_value, ctrl_value, test_value = 0xff;
447 398
448 s5k4aa_read_sensor(sd, address, &old_value, 1); 399 m5602_read_sensor(sd, address, &old_value, 1);
449 s5k4aa_write_sensor(sd, address, &test_value, 1); 400 m5602_write_sensor(sd, address, &test_value, 1);
450 s5k4aa_read_sensor(sd, address, &ctrl_value, 1); 401 m5602_read_sensor(sd, address, &ctrl_value, 1);
451 402
452 if (ctrl_value == test_value) 403 if (ctrl_value == test_value)
453 info("register 0x%x is writeable", address); 404 info("register 0x%x is writeable", address);
@@ -455,9 +406,9 @@ void s5k4aa_dump_registers(struct sd *sd)
455 info("register 0x%x is read only", address); 406 info("register 0x%x is read only", address);
456 407
457 /* Restore original value */ 408 /* Restore original value */
458 s5k4aa_write_sensor(sd, address, &old_value, 1); 409 m5602_write_sensor(sd, address, &old_value, 1);
459 } 410 }
460 } 411 }
461 info("Read/write register probing complete"); 412 info("Read/write register probing complete");
462 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); 413 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
463} 414}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index eaef67655afa..1f88b0d040c4 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -41,11 +41,10 @@
41#define S5K4AA_WINDOW_HEIGHT_LO 0x09 41#define S5K4AA_WINDOW_HEIGHT_LO 0x09
42#define S5K4AA_WINDOW_WIDTH_HI 0x0a 42#define S5K4AA_WINDOW_WIDTH_HI 0x0a
43#define S5K4AA_WINDOW_WIDTH_LO 0x0b 43#define S5K4AA_WINDOW_WIDTH_LO 0x0b
44#define S5K4AA_GLOBAL_GAIN__ 0x0f /* Only a guess ATM !!! */ 44#define S5K4AA_GLOBAL_GAIN__ 0x0f
45#define S5K4AA_H_BLANK_HI__ 0x1d /* Only a guess ATM !!! sync lost 45/* sync lost, if too low, reduces frame rate if too high */
46 if too low, reduces frame rate 46#define S5K4AA_H_BLANK_HI__ 0x1d
47 if too high */ 47#define S5K4AA_H_BLANK_LO__ 0x1e
48#define S5K4AA_H_BLANK_LO__ 0x1e /* Only a guess ATM !!! */
49#define S5K4AA_EXPOSURE_HI 0x17 48#define S5K4AA_EXPOSURE_HI 0x17
50#define S5K4AA_EXPOSURE_LO 0x18 49#define S5K4AA_EXPOSURE_LO 0x18
51#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ 50#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */
@@ -68,13 +67,6 @@ int s5k4aa_probe(struct sd *sd);
68int s5k4aa_init(struct sd *sd); 67int s5k4aa_init(struct sd *sd);
69int s5k4aa_power_down(struct sd *sd); 68int s5k4aa_power_down(struct sd *sd);
70 69
71void s5k4aa_dump_registers(struct sd *sd);
72
73int s5k4aa_read_sensor(struct sd *sd, const u8 address,
74 u8 *i2c_data, const u8 len);
75int s5k4aa_write_sensor(struct sd *sd, const u8 address,
76 u8 *i2c_data, const u8 len);
77
78int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 70int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
79int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 71int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
80int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 72int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -89,9 +81,8 @@ static struct m5602_sensor s5k4aa = {
89 .probe = s5k4aa_probe, 81 .probe = s5k4aa_probe,
90 .init = s5k4aa_init, 82 .init = s5k4aa_init,
91 .power_down = s5k4aa_power_down, 83 .power_down = s5k4aa_power_down,
92 .read_sensor = s5k4aa_read_sensor,
93 .write_sensor = s5k4aa_write_sensor,
94 .i2c_slave_id = 0x5a, 84 .i2c_slave_id = 0x5a,
85 .i2c_regW = 2,
95 .nctrls = 4, 86 .nctrls = 4,
96 .ctrls = { 87 .ctrls = {
97 { 88 {
@@ -338,32 +329,4 @@ static const unsigned char init_s5k4aa[][4] =
338 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} 329 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
339}; 330};
340 331
341static
342 const
343 struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
344 {
345 .ident = "Fujitsu-Siemens Amilo Xa 2528",
346 .matches = {
347 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
348 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
349 }
350 },
351 {
352 .ident = "Fujitsu-Siemens Amilo Xi 2550",
353 .matches = {
354 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
355 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
356 }
357 },
358 {
359 .ident = "MSI GX700",
360 .matches = {
361 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
362 DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
363 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
364 }
365 },
366 { }
367};
368
369#endif 332#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 8988a728e0b4..af3f2dc2c702 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -18,6 +18,8 @@
18 18
19#include "m5602_s5k83a.h" 19#include "m5602_s5k83a.h"
20 20
21static void s5k83a_dump_registers(struct sd *sd);
22
21int s5k83a_probe(struct sd *sd) 23int s5k83a_probe(struct sd *sd)
22{ 24{
23 u8 prod_id = 0, ver_id = 0; 25 u8 prod_id = 0, ver_id = 0;
@@ -39,7 +41,7 @@ int s5k83a_probe(struct sd *sd)
39 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) { 41 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
40 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]}; 42 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
41 if (preinit_s5k83a[i][0] == SENSOR) 43 if (preinit_s5k83a[i][0] == SENSOR)
42 err = s5k83a_write_sensor(sd, preinit_s5k83a[i][1], 44 err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
43 data, 2); 45 data, 2);
44 else 46 else
45 err = m5602_write_bridge(sd, preinit_s5k83a[i][1], 47 err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
@@ -49,10 +51,10 @@ int s5k83a_probe(struct sd *sd)
49 /* We don't know what register (if any) that contain the product id 51 /* We don't know what register (if any) that contain the product id
50 * Just pick the first addresses that seem to produce the same results 52 * Just pick the first addresses that seem to produce the same results
51 * on multiple machines */ 53 * on multiple machines */
52 if (s5k83a_read_sensor(sd, 0x00, &prod_id, 1)) 54 if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
53 return -ENODEV; 55 return -ENODEV;
54 56
55 if (s5k83a_read_sensor(sd, 0x01, &ver_id, 1)) 57 if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
56 return -ENODEV; 58 return -ENODEV;
57 59
58 if ((prod_id == 0xff) || (ver_id == 0xff)) 60 if ((prod_id == 0xff) || (ver_id == 0xff))
@@ -68,91 +70,6 @@ sensor_found:
68 return 0; 70 return 0;
69} 71}
70 72
71int s5k83a_read_sensor(struct sd *sd, const u8 address,
72 u8 *i2c_data, const u8 len)
73{
74 int err, i;
75
76 do {
77 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
78 } while ((*i2c_data & I2C_BUSY) && !err);
79 if (err < 0)
80 goto out;
81
82 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
83 sd->sensor->i2c_slave_id);
84 if (err < 0)
85 goto out;
86
87 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
88 if (err < 0)
89 goto out;
90
91 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
92 if (err < 0)
93 goto out;
94
95 do {
96 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
97 } while ((*i2c_data & I2C_BUSY) && !err);
98
99 if (err < 0)
100 goto out;
101 for (i = 0; i < len && !len; i++) {
102 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
103
104 PDEBUG(D_CONF, "Reading sensor register "
105 "0x%x containing 0x%x ", address, *i2c_data);
106 }
107
108out:
109 return (err < 0) ? err : 0;
110}
111
112int s5k83a_write_sensor(struct sd *sd, const u8 address,
113 u8 *i2c_data, const u8 len)
114{
115 int err, i;
116 u8 *p;
117 struct usb_device *udev = sd->gspca_dev.dev;
118 __u8 *buf = sd->gspca_dev.usb_buf;
119
120 /* No sensor with a data width larger than 16 bits has yet been seen */
121 if (len > 2 || !len)
122 return -EINVAL;
123
124 memcpy(buf, sensor_urb_skeleton,
125 sizeof(sensor_urb_skeleton));
126
127 buf[11] = sd->sensor->i2c_slave_id;
128 buf[15] = address;
129
130 /* Special case larger sensor writes */
131 p = buf + 16;
132
133 /* Copy a four byte write sequence for each byte to be written to */
134 for (i = 0; i < len; i++) {
135 memcpy(p, sensor_urb_skeleton + 16, 4);
136 p[3] = i2c_data[i];
137 p += 4;
138 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
139 address, i2c_data[i]);
140 }
141
142 /* Copy the tailer */
143 memcpy(p, sensor_urb_skeleton + 20, 4);
144
145 /* Set the total length */
146 p[3] = 0x10 + len;
147
148 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
149 0x04, 0x40, 0x19,
150 0x0000, buf,
151 20 + len * 4, M5602_URB_MSG_TIMEOUT);
152
153 return (err < 0) ? err : 0;
154}
155
156int s5k83a_init(struct sd *sd) 73int s5k83a_init(struct sd *sd)
157{ 74{
158 int i, err = 0; 75 int i, err = 0;
@@ -169,14 +86,14 @@ int s5k83a_init(struct sd *sd)
169 86
170 case SENSOR: 87 case SENSOR:
171 data[0] = init_s5k83a[i][2]; 88 data[0] = init_s5k83a[i][2];
172 err = s5k83a_write_sensor(sd, 89 err = m5602_write_sensor(sd,
173 init_s5k83a[i][1], data, 1); 90 init_s5k83a[i][1], data, 1);
174 break; 91 break;
175 92
176 case SENSOR_LONG: 93 case SENSOR_LONG:
177 data[0] = init_s5k83a[i][2]; 94 data[0] = init_s5k83a[i][2];
178 data[1] = init_s5k83a[i][3]; 95 data[1] = init_s5k83a[i][3];
179 err = s5k83a_write_sensor(sd, 96 err = m5602_write_sensor(sd,
180 init_s5k83a[i][1], data, 2); 97 init_s5k83a[i][1], data, 2);
181 break; 98 break;
182 default: 99 default:
@@ -200,14 +117,14 @@ void s5k83a_dump_registers(struct sd *sd)
200{ 117{
201 int address; 118 int address;
202 u8 page, old_page; 119 u8 page, old_page;
203 s5k83a_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); 120 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
204 121
205 for (page = 0; page < 16; page++) { 122 for (page = 0; page < 16; page++) {
206 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 123 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
207 info("Dumping the s5k83a register state for page 0x%x", page); 124 info("Dumping the s5k83a register state for page 0x%x", page);
208 for (address = 0; address <= 0xff; address++) { 125 for (address = 0; address <= 0xff; address++) {
209 u8 val = 0; 126 u8 val = 0;
210 s5k83a_read_sensor(sd, address, &val, 1); 127 m5602_read_sensor(sd, address, &val, 1);
211 info("register 0x%x contains 0x%x", 128 info("register 0x%x contains 0x%x",
212 address, val); 129 address, val);
213 } 130 }
@@ -215,15 +132,15 @@ void s5k83a_dump_registers(struct sd *sd)
215 info("s5k83a register state dump complete"); 132 info("s5k83a register state dump complete");
216 133
217 for (page = 0; page < 16; page++) { 134 for (page = 0; page < 16; page++) {
218 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 135 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
219 info("Probing for which registers that are read/write " 136 info("Probing for which registers that are read/write "
220 "for page 0x%x", page); 137 "for page 0x%x", page);
221 for (address = 0; address <= 0xff; address++) { 138 for (address = 0; address <= 0xff; address++) {
222 u8 old_val, ctrl_val, test_val = 0xff; 139 u8 old_val, ctrl_val, test_val = 0xff;
223 140
224 s5k83a_read_sensor(sd, address, &old_val, 1); 141 m5602_read_sensor(sd, address, &old_val, 1);
225 s5k83a_write_sensor(sd, address, &test_val, 1); 142 m5602_write_sensor(sd, address, &test_val, 1);
226 s5k83a_read_sensor(sd, address, &ctrl_val, 1); 143 m5602_read_sensor(sd, address, &ctrl_val, 1);
227 144
228 if (ctrl_val == test_val) 145 if (ctrl_val == test_val)
229 info("register 0x%x is writeable", address); 146 info("register 0x%x is writeable", address);
@@ -231,11 +148,11 @@ void s5k83a_dump_registers(struct sd *sd)
231 info("register 0x%x is read only", address); 148 info("register 0x%x is read only", address);
232 149
233 /* Restore original val */ 150 /* Restore original val */
234 s5k83a_write_sensor(sd, address, &old_val, 1); 151 m5602_write_sensor(sd, address, &old_val, 1);
235 } 152 }
236 } 153 }
237 info("Read/write register probing complete"); 154 info("Read/write register probing complete");
238 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); 155 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
239} 156}
240 157
241int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 158int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -244,11 +161,15 @@ int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
244 u8 data[2]; 161 u8 data[2];
245 struct sd *sd = (struct sd *) gspca_dev; 162 struct sd *sd = (struct sd *) gspca_dev;
246 163
247 err = s5k83a_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 164 err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
165 if (err < 0)
166 goto out;
167
248 data[1] = data[1] << 1; 168 data[1] = data[1] << 1;
249 *val = data[1]; 169 *val = data[1];
250 170
251 return (err < 0) ? err : 0; 171out:
172 return err;
252} 173}
253 174
254int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 175int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -259,23 +180,24 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
259 180
260 data[0] = 0x00; 181 data[0] = 0x00;
261 data[1] = 0x20; 182 data[1] = 0x20;
262 err = s5k83a_write_sensor(sd, 0x14, data, 2); 183 err = m5602_write_sensor(sd, 0x14, data, 2);
263 if (err < 0) 184 if (err < 0)
264 return err; 185 goto out;
265 186
266 data[0] = 0x01; 187 data[0] = 0x01;
267 data[1] = 0x00; 188 data[1] = 0x00;
268 err = s5k83a_write_sensor(sd, 0x0d, data, 2); 189 err = m5602_write_sensor(sd, 0x0d, data, 2);
269 if (err < 0) 190 if (err < 0)
270 return err; 191 goto out;
271 192
272 /* FIXME: This is not sane, we need to figure out the composition 193 /* FIXME: This is not sane, we need to figure out the composition
273 of these registers */ 194 of these registers */
274 data[0] = val >> 3; /* brightness, high 5 bits */ 195 data[0] = val >> 3; /* brightness, high 5 bits */
275 data[1] = val >> 1; /* brightness, high 7 bits */ 196 data[1] = val >> 1; /* brightness, high 7 bits */
276 err = s5k83a_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 197 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
277 198
278 return (err < 0) ? err : 0; 199out:
200 return err;
279} 201}
280 202
281int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) 203int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -284,10 +206,14 @@ int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
284 u8 data; 206 u8 data;
285 struct sd *sd = (struct sd *) gspca_dev; 207 struct sd *sd = (struct sd *) gspca_dev;
286 208
287 err = s5k83a_read_sensor(sd, S5K83A_WHITENESS, &data, 1); 209 err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1);
210 if (err < 0)
211 goto out;
288 212
289 *val = data; 213 *val = data;
290 return (err < 0) ? err : 0; 214
215out:
216 return err;
291} 217}
292 218
293int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) 219int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
@@ -297,9 +223,9 @@ int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
297 struct sd *sd = (struct sd *) gspca_dev; 223 struct sd *sd = (struct sd *) gspca_dev;
298 224
299 data[0] = val; 225 data[0] = val;
300 err = s5k83a_write_sensor(sd, S5K83A_WHITENESS, data, 1); 226 err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1);
301 227
302 return (err < 0) ? err : 0; 228 return err;
303} 229}
304 230
305int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 231int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -308,7 +234,9 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
308 u8 data[2]; 234 u8 data[2];
309 struct sd *sd = (struct sd *) gspca_dev; 235 struct sd *sd = (struct sd *) gspca_dev;
310 236
311 err = s5k83a_read_sensor(sd, S5K83A_GAIN, data, 2); 237 err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2);
238 if (err < 0)
239 goto out;
312 240
313 data[1] = data[1] & 0x3f; 241 data[1] = data[1] & 0x3f;
314 if (data[1] > S5K83A_MAXIMUM_GAIN) 242 if (data[1] > S5K83A_MAXIMUM_GAIN)
@@ -316,7 +244,8 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
316 244
317 *val = data[1]; 245 *val = data[1];
318 246
319 return (err < 0) ? err : 0; 247out:
248 return err;
320} 249}
321 250
322int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) 251int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -327,9 +256,8 @@ int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
327 256
328 data[0] = 0; 257 data[0] = 0;
329 data[1] = val; 258 data[1] = val;
330 err = s5k83a_write_sensor(sd, S5K83A_GAIN, data, 2); 259 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
331 260 return err;
332 return (err < 0) ? err : 0;
333} 261}
334 262
335int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 263int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -339,14 +267,15 @@ int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
339 struct sd *sd = (struct sd *) gspca_dev; 267 struct sd *sd = (struct sd *) gspca_dev;
340 268
341 data[0] = 0x05; 269 data[0] = 0x05;
342 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 270 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
343 if (err < 0) 271 if (err < 0)
344 return err; 272 goto out;
345 273
346 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 274 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
347 *val = (data[0] | 0x40) ? 1 : 0; 275 *val = (data[0] | 0x40) ? 1 : 0;
348 276
349 return (err < 0) ? err : 0; 277out:
278 return err;
350} 279}
351 280
352int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 281int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -356,25 +285,26 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
356 struct sd *sd = (struct sd *) gspca_dev; 285 struct sd *sd = (struct sd *) gspca_dev;
357 286
358 data[0] = 0x05; 287 data[0] = 0x05;
359 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 288 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
360 if (err < 0) 289 if (err < 0)
361 return err; 290 goto out;
362 291
363 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 292 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
364 if (err < 0) 293 if (err < 0)
365 return err; 294 goto out;
366 295
367 /* set or zero six bit, seven is hflip */ 296 /* set or zero six bit, seven is hflip */
368 data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK 297 data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
369 : (data[0] & 0x80) | S5K83A_FLIP_MASK; 298 : (data[0] & 0x80) | S5K83A_FLIP_MASK;
370 err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1); 299 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
371 if (err < 0) 300 if (err < 0)
372 return err; 301 goto out;
373 302
374 data[0] = (val) ? 0x0b : 0x0a; 303 data[0] = (val) ? 0x0b : 0x0a;
375 err = s5k83a_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); 304 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
376 305
377 return (err < 0) ? err : 0; 306out:
307 return err;
378} 308}
379 309
380int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 310int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -384,14 +314,15 @@ int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
384 struct sd *sd = (struct sd *) gspca_dev; 314 struct sd *sd = (struct sd *) gspca_dev;
385 315
386 data[0] = 0x05; 316 data[0] = 0x05;
387 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 317 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
388 if (err < 0) 318 if (err < 0)
389 return err; 319 goto out;
390 320
391 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 321 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
392 *val = (data[0] | 0x80) ? 1 : 0; 322 *val = (data[0] | 0x80) ? 1 : 0;
393 323
394 return (err < 0) ? err : 0; 324out:
325 return err;
395} 326}
396 327
397int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 328int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -401,23 +332,23 @@ int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
401 struct sd *sd = (struct sd *) gspca_dev; 332 struct sd *sd = (struct sd *) gspca_dev;
402 333
403 data[0] = 0x05; 334 data[0] = 0x05;
404 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 335 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
405 if (err < 0) 336 if (err < 0)
406 return err; 337 goto out;
407 338
408 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 339 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
409 if (err < 0) 340 if (err < 0)
410 return err; 341 goto out;
411 342
412 /* set or zero seven bit, six is vflip */ 343 /* set or zero seven bit, six is vflip */
413 data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK 344 data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
414 : (data[0] & 0x40) | S5K83A_FLIP_MASK; 345 : (data[0] & 0x40) | S5K83A_FLIP_MASK;
415 err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1); 346 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
416 if (err < 0) 347 if (err < 0)
417 return err; 348 goto out;
418 349
419 data[0] = (val) ? 0x0a : 0x0b; 350 data[0] = (val) ? 0x0a : 0x0b;
420 err = s5k83a_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); 351 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
421 352out:
422 return (err < 0) ? err : 0; 353 return err;
423} 354}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index ee3ee9cfca1d..05ccb5b57a88 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -22,15 +22,15 @@
22#include "m5602_sensor.h" 22#include "m5602_sensor.h"
23 23
24#define S5K83A_FLIP 0x01 24#define S5K83A_FLIP 0x01
25#define S5K83A_HFLIP_TUNE 0x03 25#define S5K83A_HFLIP_TUNE 0x03
26#define S5K83A_VFLIP_TUNE 0x05 26#define S5K83A_VFLIP_TUNE 0x05
27#define S5K83A_WHITENESS 0x0a 27#define S5K83A_WHITENESS 0x0a
28#define S5K83A_GAIN 0x18 28#define S5K83A_GAIN 0x18
29#define S5K83A_BRIGHTNESS 0x1b 29#define S5K83A_BRIGHTNESS 0x1b
30#define S5K83A_PAGE_MAP 0xec 30#define S5K83A_PAGE_MAP 0xec
31 31
32#define S5K83A_DEFAULT_BRIGHTNESS 0x71 32#define S5K83A_DEFAULT_BRIGHTNESS 0x71
33#define S5K83A_DEFAULT_WHITENESS 0x7e 33#define S5K83A_DEFAULT_WHITENESS 0x7e
34#define S5K83A_DEFAULT_GAIN 0x00 34#define S5K83A_DEFAULT_GAIN 0x00
35#define S5K83A_MAXIMUM_GAIN 0x3c 35#define S5K83A_MAXIMUM_GAIN 0x3c
36#define S5K83A_FLIP_MASK 0x10 36#define S5K83A_FLIP_MASK 0x10
@@ -46,13 +46,6 @@ int s5k83a_probe(struct sd *sd);
46int s5k83a_init(struct sd *sd); 46int s5k83a_init(struct sd *sd);
47int s5k83a_power_down(struct sd *sd); 47int s5k83a_power_down(struct sd *sd);
48 48
49void s5k83a_dump_registers(struct sd *sd);
50
51int s5k83a_read_sensor(struct sd *sd, const u8 address,
52 u8 *i2c_data, const u8 len);
53int s5k83a_write_sensor(struct sd *sd, const u8 address,
54 u8 *i2c_data, const u8 len);
55
56int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); 49int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
57int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); 50int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
58int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val); 51int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
@@ -64,15 +57,13 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
64int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 57int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
65int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); 58int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
66 59
67
68static struct m5602_sensor s5k83a = { 60static struct m5602_sensor s5k83a = {
69 .name = "S5K83A", 61 .name = "S5K83A",
70 .probe = s5k83a_probe, 62 .probe = s5k83a_probe,
71 .init = s5k83a_init, 63 .init = s5k83a_init,
72 .power_down = s5k83a_power_down, 64 .power_down = s5k83a_power_down,
73 .read_sensor = s5k83a_read_sensor,
74 .write_sensor = s5k83a_write_sensor,
75 .i2c_slave_id = 0x5a, 65 .i2c_slave_id = 0x5a,
66 .i2c_regW = 2,
76 .nctrls = 5, 67 .nctrls = 5,
77 .ctrls = { 68 .ctrls = {
78 { 69 {
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 60c9a48e0c02..261623f0da48 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -49,23 +49,21 @@ struct m5602_sensor {
49 /* What i2c address the sensor is connected to */ 49 /* What i2c address the sensor is connected to */
50 u8 i2c_slave_id; 50 u8 i2c_slave_id;
51 51
52 /* Width of each i2c register (in bytes) */
53 u8 i2c_regW;
54
52 /* Probes if the sensor is connected */ 55 /* Probes if the sensor is connected */
53 int (*probe)(struct sd *sd); 56 int (*probe)(struct sd *sd);
54 57
55 /* Performs a initialization sequence */ 58 /* Performs a initialization sequence */
56 int (*init)(struct sd *sd); 59 int (*init)(struct sd *sd);
57 60
61 /* Executed when the camera starts to send data */
62 int (*start)(struct sd *sd);
63
58 /* Performs a power down sequence */ 64 /* Performs a power down sequence */
59 int (*power_down)(struct sd *sd); 65 int (*power_down)(struct sd *sd);
60 66
61 /* Reads a sensor register */
62 int (*read_sensor)(struct sd *sd, const u8 address,
63 u8 *i2c_data, const u8 len);
64
65 /* Writes to a sensor register */
66 int (*write_sensor)(struct sd *sd, const u8 address,
67 u8 *i2c_data, const u8 len);
68
69 int nctrls; 67 int nctrls;
70 struct ctrl ctrls[M5602_MAX_CTRLS]; 68 struct ctrl ctrls[M5602_MAX_CTRLS];
71 69
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 277ca34a8817..3d2090e67a63 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -39,7 +39,7 @@ struct sd {
39static struct ctrl sd_ctrls[] = { 39static struct ctrl sd_ctrls[] = {
40}; 40};
41 41
42static struct v4l2_pix_format vga_mode[] = { 42static const struct v4l2_pix_format vga_mode[] = {
43 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 43 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
44 .bytesperline = 320, 44 .bytesperline = 320,
45 .sizeimage = 320 * 240 * 3 / 8 + 589, 45 .sizeimage = 320 * 240 * 3 / 8 + 589,
@@ -123,7 +123,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
123 cam = &gspca_dev->cam; 123 cam = &gspca_dev->cam;
124 cam->epaddr = 0x01; 124 cam->epaddr = 0x01;
125 cam->cam_mode = vga_mode; 125 cam->cam_mode = vga_mode;
126 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 126 cam->nmodes = ARRAY_SIZE(vga_mode);
127 sd->qindex = 1; /* set the quantization table */ 127 sd->qindex = 1; /* set the quantization table */
128 return 0; 128 return 0;
129} 129}
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index ca671194679e..ee232956c812 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -3,7 +3,18 @@
3 * 3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) 4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
5 * 5 *
6 * (This module is adapted from the ov51x-jpeg package) 6 * This module is adapted from the ov51x-jpeg package, which itself
7 * was adapted from the ov511 driver.
8 *
9 * Original copyright for the ov511 driver is:
10 *
11 * Copyright (c) 1999-2004 Mark W. McClelland
12 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
13 *
14 * ov51x-jpeg original copyright is:
15 *
16 * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org>
17 * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com>
7 * 18 *
8 * This program is free software; you can redistribute it and/or modify 19 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 20 * it under the terms of the GNU General Public License as published by
@@ -40,22 +51,18 @@ struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */ 51 struct gspca_dev gspca_dev; /* !! must be the first item */
41 52
42 /* Determined by sensor type */ 53 /* Determined by sensor type */
43 char sif; 54 __u8 sif;
44
45 unsigned char primary_i2c_slave; /* I2C write id of sensor */
46 55
47 unsigned char brightness; 56 __u8 brightness;
48 unsigned char contrast; 57 __u8 contrast;
49 unsigned char colors; 58 __u8 colors;
50 __u8 hflip; 59 __u8 hflip;
51 __u8 vflip; 60 __u8 vflip;
52 61
53 char compress; /* Should the next frame be compressed? */ 62 __u8 stopped; /* Streaming is temporarily paused */
54 char compress_inited; /* Are compression params uploaded? */
55 char stopped; /* Streaming is temporarily paused */
56 63
57 char frame_rate; /* current Framerate (OV519 only) */ 64 __u8 frame_rate; /* current Framerate (OV519 only) */
58 char clockdiv; /* clockdiv override for OV519 only */ 65 __u8 clockdiv; /* clockdiv override for OV519 only */
59 66
60 char sensor; /* Type of image sensor chip (SEN_*) */ 67 char sensor; /* Type of image sensor chip (SEN_*) */
61#define SEN_UNKNOWN 0 68#define SEN_UNKNOWN 0
@@ -67,7 +74,6 @@ struct sd {
67#define SEN_OV7670 6 74#define SEN_OV7670 6
68#define SEN_OV76BE 7 75#define SEN_OV76BE 7
69#define SEN_OV8610 8 76#define SEN_OV8610 8
70
71}; 77};
72 78
73/* V4L2 controls supported by the driver */ 79/* V4L2 controls supported by the driver */
@@ -158,7 +164,7 @@ static struct ctrl sd_ctrls[] = {
158 }, 164 },
159}; 165};
160 166
161static struct v4l2_pix_format vga_mode[] = { 167static const struct v4l2_pix_format vga_mode[] = {
162 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 168 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
163 .bytesperline = 320, 169 .bytesperline = 320,
164 .sizeimage = 320 * 240 * 3 / 8 + 590, 170 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -170,7 +176,7 @@ static struct v4l2_pix_format vga_mode[] = {
170 .colorspace = V4L2_COLORSPACE_JPEG, 176 .colorspace = V4L2_COLORSPACE_JPEG,
171 .priv = 0}, 177 .priv = 0},
172}; 178};
173static struct v4l2_pix_format sif_mode[] = { 179static const struct v4l2_pix_format sif_mode[] = {
174 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 180 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
175 .bytesperline = 176, 181 .bytesperline = 176,
176 .sizeimage = 176 * 144 * 3 / 8 + 590, 182 .sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -184,15 +190,15 @@ static struct v4l2_pix_format sif_mode[] = {
184}; 190};
185 191
186/* OV519 Camera interface register numbers */ 192/* OV519 Camera interface register numbers */
187#define OV519_CAM_H_SIZE 0x10 193#define OV519_R10_H_SIZE 0x10
188#define OV519_CAM_V_SIZE 0x11 194#define OV519_R11_V_SIZE 0x11
189#define OV519_CAM_X_OFFSETL 0x12 195#define OV519_R12_X_OFFSETL 0x12
190#define OV519_CAM_X_OFFSETH 0x13 196#define OV519_R13_X_OFFSETH 0x13
191#define OV519_CAM_Y_OFFSETL 0x14 197#define OV519_R14_Y_OFFSETL 0x14
192#define OV519_CAM_Y_OFFSETH 0x15 198#define OV519_R15_Y_OFFSETH 0x15
193#define OV519_CAM_DIVIDER 0x16 199#define OV519_R16_DIVIDER 0x16
194#define OV519_CAM_DFR 0x20 200#define OV519_R20_DFR 0x20
195#define OV519_CAM_FORMAT 0x25 201#define OV519_R25_FORMAT 0x25
196 202
197/* OV519 System Controller register numbers */ 203/* OV519 System Controller register numbers */
198#define OV519_SYS_RESET1 0x51 204#define OV519_SYS_RESET1 0x51
@@ -562,8 +568,8 @@ static const struct ov_i2c_regvals norm_7670[] = {
562 { OV7670_REG_VSTOP, 0x7a }, 568 { OV7670_REG_VSTOP, 0x7a },
563 { OV7670_REG_VREF, 0x0a }, 569 { OV7670_REG_VREF, 0x0a },
564 570
565 { OV7670_REG_COM3, 0 }, 571 { OV7670_REG_COM3, 0x00 },
566 { OV7670_REG_COM14, 0 }, 572 { OV7670_REG_COM14, 0x00 },
567/* Mystery scaling numbers */ 573/* Mystery scaling numbers */
568 { 0x70, 0x3a }, 574 { 0x70, 0x3a },
569 { 0x71, 0x35 }, 575 { 0x71, 0x35 },
@@ -595,8 +601,8 @@ static const struct ov_i2c_regvals norm_7670[] = {
595 { OV7670_REG_COM8, OV7670_COM8_FASTAEC 601 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
596 | OV7670_COM8_AECSTEP 602 | OV7670_COM8_AECSTEP
597 | OV7670_COM8_BFILT }, 603 | OV7670_COM8_BFILT },
598 { OV7670_REG_GAIN, 0 }, 604 { OV7670_REG_GAIN, 0x00 },
599 { OV7670_REG_AECH, 0 }, 605 { OV7670_REG_AECH, 0x00 },
600 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ 606 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
601 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ 607 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
602 { OV7670_REG_BD50MAX, 0x05 }, 608 { OV7670_REG_BD50MAX, 0x05 },
@@ -634,16 +640,16 @@ static const struct ov_i2c_regvals norm_7670[] = {
634 { OV7670_REG_COM12, 0x78 }, 640 { OV7670_REG_COM12, 0x78 },
635 { 0x4d, 0x40 }, 641 { 0x4d, 0x40 },
636 { 0x4e, 0x20 }, 642 { 0x4e, 0x20 },
637 { OV7670_REG_GFIX, 0 }, 643 { OV7670_REG_GFIX, 0x00 },
638 { 0x6b, 0x4a }, 644 { 0x6b, 0x4a },
639 { 0x74, 0x10 }, 645 { 0x74, 0x10 },
640 { 0x8d, 0x4f }, 646 { 0x8d, 0x4f },
641 { 0x8e, 0 }, 647 { 0x8e, 0x00 },
642 { 0x8f, 0 }, 648 { 0x8f, 0x00 },
643 { 0x90, 0 }, 649 { 0x90, 0x00 },
644 { 0x91, 0 }, 650 { 0x91, 0x00 },
645 { 0x96, 0 }, 651 { 0x96, 0x00 },
646 { 0x9a, 0 }, 652 { 0x9a, 0x00 },
647 { 0xb0, 0x84 }, 653 { 0xb0, 0x84 },
648 { 0xb1, 0x0c }, 654 { 0xb1, 0x0c },
649 { 0xb2, 0x0e }, 655 { 0xb2, 0x0e },
@@ -681,17 +687,17 @@ static const struct ov_i2c_regvals norm_7670[] = {
681/* Matrix coefficients */ 687/* Matrix coefficients */
682 { 0x4f, 0x80 }, 688 { 0x4f, 0x80 },
683 { 0x50, 0x80 }, 689 { 0x50, 0x80 },
684 { 0x51, 0 }, 690 { 0x51, 0x00 },
685 { 0x52, 0x22 }, 691 { 0x52, 0x22 },
686 { 0x53, 0x5e }, 692 { 0x53, 0x5e },
687 { 0x54, 0x80 }, 693 { 0x54, 0x80 },
688 { 0x58, 0x9e }, 694 { 0x58, 0x9e },
689 695
690 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN }, 696 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
691 { OV7670_REG_EDGE, 0 }, 697 { OV7670_REG_EDGE, 0x00 },
692 { 0x75, 0x05 }, 698 { 0x75, 0x05 },
693 { 0x76, 0xe1 }, 699 { 0x76, 0xe1 },
694 { 0x4c, 0 }, 700 { 0x4c, 0x00 },
695 { 0x77, 0x01 }, 701 { 0x77, 0x01 },
696 { OV7670_REG_COM13, OV7670_COM13_GAMMA 702 { OV7670_REG_COM13, OV7670_COM13_GAMMA
697 | OV7670_COM13_UVSAT 703 | OV7670_COM13_UVSAT
@@ -704,7 +710,7 @@ static const struct ov_i2c_regvals norm_7670[] = {
704 { 0x34, 0x11 }, 710 { 0x34, 0x11 },
705 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, 711 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
706 { 0xa4, 0x88 }, 712 { 0xa4, 0x88 },
707 { 0x96, 0 }, 713 { 0x96, 0x00 },
708 { 0x97, 0x30 }, 714 { 0x97, 0x30 },
709 { 0x98, 0x20 }, 715 { 0x98, 0x20 },
710 { 0x99, 0x30 }, 716 { 0x99, 0x30 },
@@ -942,11 +948,11 @@ static int i2c_w(struct sd *sd,
942 948
943 /* Initiate 3-byte write cycle */ 949 /* Initiate 3-byte write cycle */
944 rc = reg_w(sd, R518_I2C_CTL, 0x01); 950 rc = reg_w(sd, R518_I2C_CTL, 0x01);
951 if (rc < 0)
952 return rc;
945 953
946 /* wait for write complete */ 954 /* wait for write complete */
947 msleep(4); 955 msleep(4);
948 if (rc < 0)
949 return rc;
950 return reg_r8(sd, R518_I2C_CTL); 956 return reg_r8(sd, R518_I2C_CTL);
951} 957}
952 958
@@ -1029,7 +1035,7 @@ static inline int ov51x_restart(struct sd *sd)
1029 */ 1035 */
1030static int init_ov_sensor(struct sd *sd) 1036static int init_ov_sensor(struct sd *sd)
1031{ 1037{
1032 int i, success; 1038 int i;
1033 1039
1034 /* Reset the sensor */ 1040 /* Reset the sensor */
1035 if (i2c_w(sd, 0x12, 0x80) < 0) 1041 if (i2c_w(sd, 0x12, 0x80) < 0)
@@ -1038,11 +1044,11 @@ static int init_ov_sensor(struct sd *sd)
1038 /* Wait for it to initialize */ 1044 /* Wait for it to initialize */
1039 msleep(150); 1045 msleep(150);
1040 1046
1041 for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { 1047 for (i = 0; i < i2c_detect_tries; i++) {
1042 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f && 1048 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
1043 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) { 1049 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
1044 success = 1; 1050 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
1045 continue; 1051 return 0;
1046 } 1052 }
1047 1053
1048 /* Reset the sensor */ 1054 /* Reset the sensor */
@@ -1054,10 +1060,7 @@ static int init_ov_sensor(struct sd *sd)
1054 if (i2c_r(sd, 0x00) < 0) 1060 if (i2c_r(sd, 0x00) < 0)
1055 return -EIO; 1061 return -EIO;
1056 } 1062 }
1057 if (!success) 1063 return -EIO;
1058 return -EIO;
1059 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
1060 return 0;
1061} 1064}
1062 1065
1063/* Set the read and write slave IDs. The "slave" argument is the write slave, 1066/* Set the read and write slave IDs. The "slave" argument is the write slave,
@@ -1073,7 +1076,6 @@ static int ov51x_set_slave_ids(struct sd *sd,
1073 rc = reg_w(sd, R51x_I2C_W_SID, slave); 1076 rc = reg_w(sd, R51x_I2C_W_SID, slave);
1074 if (rc < 0) 1077 if (rc < 0)
1075 return rc; 1078 return rc;
1076 sd->primary_i2c_slave = slave;
1077 return reg_w(sd, R51x_I2C_R_SID, slave + 1); 1079 return reg_w(sd, R51x_I2C_R_SID, slave + 1);
1078} 1080}
1079 1081
@@ -1285,7 +1287,6 @@ static int ov6xx0_configure(struct sd *sd)
1285/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ 1287/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
1286static void ov51x_led_control(struct sd *sd, int on) 1288static void ov51x_led_control(struct sd *sd, int on)
1287{ 1289{
1288/* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */
1289 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ 1290 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1290} 1291}
1291 1292
@@ -1352,7 +1353,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1352 } 1353 }
1353 if (ov8xx0_configure(sd) < 0) { 1354 if (ov8xx0_configure(sd) < 0) {
1354 PDEBUG(D_ERR, 1355 PDEBUG(D_ERR,
1355 "Failed to configure OV8xx0 sensor"); 1356 "Failed to configure OV8xx0 sensor");
1356 goto error; 1357 goto error;
1357 } 1358 }
1358 } 1359 }
@@ -1482,7 +1483,7 @@ static int ov519_mode_init_regs(struct sd *sd)
1482 return -EIO; 1483 return -EIO;
1483 if (sd->sensor == SEN_OV7640) { 1484 if (sd->sensor == SEN_OV7640) {
1484 /* Select 8-bit input mode */ 1485 /* Select 8-bit input mode */
1485 reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); 1486 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
1486 } 1487 }
1487 } else { 1488 } else {
1488 if (write_regvals(sd, mode_init_519_ov7670, 1489 if (write_regvals(sd, mode_init_519_ov7670,
@@ -1490,14 +1491,14 @@ static int ov519_mode_init_regs(struct sd *sd)
1490 return -EIO; 1491 return -EIO;
1491 } 1492 }
1492 1493
1493 reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4); 1494 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
1494 reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3); 1495 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
1495 reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); 1496 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
1496 reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); 1497 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
1497 reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); 1498 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
1498 reg_w(sd, OV519_CAM_Y_OFFSETH, 0x00); 1499 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
1499 reg_w(sd, OV519_CAM_DIVIDER, 0x00); 1500 reg_w(sd, OV519_R16_DIVIDER, 0x00);
1500 reg_w(sd, OV519_CAM_FORMAT, 0x03); /* YUV422 */ 1501 reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
1501 reg_w(sd, 0x26, 0x00); /* Undocumented */ 1502 reg_w(sd, 0x26, 0x00); /* Undocumented */
1502 1503
1503 /******** Set the framerate ********/ 1504 /******** Set the framerate ********/
@@ -1509,8 +1510,8 @@ static int ov519_mode_init_regs(struct sd *sd)
1509 switch (sd->sensor) { 1510 switch (sd->sensor) {
1510 case SEN_OV7640: 1511 case SEN_OV7640:
1511 switch (sd->frame_rate) { 1512 switch (sd->frame_rate) {
1512/*fixme: default was 30 fps */ 1513 default:
1513 case 30: 1514/* case 30: */
1514 reg_w(sd, 0xa4, 0x0c); 1515 reg_w(sd, 0xa4, 0x0c);
1515 reg_w(sd, 0x23, 0xff); 1516 reg_w(sd, 0x23, 0xff);
1516 break; 1517 break;
@@ -1522,8 +1523,7 @@ static int ov519_mode_init_regs(struct sd *sd)
1522 reg_w(sd, 0xa4, 0x0c); 1523 reg_w(sd, 0xa4, 0x0c);
1523 reg_w(sd, 0x23, 0x1b); 1524 reg_w(sd, 0x23, 0x1b);
1524 break; 1525 break;
1525 default: 1526 case 15:
1526/* case 15: */
1527 reg_w(sd, 0xa4, 0x04); 1527 reg_w(sd, 0xa4, 0x04);
1528 reg_w(sd, 0x23, 0xff); 1528 reg_w(sd, 0x23, 0xff);
1529 sd->clockdiv = 1; 1529 sd->clockdiv = 1;
@@ -1576,7 +1576,6 @@ static int ov519_mode_init_regs(struct sd *sd)
1576 } 1576 }
1577 break; 1577 break;
1578 } 1578 }
1579
1580 return 0; 1579 return 0;
1581} 1580}
1582 1581
@@ -1667,7 +1666,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
1667 * the gain or the contrast. The "reserved" bits seem 1666 * the gain or the contrast. The "reserved" bits seem
1668 * to have some effect in this case. */ 1667 * to have some effect in this case. */
1669 i2c_w(sd, 0x2d, 0x85); 1668 i2c_w(sd, 0x2d, 0x85);
1670 } else if (sd->clockdiv >= 0) { 1669 } else {
1671 i2c_w(sd, 0x11, sd->clockdiv); 1670 i2c_w(sd, 0x11, sd->clockdiv);
1672 } 1671 }
1673 1672
@@ -1869,7 +1868,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1869 ret = ov51x_restart(sd); 1868 ret = ov51x_restart(sd);
1870 if (ret < 0) 1869 if (ret < 0)
1871 goto out; 1870 goto out;
1872 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
1873 ov51x_led_control(sd, 1); 1871 ov51x_led_control(sd, 1);
1874 return 0; 1872 return 0;
1875out: 1873out:
@@ -1879,8 +1877,10 @@ out:
1879 1877
1880static void sd_stopN(struct gspca_dev *gspca_dev) 1878static void sd_stopN(struct gspca_dev *gspca_dev)
1881{ 1879{
1882 ov51x_stop((struct sd *) gspca_dev); 1880 struct sd *sd = (struct sd *) gspca_dev;
1883 ov51x_led_control((struct sd *) gspca_dev, 0); 1881
1882 ov51x_stop(sd);
1883 ov51x_led_control(sd, 0);
1884} 1884}
1885 1885
1886static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1886static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -1935,9 +1935,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1935 int val; 1935 int val;
1936 1936
1937 val = sd->brightness; 1937 val = sd->brightness;
1938 PDEBUG(D_CONF, "brightness:%d", val);
1939/* if (gspca_dev->streaming)
1940 * ov51x_stop(sd); */
1941 switch (sd->sensor) { 1938 switch (sd->sensor) {
1942 case SEN_OV8610: 1939 case SEN_OV8610:
1943 case SEN_OV7610: 1940 case SEN_OV7610:
@@ -1959,8 +1956,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1959 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); 1956 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
1960 break; 1957 break;
1961 } 1958 }
1962/* if (gspca_dev->streaming)
1963 * ov51x_restart(sd); */
1964} 1959}
1965 1960
1966static void setcontrast(struct gspca_dev *gspca_dev) 1961static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1969,9 +1964,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1969 int val; 1964 int val;
1970 1965
1971 val = sd->contrast; 1966 val = sd->contrast;
1972 PDEBUG(D_CONF, "contrast:%d", val);
1973/* if (gspca_dev->streaming)
1974 ov51x_stop(sd); */
1975 switch (sd->sensor) { 1967 switch (sd->sensor) {
1976 case SEN_OV7610: 1968 case SEN_OV7610:
1977 case SEN_OV6620: 1969 case SEN_OV6620:
@@ -2007,8 +1999,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
2007 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); 1999 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
2008 break; 2000 break;
2009 } 2001 }
2010/* if (gspca_dev->streaming)
2011 ov51x_restart(sd); */
2012} 2002}
2013 2003
2014static void setcolors(struct gspca_dev *gspca_dev) 2004static void setcolors(struct gspca_dev *gspca_dev)
@@ -2017,9 +2007,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
2017 int val; 2007 int val;
2018 2008
2019 val = sd->colors; 2009 val = sd->colors;
2020 PDEBUG(D_CONF, "saturation:%d", val);
2021/* if (gspca_dev->streaming)
2022 ov51x_stop(sd); */
2023 switch (sd->sensor) { 2010 switch (sd->sensor) {
2024 case SEN_OV8610: 2011 case SEN_OV8610:
2025 case SEN_OV7610: 2012 case SEN_OV7610:
@@ -2044,8 +2031,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
2044 /* set REG_COM13 values for UV sat auto mode */ 2031 /* set REG_COM13 values for UV sat auto mode */
2045 break; 2032 break;
2046 } 2033 }
2047/* if (gspca_dev->streaming)
2048 ov51x_restart(sd); */
2049} 2034}
2050 2035
2051static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 2036static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -2053,7 +2038,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
2053 struct sd *sd = (struct sd *) gspca_dev; 2038 struct sd *sd = (struct sd *) gspca_dev;
2054 2039
2055 sd->brightness = val; 2040 sd->brightness = val;
2056 setbrightness(gspca_dev); 2041 if (gspca_dev->streaming)
2042 setbrightness(gspca_dev);
2057 return 0; 2043 return 0;
2058} 2044}
2059 2045
@@ -2070,7 +2056,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2070 struct sd *sd = (struct sd *) gspca_dev; 2056 struct sd *sd = (struct sd *) gspca_dev;
2071 2057
2072 sd->contrast = val; 2058 sd->contrast = val;
2073 setcontrast(gspca_dev); 2059 if (gspca_dev->streaming)
2060 setcontrast(gspca_dev);
2074 return 0; 2061 return 0;
2075} 2062}
2076 2063
@@ -2087,7 +2074,8 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
2087 struct sd *sd = (struct sd *) gspca_dev; 2074 struct sd *sd = (struct sd *) gspca_dev;
2088 2075
2089 sd->colors = val; 2076 sd->colors = val;
2090 setcolors(gspca_dev); 2077 if (gspca_dev->streaming)
2078 setcolors(gspca_dev);
2091 return 0; 2079 return 0;
2092} 2080}
2093 2081
@@ -2104,7 +2092,8 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2104 struct sd *sd = (struct sd *) gspca_dev; 2092 struct sd *sd = (struct sd *) gspca_dev;
2105 2093
2106 sd->hflip = val; 2094 sd->hflip = val;
2107 sethvflip(sd); 2095 if (gspca_dev->streaming)
2096 sethvflip(sd);
2108 return 0; 2097 return 0;
2109} 2098}
2110 2099
@@ -2121,7 +2110,8 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2121 struct sd *sd = (struct sd *) gspca_dev; 2110 struct sd *sd = (struct sd *) gspca_dev;
2122 2111
2123 sd->vflip = val; 2112 sd->vflip = val;
2124 sethvflip(sd); 2113 if (gspca_dev->streaming)
2114 sethvflip(sd);
2125 return 0; 2115 return 0;
2126} 2116}
2127 2117
@@ -2162,7 +2152,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2162 {USB_DEVICE(0x05a9, 0x8519)}, 2152 {USB_DEVICE(0x05a9, 0x8519)},
2163 {} 2153 {}
2164}; 2154};
2165#undef DVNAME 2155
2166MODULE_DEVICE_TABLE(usb, device_table); 2156MODULE_DEVICE_TABLE(usb, device_table);
2167 2157
2168/* -- device connect -- */ 2158/* -- device connect -- */
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
new file mode 100644
index 000000000000..3bf15e401693
--- /dev/null
+++ b/drivers/media/video/gspca/ov534.c
@@ -0,0 +1,601 @@
1/*
2 * ov534/ov772x gspca driver
3 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
4 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
5 *
6 * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
7 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
8 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#define MODULE_NAME "ov534"
26
27#include "gspca.h"
28
29#define OV534_REG_ADDRESS 0xf1 /* ? */
30#define OV534_REG_SUBADDR 0xf2
31#define OV534_REG_WRITE 0xf3
32#define OV534_REG_READ 0xf4
33#define OV534_REG_OPERATION 0xf5
34#define OV534_REG_STATUS 0xf6
35
36#define OV534_OP_WRITE_3 0x37
37#define OV534_OP_WRITE_2 0x33
38#define OV534_OP_READ_2 0xf9
39
40#define CTRL_TIMEOUT 500
41
42MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
43MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
44MODULE_LICENSE("GPL");
45
46/* specific webcam descriptor */
47struct sd {
48 struct gspca_dev gspca_dev; /* !! must be the first item */
49 __u32 last_fid;
50 __u32 last_pts;
51 int frame_rate;
52};
53
54/* V4L2 controls supported by the driver */
55static struct ctrl sd_ctrls[] = {
56};
57
58static const struct v4l2_pix_format vga_mode[] = {
59 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
60 .bytesperline = 640 * 2,
61 .sizeimage = 640 * 480 * 2,
62 .colorspace = V4L2_COLORSPACE_JPEG,
63 .priv = 0},
64};
65
66static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
67{
68 struct usb_device *udev = gspca_dev->dev;
69 int ret;
70
71 PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
72 gspca_dev->usb_buf[0] = val;
73 ret = usb_control_msg(udev,
74 usb_sndctrlpipe(udev, 0),
75 0x1,
76 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
77 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
78 if (ret < 0)
79 PDEBUG(D_ERR, "write failed");
80}
81
82static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
83{
84 struct usb_device *udev = gspca_dev->dev;
85 int ret;
86
87 ret = usb_control_msg(udev,
88 usb_rcvctrlpipe(udev, 0),
89 0x1,
90 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
91 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
92 PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
93 if (ret < 0)
94 PDEBUG(D_ERR, "read failed");
95 return gspca_dev->usb_buf[0];
96}
97
98/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
99 * (direction and output)? */
100static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
101{
102 u8 data;
103
104 PDEBUG(D_CONF, "led status: %d", status);
105
106 data = ov534_reg_read(gspca_dev, 0x21);
107 data |= 0x80;
108 ov534_reg_write(gspca_dev, 0x21, data);
109
110 data = ov534_reg_read(gspca_dev, 0x23);
111 if (status)
112 data |= 0x80;
113 else
114 data &= ~(0x80);
115
116 ov534_reg_write(gspca_dev, 0x23, data);
117}
118
119static int sccb_check_status(struct gspca_dev *gspca_dev)
120{
121 u8 data;
122 int i;
123
124 for (i = 0; i < 5; i++) {
125 data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
126
127 switch (data) {
128 case 0x00:
129 return 1;
130 case 0x04:
131 return 0;
132 case 0x03:
133 break;
134 default:
135 PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
136 data, i + 1);
137 }
138 }
139 return 0;
140}
141
142static void sccb_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
143{
144 PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val);
145 ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
146 ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
147 ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
148
149 if (!sccb_check_status(gspca_dev))
150 PDEBUG(D_ERR, "sccb_reg_write failed");
151}
152
153#ifdef GSPCA_DEBUG
154static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
155{
156 ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
157 ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
158 if (!sccb_check_status(gspca_dev))
159 PDEBUG(D_ERR, "sccb_reg_read failed 1");
160
161 ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
162 if (!sccb_check_status(gspca_dev))
163 PDEBUG(D_ERR, "sccb_reg_read failed 2");
164
165 return ov534_reg_read(gspca_dev, OV534_REG_READ);
166}
167#endif
168
169static const __u8 ov534_reg_initdata[][2] = {
170 { 0xe7, 0x3a },
171
172 { OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */
173
174 { 0xc2, 0x0c },
175 { 0x88, 0xf8 },
176 { 0xc3, 0x69 },
177 { 0x89, 0xff },
178 { 0x76, 0x03 },
179 { 0x92, 0x01 },
180 { 0x93, 0x18 },
181 { 0x94, 0x10 },
182 { 0x95, 0x10 },
183 { 0xe2, 0x00 },
184 { 0xe7, 0x3e },
185
186 { 0x96, 0x00 },
187
188 { 0x97, 0x20 },
189 { 0x97, 0x20 },
190 { 0x97, 0x20 },
191 { 0x97, 0x0a },
192 { 0x97, 0x3f },
193 { 0x97, 0x4a },
194 { 0x97, 0x20 },
195 { 0x97, 0x15 },
196 { 0x97, 0x0b },
197
198 { 0x8e, 0x40 },
199 { 0x1f, 0x81 },
200 { 0x34, 0x05 },
201 { 0xe3, 0x04 },
202 { 0x88, 0x00 },
203 { 0x89, 0x00 },
204 { 0x76, 0x00 },
205 { 0xe7, 0x2e },
206 { 0x31, 0xf9 },
207 { 0x25, 0x42 },
208 { 0x21, 0xf0 },
209
210 { 0x1c, 0x00 },
211 { 0x1d, 0x40 },
212 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
213 { 0x1d, 0x00 }, /* payload size */
214 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
215 { 0x1d, 0x58 }, /* frame size */
216 { 0x1d, 0x00 }, /* frame size */
217
218 { 0x1c, 0x0a },
219 { 0x1d, 0x08 }, /* turn on UVC header */
220 { 0x1d, 0x0e }, /* .. */
221
222 { 0x8d, 0x1c },
223 { 0x8e, 0x80 },
224 { 0xe5, 0x04 },
225
226 { 0xc0, 0x50 },
227 { 0xc1, 0x3c },
228 { 0xc2, 0x0c },
229};
230
231static const __u8 ov772x_reg_initdata[][2] = {
232 { 0x12, 0x80 },
233 { 0x11, 0x01 },
234
235 { 0x3d, 0x03 },
236 { 0x17, 0x26 },
237 { 0x18, 0xa0 },
238 { 0x19, 0x07 },
239 { 0x1a, 0xf0 },
240 { 0x32, 0x00 },
241 { 0x29, 0xa0 },
242 { 0x2c, 0xf0 },
243 { 0x65, 0x20 },
244 { 0x11, 0x01 },
245 { 0x42, 0x7f },
246 { 0x63, 0xe0 },
247 { 0x64, 0xff },
248 { 0x66, 0x00 },
249 { 0x13, 0xf0 },
250 { 0x0d, 0x41 },
251 { 0x0f, 0xc5 },
252 { 0x14, 0x11 },
253
254 { 0x22, 0x7f },
255 { 0x23, 0x03 },
256 { 0x24, 0x40 },
257 { 0x25, 0x30 },
258 { 0x26, 0xa1 },
259 { 0x2a, 0x00 },
260 { 0x2b, 0x00 },
261 { 0x6b, 0xaa },
262 { 0x13, 0xff },
263
264 { 0x90, 0x05 },
265 { 0x91, 0x01 },
266 { 0x92, 0x03 },
267 { 0x93, 0x00 },
268 { 0x94, 0x60 },
269 { 0x95, 0x3c },
270 { 0x96, 0x24 },
271 { 0x97, 0x1e },
272 { 0x98, 0x62 },
273 { 0x99, 0x80 },
274 { 0x9a, 0x1e },
275 { 0x9b, 0x08 },
276 { 0x9c, 0x20 },
277 { 0x9e, 0x81 },
278
279 { 0xa6, 0x04 },
280 { 0x7e, 0x0c },
281 { 0x7f, 0x16 },
282 { 0x80, 0x2a },
283 { 0x81, 0x4e },
284 { 0x82, 0x61 },
285 { 0x83, 0x6f },
286 { 0x84, 0x7b },
287 { 0x85, 0x86 },
288 { 0x86, 0x8e },
289 { 0x87, 0x97 },
290 { 0x88, 0xa4 },
291 { 0x89, 0xaf },
292 { 0x8a, 0xc5 },
293 { 0x8b, 0xd7 },
294 { 0x8c, 0xe8 },
295 { 0x8d, 0x20 },
296
297 { 0x0c, 0x90 },
298
299 { 0x2b, 0x00 },
300 { 0x22, 0x7f },
301 { 0x23, 0x03 },
302 { 0x11, 0x01 },
303 { 0x0c, 0xd0 },
304 { 0x64, 0xff },
305 { 0x0d, 0x41 },
306
307 { 0x14, 0x41 },
308 { 0x0e, 0xcd },
309 { 0xac, 0xbf },
310 { 0x8e, 0x00 },
311 { 0x0c, 0xd0 }
312};
313
314/* set framerate */
315static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
316{
317 struct sd *sd = (struct sd *) gspca_dev;
318 int fr = sd->frame_rate;
319
320 switch (fr) {
321 case 50:
322 sccb_reg_write(gspca_dev, 0x11, 0x01);
323 sccb_reg_write(gspca_dev, 0x0d, 0x41);
324 ov534_reg_write(gspca_dev, 0xe5, 0x02);
325 break;
326 case 40:
327 sccb_reg_write(gspca_dev, 0x11, 0x02);
328 sccb_reg_write(gspca_dev, 0x0d, 0xc1);
329 ov534_reg_write(gspca_dev, 0xe5, 0x04);
330 break;
331/* case 30: */
332 default:
333 fr = 30;
334 sccb_reg_write(gspca_dev, 0x11, 0x04);
335 sccb_reg_write(gspca_dev, 0x0d, 0x81);
336 ov534_reg_write(gspca_dev, 0xe5, 0x02);
337 break;
338 case 15:
339 sccb_reg_write(gspca_dev, 0x11, 0x03);
340 sccb_reg_write(gspca_dev, 0x0d, 0x41);
341 ov534_reg_write(gspca_dev, 0xe5, 0x04);
342 break;
343 }
344
345 sd->frame_rate = fr;
346 PDEBUG(D_PROBE, "frame_rate: %d", fr);
347}
348
349/* setup method */
350static void ov534_setup(struct gspca_dev *gspca_dev)
351{
352 int i;
353
354 /* Initialize bridge chip */
355 for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++)
356 ov534_reg_write(gspca_dev, ov534_reg_initdata[i][0],
357 ov534_reg_initdata[i][1]);
358
359 PDEBUG(D_PROBE, "sensor is ov%02x%02x",
360 sccb_reg_read(gspca_dev, 0x0a),
361 sccb_reg_read(gspca_dev, 0x0b));
362
363 ov534_set_led(gspca_dev, 1);
364
365 /* Initialize sensor */
366 for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++)
367 sccb_reg_write(gspca_dev, ov772x_reg_initdata[i][0],
368 ov772x_reg_initdata[i][1]);
369
370 ov534_reg_write(gspca_dev, 0xe0, 0x09);
371 ov534_set_led(gspca_dev, 0);
372}
373
374/* this function is called at probe time */
375static int sd_config(struct gspca_dev *gspca_dev,
376 const struct usb_device_id *id)
377{
378 struct cam *cam;
379
380 cam = &gspca_dev->cam;
381
382 cam->epaddr = 0x01;
383 cam->cam_mode = vga_mode;
384 cam->nmodes = ARRAY_SIZE(vga_mode);
385
386 cam->bulk_size = 16384;
387 cam->bulk_nurbs = 2;
388
389 return 0;
390}
391
392/* this function is called at probe and resume time */
393static int sd_init(struct gspca_dev *gspca_dev)
394{
395 ov534_setup(gspca_dev);
396 ov534_set_frame_rate(gspca_dev);
397
398 return 0;
399}
400
401static int sd_start(struct gspca_dev *gspca_dev)
402{
403 /* start streaming data */
404 ov534_set_led(gspca_dev, 1);
405 ov534_reg_write(gspca_dev, 0xe0, 0x00);
406
407 return 0;
408}
409
410static void sd_stopN(struct gspca_dev *gspca_dev)
411{
412 /* stop streaming data */
413 ov534_reg_write(gspca_dev, 0xe0, 0x09);
414 ov534_set_led(gspca_dev, 0);
415}
416
417/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
418#define UVC_STREAM_EOH (1 << 7)
419#define UVC_STREAM_ERR (1 << 6)
420#define UVC_STREAM_STI (1 << 5)
421#define UVC_STREAM_RES (1 << 4)
422#define UVC_STREAM_SCR (1 << 3)
423#define UVC_STREAM_PTS (1 << 2)
424#define UVC_STREAM_EOF (1 << 1)
425#define UVC_STREAM_FID (1 << 0)
426
427static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
428 __u8 *data, int len)
429{
430 struct sd *sd = (struct sd *) gspca_dev;
431 __u32 this_pts;
432 int this_fid;
433 int remaining_len = len;
434 __u8 *next_data = data;
435
436scan_next:
437 if (remaining_len <= 0)
438 return;
439
440 data = next_data;
441 len = min(remaining_len, 2048);
442 remaining_len -= len;
443 next_data += len;
444
445 /* Payloads are prefixed with a UVC-style header. We
446 consider a frame to start when the FID toggles, or the PTS
447 changes. A frame ends when EOF is set, and we've received
448 the correct number of bytes. */
449
450 /* Verify UVC header. Header length is always 12 */
451 if (data[0] != 12 || len < 12) {
452 PDEBUG(D_PACK, "bad header");
453 goto discard;
454 }
455
456 /* Check errors */
457 if (data[1] & UVC_STREAM_ERR) {
458 PDEBUG(D_PACK, "payload error");
459 goto discard;
460 }
461
462 /* Extract PTS and FID */
463 if (!(data[1] & UVC_STREAM_PTS)) {
464 PDEBUG(D_PACK, "PTS not present");
465 goto discard;
466 }
467 this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2];
468 this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
469
470 /* If PTS or FID has changed, start a new frame. */
471 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
472 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
473 sd->last_pts = this_pts;
474 sd->last_fid = this_fid;
475 }
476
477 /* Add the data from this payload */
478 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
479 data + 12, len - 12);
480
481 /* If this packet is marked as EOF, end the frame */
482 if (data[1] & UVC_STREAM_EOF) {
483 sd->last_pts = 0;
484
485 if ((frame->data_end - frame->data) !=
486 (gspca_dev->width * gspca_dev->height * 2)) {
487 PDEBUG(D_PACK, "short frame");
488 goto discard;
489 }
490
491 gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0);
492 }
493
494 /* Done this payload */
495 goto scan_next;
496
497discard:
498 /* Discard data until a new frame starts. */
499 gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
500 goto scan_next;
501}
502
503/* get stream parameters (framerate) */
504static int sd_get_streamparm(struct gspca_dev *gspca_dev,
505 struct v4l2_streamparm *parm)
506{
507 struct v4l2_captureparm *cp = &parm->parm.capture;
508 struct v4l2_fract *tpf = &cp->timeperframe;
509 struct sd *sd = (struct sd *) gspca_dev;
510
511 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
512 return -EINVAL;
513
514 cp->capability |= V4L2_CAP_TIMEPERFRAME;
515 tpf->numerator = 1;
516 tpf->denominator = sd->frame_rate;
517
518 return 0;
519}
520
521/* set stream parameters (framerate) */
522static int sd_set_streamparm(struct gspca_dev *gspca_dev,
523 struct v4l2_streamparm *parm)
524{
525 struct v4l2_captureparm *cp = &parm->parm.capture;
526 struct v4l2_fract *tpf = &cp->timeperframe;
527 struct sd *sd = (struct sd *) gspca_dev;
528
529 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
530 return -EINVAL;
531
532 /* Set requested framerate */
533 sd->frame_rate = tpf->denominator / tpf->numerator;
534 ov534_set_frame_rate(gspca_dev);
535
536 /* Return the actual framerate */
537 tpf->numerator = 1;
538 tpf->denominator = sd->frame_rate;
539
540 return 0;
541}
542
543/* sub-driver description */
544static const struct sd_desc sd_desc = {
545 .name = MODULE_NAME,
546 .ctrls = sd_ctrls,
547 .nctrls = ARRAY_SIZE(sd_ctrls),
548 .config = sd_config,
549 .init = sd_init,
550 .start = sd_start,
551 .stopN = sd_stopN,
552 .pkt_scan = sd_pkt_scan,
553 .get_streamparm = sd_get_streamparm,
554 .set_streamparm = sd_set_streamparm,
555};
556
557/* -- module initialisation -- */
558static const __devinitdata struct usb_device_id device_table[] = {
559 {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */
560 {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */
561 {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */
562 {}
563};
564
565MODULE_DEVICE_TABLE(usb, device_table);
566
567/* -- device connect -- */
568static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
569{
570 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
571 THIS_MODULE);
572}
573
574static struct usb_driver sd_driver = {
575 .name = MODULE_NAME,
576 .id_table = device_table,
577 .probe = sd_probe,
578 .disconnect = gspca_disconnect,
579#ifdef CONFIG_PM
580 .suspend = gspca_suspend,
581 .resume = gspca_resume,
582#endif
583};
584
585/* -- module insert / remove -- */
586static int __init sd_mod_init(void)
587{
588 if (usb_register(&sd_driver) < 0)
589 return -1;
590 PDEBUG(D_PROBE, "registered");
591 return 0;
592}
593
594static void __exit sd_mod_exit(void)
595{
596 usb_deregister(&sd_driver);
597 PDEBUG(D_PROBE, "deregistered");
598}
599
600module_init(sd_mod_init);
601module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 0b0c573d06da..c90ac852bac0 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Pixart PAC207BCA library 2 * Pixart PAC207BCA library
3 * 3 *
4 * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> 4 * Copyright (C) 2008 Hans de Goede <hdgoede@redhat.com>
5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li 5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
6 * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr 6 * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
7 * 7 *
@@ -27,7 +27,7 @@
27 27
28#include "gspca.h" 28#include "gspca.h"
29 29
30MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); 30MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
31MODULE_DESCRIPTION("Pixart PAC207"); 31MODULE_DESCRIPTION("Pixart PAC207");
32MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
33 33
@@ -149,7 +149,7 @@ static struct ctrl sd_ctrls[] = {
149 }, 149 },
150}; 150};
151 151
152static struct v4l2_pix_format sif_mode[] = { 152static const struct v4l2_pix_format sif_mode[] = {
153 {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, 153 {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
154 .bytesperline = 176, 154 .bytesperline = 176,
155 .sizeimage = (176 + 2) * 144, 155 .sizeimage = (176 + 2) * 144,
@@ -529,6 +529,7 @@ static const struct sd_desc sd_desc = {
529static const __devinitdata struct usb_device_id device_table[] = { 529static const __devinitdata struct usb_device_id device_table[] = {
530 {USB_DEVICE(0x041e, 0x4028)}, 530 {USB_DEVICE(0x041e, 0x4028)},
531 {USB_DEVICE(0x093a, 0x2460)}, 531 {USB_DEVICE(0x093a, 0x2460)},
532 {USB_DEVICE(0x093a, 0x2461)},
532 {USB_DEVICE(0x093a, 0x2463)}, 533 {USB_DEVICE(0x093a, 0x2463)},
533 {USB_DEVICE(0x093a, 0x2464)}, 534 {USB_DEVICE(0x093a, 0x2464)},
534 {USB_DEVICE(0x093a, 0x2468)}, 535 {USB_DEVICE(0x093a, 0x2468)},
@@ -536,6 +537,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
536 {USB_DEVICE(0x093a, 0x2471)}, 537 {USB_DEVICE(0x093a, 0x2471)},
537 {USB_DEVICE(0x093a, 0x2472)}, 538 {USB_DEVICE(0x093a, 0x2472)},
538 {USB_DEVICE(0x093a, 0x2476)}, 539 {USB_DEVICE(0x093a, 0x2476)},
540 {USB_DEVICE(0x145f, 0x013a)},
539 {USB_DEVICE(0x2001, 0xf115)}, 541 {USB_DEVICE(0x2001, 0xf115)},
540 {} 542 {}
541}; 543};
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index fbd45e235d97..a9c95cba710e 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -226,7 +226,7 @@ static struct ctrl sd_ctrls[] = {
226 }, 226 },
227}; 227};
228 228
229static struct v4l2_pix_format vga_mode[] = { 229static const struct v4l2_pix_format vga_mode[] = {
230 {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, 230 {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
231 .bytesperline = 160, 231 .bytesperline = 160,
232 .sizeimage = 160 * 120 * 3 / 8 + 590, 232 .sizeimage = 160 * 120 * 3 / 8 + 590,
@@ -1064,10 +1064,13 @@ static __devinitdata struct usb_device_id device_table[] = {
1064 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311}, 1064 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
1065 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311}, 1065 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
1066 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311}, 1066 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
1067 {USB_DEVICE(0x093a, 0x2620), .driver_info = SENSOR_PAC7302},
1067 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302}, 1068 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
1069 {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
1068 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302}, 1070 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1069 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302}, 1071 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
1070 {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302}, 1072 {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
1073 {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
1071 {} 1074 {}
1072}; 1075};
1073MODULE_DEVICE_TABLE(usb, device_table); 1076MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 6c69bc7778fc..b3e4e0677b68 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -132,8 +132,6 @@ struct sensor_data {
132 ignore atleast the 2 next frames for the new settings to come into effect 132 ignore atleast the 2 next frames for the new settings to come into effect
133 before doing any other adjustments */ 133 before doing any other adjustments */
134#define AUTOGAIN_IGNORE_FRAMES 3 134#define AUTOGAIN_IGNORE_FRAMES 3
135#define AUTOGAIN_DEADZONE 1000
136#define DESIRED_AVG_LUM 7000
137 135
138/* V4L2 controls supported by the driver */ 136/* V4L2 controls supported by the driver */
139static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 137static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -229,7 +227,7 @@ static struct ctrl sd_ctrls[] = {
229 }, 227 },
230}; 228};
231 229
232static struct v4l2_pix_format vga_mode[] = { 230static const struct v4l2_pix_format vga_mode[] = {
233 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 231 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
234 .bytesperline = 160, 232 .bytesperline = 160,
235 .sizeimage = 160 * 120, 233 .sizeimage = 160 * 120,
@@ -251,7 +249,7 @@ static struct v4l2_pix_format vga_mode[] = {
251 .colorspace = V4L2_COLORSPACE_SRGB, 249 .colorspace = V4L2_COLORSPACE_SRGB,
252 .priv = 0}, 250 .priv = 0},
253}; 251};
254static struct v4l2_pix_format sif_mode[] = { 252static const struct v4l2_pix_format sif_mode[] = {
255 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 253 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
256 .bytesperline = 160, 254 .bytesperline = 160,
257 .sizeimage = 160 * 120, 255 .sizeimage = 160 * 120,
@@ -827,18 +825,29 @@ static void setfreq(struct gspca_dev *gspca_dev)
827 825
828static void do_autogain(struct gspca_dev *gspca_dev) 826static void do_autogain(struct gspca_dev *gspca_dev)
829{ 827{
828 int deadzone, desired_avg_lum;
830 struct sd *sd = (struct sd *) gspca_dev; 829 struct sd *sd = (struct sd *) gspca_dev;
831 int avg_lum = atomic_read(&sd->avg_lum); 830 int avg_lum = atomic_read(&sd->avg_lum);
832 831
833 if (avg_lum == -1) 832 if (avg_lum == -1)
834 return; 833 return;
835 834
835 /* SIF / VGA sensors have a different autoexposure area and thus
836 different avg_lum values for the same picture brightness */
837 if (sensor_data[sd->sensor].flags & F_SIF) {
838 deadzone = 1000;
839 desired_avg_lum = 7000;
840 } else {
841 deadzone = 3000;
842 desired_avg_lum = 23000;
843 }
844
836 if (sd->autogain_ignore_frames > 0) 845 if (sd->autogain_ignore_frames > 0)
837 sd->autogain_ignore_frames--; 846 sd->autogain_ignore_frames--;
838 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 847 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
839 sd->brightness * DESIRED_AVG_LUM / 127, 848 sd->brightness * desired_avg_lum / 127,
840 AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) { 849 deadzone, GAIN_KNEE, EXPOSURE_KNEE)) {
841 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n", 850 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
842 (int)sd->gain, (int)sd->exposure); 851 (int)sd->gain, (int)sd->exposure);
843 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 852 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
844 } 853 }
@@ -1226,8 +1235,8 @@ static __devinitdata struct usb_device_id device_table[] = {
1226 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, 1235 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1227 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, 1236 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1228 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, 1237 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1229 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1230#endif 1238#endif
1239 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1231 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, 1240 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1232#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1241#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1233 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, 1242 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 53cb82d9e7c6..3373b8d9d2a8 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -24,6 +24,8 @@
24#include "gspca.h" 24#include "gspca.h"
25#include "jpeg.h" 25#include "jpeg.h"
26 26
27#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
28
27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 29MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
29MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
@@ -35,23 +37,26 @@ struct sd {
35 atomic_t avg_lum; 37 atomic_t avg_lum;
36 unsigned int exposure; 38 unsigned int exposure;
37 39
38 unsigned short brightness; 40 __u16 brightness;
39 unsigned char contrast; 41 __u8 contrast;
40 unsigned char colors; 42 __u8 colors;
41 unsigned char autogain; 43 __u8 autogain;
44 __u8 blue;
45 __u8 red;
42 __u8 vflip; /* ov7630 only */ 46 __u8 vflip; /* ov7630 only */
47 __u8 infrared; /* mi0360 only */
43 48
44 signed char ag_cnt; 49 __s8 ag_cnt;
45#define AG_CNT_START 13 50#define AG_CNT_START 13
46 51
47 char qindex; 52 __u8 qindex;
48 unsigned char bridge; 53 __u8 bridge;
49#define BRIDGE_SN9C102P 0 54#define BRIDGE_SN9C102P 0
50#define BRIDGE_SN9C105 1 55#define BRIDGE_SN9C105 1
51#define BRIDGE_SN9C110 2 56#define BRIDGE_SN9C110 2
52#define BRIDGE_SN9C120 3 57#define BRIDGE_SN9C120 3
53#define BRIDGE_SN9C325 4 58#define BRIDGE_SN9C325 4
54 char sensor; /* Type of image sensor chip */ 59 __u8 sensor; /* Type of image sensor chip */
55#define SENSOR_HV7131R 0 60#define SENSOR_HV7131R 0
56#define SENSOR_MI0360 1 61#define SENSOR_MI0360 1
57#define SENSOR_MO4000 2 62#define SENSOR_MO4000 2
@@ -59,7 +64,7 @@ struct sd {
59#define SENSOR_OV7630 4 64#define SENSOR_OV7630 4
60#define SENSOR_OV7648 5 65#define SENSOR_OV7648 5
61#define SENSOR_OV7660 6 66#define SENSOR_OV7660 6
62 unsigned char i2c_base; 67 __u8 i2c_base;
63}; 68};
64 69
65/* V4L2 controls supported by the driver */ 70/* V4L2 controls supported by the driver */
@@ -69,10 +74,16 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 74static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 75static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 76static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
72static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 81static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 82static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 83static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
76 87
77static struct ctrl sd_ctrls[] = { 88static struct ctrl sd_ctrls[] = {
78 { 89 {
@@ -84,7 +95,7 @@ static struct ctrl sd_ctrls[] = {
84#define BRIGHTNESS_MAX 0xffff 95#define BRIGHTNESS_MAX 0xffff
85 .maximum = BRIGHTNESS_MAX, 96 .maximum = BRIGHTNESS_MAX,
86 .step = 1, 97 .step = 1,
87#define BRIGHTNESS_DEF 0x7fff 98#define BRIGHTNESS_DEF 0x8000
88 .default_value = BRIGHTNESS_DEF, 99 .default_value = BRIGHTNESS_DEF,
89 }, 100 },
90 .set = sd_setbrightness, 101 .set = sd_setbrightness,
@@ -111,7 +122,7 @@ static struct ctrl sd_ctrls[] = {
111 .type = V4L2_CTRL_TYPE_INTEGER, 122 .type = V4L2_CTRL_TYPE_INTEGER,
112 .name = "Color", 123 .name = "Color",
113 .minimum = 0, 124 .minimum = 0,
114 .maximum = 64, 125 .maximum = 40,
115 .step = 1, 126 .step = 1,
116#define COLOR_DEF 32 127#define COLOR_DEF 32
117 .default_value = COLOR_DEF, 128 .default_value = COLOR_DEF,
@@ -119,7 +130,35 @@ static struct ctrl sd_ctrls[] = {
119 .set = sd_setcolors, 130 .set = sd_setcolors,
120 .get = sd_getcolors, 131 .get = sd_getcolors,
121 }, 132 },
122#define AUTOGAIN_IDX 3 133 {
134 {
135 .id = V4L2_CID_BLUE_BALANCE,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Blue Balance",
138 .minimum = 24,
139 .maximum = 40,
140 .step = 1,
141#define BLUE_BALANCE_DEF 32
142 .default_value = BLUE_BALANCE_DEF,
143 },
144 .set = sd_setblue_balance,
145 .get = sd_getblue_balance,
146 },
147 {
148 {
149 .id = V4L2_CID_RED_BALANCE,
150 .type = V4L2_CTRL_TYPE_INTEGER,
151 .name = "Red Balance",
152 .minimum = 24,
153 .maximum = 40,
154 .step = 1,
155#define RED_BALANCE_DEF 32
156 .default_value = RED_BALANCE_DEF,
157 },
158 .set = sd_setred_balance,
159 .get = sd_getred_balance,
160 },
161#define AUTOGAIN_IDX 5
123 { 162 {
124 { 163 {
125 .id = V4L2_CID_AUTOGAIN, 164 .id = V4L2_CID_AUTOGAIN,
@@ -135,7 +174,7 @@ static struct ctrl sd_ctrls[] = {
135 .get = sd_getautogain, 174 .get = sd_getautogain,
136 }, 175 },
137/* ov7630 only */ 176/* ov7630 only */
138#define VFLIP_IDX 4 177#define VFLIP_IDX 6
139 { 178 {
140 { 179 {
141 .id = V4L2_CID_VFLIP, 180 .id = V4L2_CID_VFLIP,
@@ -150,9 +189,43 @@ static struct ctrl sd_ctrls[] = {
150 .set = sd_setvflip, 189 .set = sd_setvflip,
151 .get = sd_getvflip, 190 .get = sd_getvflip,
152 }, 191 },
192/* mi0360 only */
193#define INFRARED_IDX 7
194 {
195 {
196 .id = V4L2_CID_INFRARED,
197 .type = V4L2_CTRL_TYPE_BOOLEAN,
198 .name = "Infrared",
199 .minimum = 0,
200 .maximum = 1,
201 .step = 1,
202#define INFRARED_DEF 0
203 .default_value = INFRARED_DEF,
204 },
205 .set = sd_setinfrared,
206 .get = sd_getinfrared,
207 },
208};
209
210/* table of the disabled controls */
211static __u32 ctrl_dis[] = {
212 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
213 /* SENSOR_HV7131R 0 */
214 (1 << VFLIP_IDX),
215 /* SENSOR_MI0360 1 */
216 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
217 /* SENSOR_MO4000 2 */
218 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
219 /* SENSOR_OM6802 3 */
220 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
221 /* SENSOR_OV7630 4 */
222 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
223 /* SENSOR_OV7648 5 */
224 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
225 /* SENSOR_OV7660 6 */
153}; 226};
154 227
155static struct v4l2_pix_format vga_mode[] = { 228static const struct v4l2_pix_format vga_mode[] = {
156 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 229 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
157 .bytesperline = 160, 230 .bytesperline = 160,
158 .sizeimage = 160 * 120 * 4 / 8 + 590, 231 .sizeimage = 160 * 120 * 4 / 8 + 590,
@@ -231,13 +304,13 @@ static const __u8 sn_ov7630[] = {
231 304
232static const __u8 sn_ov7648[] = { 305static const __u8 sn_ov7648[] = {
233/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 306/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
234 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 307 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
235/* reg8 reg9 rega regb regc regd rege regf */ 308/* reg8 reg9 rega regb regc regd rege regf */
236 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10, 309 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
237/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 310/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
238 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82, 311 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
239/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ 312/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
240 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 313 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
241}; 314};
242 315
243static const __u8 sn_ov7660[] = { 316static const __u8 sn_ov7660[] = {
@@ -469,6 +542,53 @@ static const __u8 ov7630_sensor_init[][8] = {
469/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */ 542/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
470 {} 543 {}
471}; 544};
545
546static const __u8 ov7648_sensor_init[][8] = {
547 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
548 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
549 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
550 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
551 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
552 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
553 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
554 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
555 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
556 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
557 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
558 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
559 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
560 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
561 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
562 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
563 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
564 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
565 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
566 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
567 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
568
569 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
570/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
571/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
572 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
573/*...*/
574/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
575/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
576 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
577 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
578/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
579/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
580/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
581/*...*/
582 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
583/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
584/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
585/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
586/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
587/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
588
589 {}
590};
591
472static const __u8 ov7660_sensor_init[][8] = { 592static const __u8 ov7660_sensor_init[][8] = {
473 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 593 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
474/* (delay 20ms) */ 594/* (delay 20ms) */
@@ -557,64 +677,6 @@ static const __u8 ov7660_sensor_init[][8] = {
557 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, 677 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
558 {} 678 {}
559}; 679};
560/* reg 0x04 reg 0x07 reg 0x10 */
561/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
562
563static const __u8 ov7648_sensor_init[][8] = {
564 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
565 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
566 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
567 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
568 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
569 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
570 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
571 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
572 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
573 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
574 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
575 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
576 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
577 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
578 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
579 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
580 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
581 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
582 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
583 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
584 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
585 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
586 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
587 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
588 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
589 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
590 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
591 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
592 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
593 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
594 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
595 * This is currently setting a
596 * blue tint, and some things more , i leave it here for future test if
597 * somene is having problems with color on this sensor
598 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
599 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
600 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
601 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
602 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
603 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
604 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
605 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
606 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
607 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
608 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
609 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
610 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
611 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
612 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
613 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
614 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
615/* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
616 {}
617};
618 680
619static const __u8 qtable4[] = { 681static const __u8 qtable4[] = {
620 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, 682 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
@@ -757,8 +819,6 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
757 819
758static int probesensor(struct gspca_dev *gspca_dev) 820static int probesensor(struct gspca_dev *gspca_dev)
759{ 821{
760 struct sd *sd = (struct sd *) gspca_dev;
761
762 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ 822 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
763 msleep(10); 823 msleep(10);
764 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ 824 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
@@ -770,8 +830,7 @@ static int probesensor(struct gspca_dev *gspca_dev)
770 && gspca_dev->usb_buf[3] == 0x00 830 && gspca_dev->usb_buf[3] == 0x00
771 && gspca_dev->usb_buf[4] == 0x00) { 831 && gspca_dev->usb_buf[4] == 0x00) {
772 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); 832 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
773 sd->sensor = SENSOR_HV7131R; 833 return 0;
774 return SENSOR_HV7131R;
775 } 834 }
776 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x", 835 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
777 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], 836 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
@@ -827,17 +886,20 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
827 reg_w1(gspca_dev, 0x01, 0x40); 886 reg_w1(gspca_dev, 0x01, 0x40);
828 break; 887 break;
829 case SENSOR_OV7648: 888 case SENSOR_OV7648:
830 reg_w1(gspca_dev, 0x01, 0x43); 889 reg_w1(gspca_dev, 0x01, 0x63);
831 reg_w1(gspca_dev, 0x17, 0xae); 890 reg_w1(gspca_dev, 0x17, 0x20);
832 reg_w1(gspca_dev, 0x01, 0x42); 891 reg_w1(gspca_dev, 0x01, 0x42);
833 break; 892 break;
834/*jfm: from win trace */ 893/*jfm: from win trace */
835 case SENSOR_OV7660: 894 case SENSOR_OV7660:
836 reg_w1(gspca_dev, 0x01, 0x61); 895 if (sd->bridge == BRIDGE_SN9C120) {
837 reg_w1(gspca_dev, 0x17, 0x20); 896 reg_w1(gspca_dev, 0x01, 0x61);
838 reg_w1(gspca_dev, 0x01, 0x60); 897 reg_w1(gspca_dev, 0x17, 0x20);
839 reg_w1(gspca_dev, 0x01, 0x40); 898 reg_w1(gspca_dev, 0x01, 0x60);
840 break; 899 reg_w1(gspca_dev, 0x01, 0x40);
900 break;
901 }
902 /* fall thru */
841 default: 903 default:
842 reg_w1(gspca_dev, 0x01, 0x43); 904 reg_w1(gspca_dev, 0x01, 0x43);
843 reg_w1(gspca_dev, 0x17, 0x61); 905 reg_w1(gspca_dev, 0x17, 0x61);
@@ -922,6 +984,13 @@ static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
922{ 984{
923 int i = 0; 985 int i = 0;
924 986
987 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
988 i++;
989/* win: dble reset */
990 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
991 i++;
992 msleep(20);
993/* win: i2c reg read 00..7f */
925 while (ov7648_sensor_init[i][0]) { 994 while (ov7648_sensor_init[i][0]) {
926 i2c_w8(gspca_dev, ov7648_sensor_init[i]); 995 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
927 i++; 996 i++;
@@ -961,19 +1030,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
961 sd->brightness = BRIGHTNESS_DEF; 1030 sd->brightness = BRIGHTNESS_DEF;
962 sd->contrast = CONTRAST_DEF; 1031 sd->contrast = CONTRAST_DEF;
963 sd->colors = COLOR_DEF; 1032 sd->colors = COLOR_DEF;
1033 sd->blue = BLUE_BALANCE_DEF;
1034 sd->red = RED_BALANCE_DEF;
964 sd->autogain = AUTOGAIN_DEF; 1035 sd->autogain = AUTOGAIN_DEF;
965 sd->ag_cnt = -1; 1036 sd->ag_cnt = -1;
1037 sd->vflip = VFLIP_DEF;
1038 sd->infrared = INFRARED_DEF;
966 1039
967 switch (sd->sensor) { 1040 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
968 case SENSOR_OV7630:
969 case SENSOR_OV7648:
970 case SENSOR_OV7660:
971 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
972 break;
973 }
974 if (sd->sensor != SENSOR_OV7630)
975 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
976
977 return 0; 1041 return 0;
978} 1042}
979 1043
@@ -981,7 +1045,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
981static int sd_init(struct gspca_dev *gspca_dev) 1045static int sd_init(struct gspca_dev *gspca_dev)
982{ 1046{
983 struct sd *sd = (struct sd *) gspca_dev; 1047 struct sd *sd = (struct sd *) gspca_dev;
984/* const __u8 *sn9c1xx; */
985 __u8 regGpio[] = { 0x29, 0x74 }; 1048 __u8 regGpio[] = { 0x29, 0x74 };
986 __u8 regF1; 1049 __u8 regF1;
987 1050
@@ -1100,32 +1163,13 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
1100 return expo; 1163 return expo;
1101} 1164}
1102 1165
1103/* this function is used for sensors o76xx only */
1104static void setbrightcont(struct gspca_dev *gspca_dev)
1105{
1106 struct sd *sd = (struct sd *) gspca_dev;
1107 int val;
1108 __u8 reg84_full[0x15];
1109
1110 memcpy(reg84_full, reg84, sizeof reg84_full);
1111 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1112 reg84_full[0] = (val + 1) / 2; /* red */
1113 reg84_full[2] = val; /* green */
1114 reg84_full[4] = (val + 1) / 5; /* blue */
1115 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
1116 / BRIGHTNESS_MAX;
1117 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
1118 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1119}
1120
1121/* sensor != ov76xx */
1122static void setbrightness(struct gspca_dev *gspca_dev) 1166static void setbrightness(struct gspca_dev *gspca_dev)
1123{ 1167{
1124 struct sd *sd = (struct sd *) gspca_dev; 1168 struct sd *sd = (struct sd *) gspca_dev;
1125 unsigned int expo; 1169 unsigned int expo;
1126 __u8 k2; 1170 __u8 k2;
1127 1171
1128 k2 = sd->brightness >> 10; 1172 k2 = ((int) sd->brightness - 0x8000) >> 10;
1129 switch (sd->sensor) { 1173 switch (sd->sensor) {
1130 case SENSOR_HV7131R: 1174 case SENSOR_HV7131R:
1131 expo = sd->brightness << 4; 1175 expo = sd->brightness << 4;
@@ -1147,38 +1191,49 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1147 break; 1191 break;
1148 } 1192 }
1149 1193
1150 reg_w1(gspca_dev, 0x96, k2); 1194 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1151} 1195}
1152 1196
1153/* sensor != ov76xx */
1154static void setcontrast(struct gspca_dev *gspca_dev) 1197static void setcontrast(struct gspca_dev *gspca_dev)
1155{ 1198{
1156 struct sd *sd = (struct sd *) gspca_dev; 1199 struct sd *sd = (struct sd *) gspca_dev;
1157 __u8 k2; 1200 __u8 k2;
1158 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; 1201 __u8 contrast[6];
1159 1202
1160 k2 = sd->contrast; 1203 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1161 contrast[2] = k2; 1204 contrast[0] = (k2 + 1) / 2; /* red */
1162 contrast[0] = (k2 + 1) >> 1; 1205 contrast[1] = 0;
1163 contrast[4] = (k2 + 1) / 5; 1206 contrast[2] = k2; /* green */
1164 reg_w(gspca_dev, 0x84, contrast, 6); 1207 contrast[3] = 0;
1208 contrast[4] = (k2 + 1) / 5; /* blue */
1209 contrast[5] = 0;
1210 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1165} 1211}
1166 1212
1167static void setcolors(struct gspca_dev *gspca_dev) 1213static void setcolors(struct gspca_dev *gspca_dev)
1168{ 1214{
1169 struct sd *sd = (struct sd *) gspca_dev; 1215 struct sd *sd = (struct sd *) gspca_dev;
1170 __u8 blue, red; 1216 int i, v;
1171 1217 __u8 reg8a[12]; /* U & V gains */
1172 if (sd->colors >= 32) { 1218 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1173 red = 32 + (sd->colors - 32) / 2; 1219 -24, -38, 64, /* UR UG UB */
1174 blue = 64 - sd->colors; 1220 62, -51, -9 /* VR VG VB */
1175 } else { 1221 };
1176 red = sd->colors; 1222 for (i = 0; i < 6; i++) {
1177 blue = 32 + (32 - sd->colors) / 2; 1223 v = uv[i] * sd->colors / COLOR_DEF;
1224 reg8a[i * 2] = v;
1225 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1178 } 1226 }
1179 reg_w1(gspca_dev, 0x05, red); 1227 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1228}
1229
1230static void setredblue(struct gspca_dev *gspca_dev)
1231{
1232 struct sd *sd = (struct sd *) gspca_dev;
1233
1234 reg_w1(gspca_dev, 0x05, sd->red);
1180/* reg_w1(gspca_dev, 0x07, 32); */ 1235/* reg_w1(gspca_dev, 0x07, 32); */
1181 reg_w1(gspca_dev, 0x06, blue); 1236 reg_w1(gspca_dev, 0x06, sd->blue);
1182} 1237}
1183 1238
1184static void setautogain(struct gspca_dev *gspca_dev) 1239static void setautogain(struct gspca_dev *gspca_dev)
@@ -1195,12 +1250,18 @@ static void setautogain(struct gspca_dev *gspca_dev)
1195 1250
1196static void setvflip(struct sd *sd) 1251static void setvflip(struct sd *sd)
1197{ 1252{
1198 if (sd->sensor != SENSOR_OV7630)
1199 return;
1200 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */ 1253 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1201 sd->vflip ? 0x82 : 0x02); 1254 sd->vflip ? 0x82 : 0x02);
1202} 1255}
1203 1256
1257static void setinfrared(struct sd *sd)
1258{
1259/*fixme: different sequence for StarCam Clip and StarCam 370i */
1260/* Clip */
1261 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1262 sd->infrared ? 0x66 : 0x64);
1263}
1264
1204/* -- start the camera -- */ 1265/* -- start the camera -- */
1205static int sd_start(struct gspca_dev *gspca_dev) 1266static int sd_start(struct gspca_dev *gspca_dev)
1206{ 1267{
@@ -1235,28 +1296,39 @@ static int sd_start(struct gspca_dev *gspca_dev)
1235 reg17 = 0xe2; 1296 reg17 = 0xe2;
1236 break; 1297 break;
1237 case SENSOR_OV7648: 1298 case SENSOR_OV7648:
1238 reg17 = 0xae; 1299 reg17 = 0x20;
1239 break; 1300 break;
1240/*jfm: from win trace */ 1301/*jfm: from win trace */
1241 case SENSOR_OV7660: 1302 case SENSOR_OV7660:
1242 reg17 = 0xa0; 1303 if (sd->bridge == BRIDGE_SN9C120) {
1243 break; 1304 reg17 = 0xa0;
1305 break;
1306 }
1307 /* fall thru */
1244 default: 1308 default:
1245 reg17 = 0x60; 1309 reg17 = 0x60;
1246 break; 1310 break;
1247 } 1311 }
1248 reg_w1(gspca_dev, 0x17, reg17); 1312 reg_w1(gspca_dev, 0x17, reg17);
1249 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); 1313/* set reg1 was here */
1250 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); 1314 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1251 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); 1315 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1316 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1252 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); 1317 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1253 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def); 1318 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1254 for (i = 0; i < 8; i++) 1319 for (i = 0; i < 8; i++)
1255 reg_w(gspca_dev, 0x84, reg84, sizeof reg84); 1320 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1256 switch (sd->sensor) { 1321 switch (sd->sensor) {
1257 case SENSOR_OV7660: 1322 case SENSOR_OV7648:
1258 reg_w1(gspca_dev, 0x9a, 0x05); 1323 reg_w1(gspca_dev, 0x9a, 0x0a);
1324 reg_w1(gspca_dev, 0x99, 0x60);
1259 break; 1325 break;
1326 case SENSOR_OV7660:
1327 if (sd->bridge == BRIDGE_SN9C120) {
1328 reg_w1(gspca_dev, 0x9a, 0x05);
1329 break;
1330 }
1331 /* fall thru */
1260 default: 1332 default:
1261 reg_w1(gspca_dev, 0x9a, 0x08); 1333 reg_w1(gspca_dev, 0x9a, 0x08);
1262 reg_w1(gspca_dev, 0x99, 0x59); 1334 reg_w1(gspca_dev, 0x99, 0x59);
@@ -1265,10 +1337,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
1265 1337
1266 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1338 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1267 if (mode) 1339 if (mode)
1268 reg1 = 0x46; /* 320 clk 48Mhz */ 1340 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1269 else 1341 else
1270 reg1 = 0x06; /* 640 clk 24Mz */ 1342 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1271 reg17 = 0x61; 1343 reg17 = 0x61; /* 0x:20: enable sensor clock */
1272 switch (sd->sensor) { 1344 switch (sd->sensor) {
1273 case SENSOR_HV7131R: 1345 case SENSOR_HV7131R:
1274 hv7131R_InitSensor(gspca_dev); 1346 hv7131R_InitSensor(gspca_dev);
@@ -1298,23 +1370,21 @@ static int sd_start(struct gspca_dev *gspca_dev)
1298 break; 1370 break;
1299 case SENSOR_OV7648: 1371 case SENSOR_OV7648:
1300 ov7648_InitSensor(gspca_dev); 1372 ov7648_InitSensor(gspca_dev);
1301 reg17 = 0xa2; 1373 reg17 = 0x21;
1302 reg1 = 0x44; 1374/* reg1 = 0x42; * 42 - 46? */
1303/* if (mode)
1304 ; * 320x2...
1305 else
1306 ; * 640x... */
1307 break; 1375 break;
1308 default: 1376 default:
1309/* case SENSOR_OV7660: */ 1377/* case SENSOR_OV7660: */
1310 ov7660_InitSensor(gspca_dev); 1378 ov7660_InitSensor(gspca_dev);
1311 if (mode) { 1379 if (sd->bridge == BRIDGE_SN9C120) {
1312/* reg17 = 0x21; * 320 */ 1380 if (mode) { /* 320x240 - 160x120 */
1313/* reg1 = 0x44; */ 1381 reg17 = 0xa2;
1314/* reg1 = 0x46; (done) */ 1382 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1383 }
1315 } else { 1384 } else {
1316 reg17 = 0xa2; /* 640 */ 1385 reg17 = 0x22;
1317 reg1 = 0x44; 1386 reg1 = 0x06; /* 24 Mhz, video trf eneble
1387 * inverse power down */
1318 } 1388 }
1319 break; 1389 break;
1320 } 1390 }
@@ -1342,23 +1412,18 @@ static int sd_start(struct gspca_dev *gspca_dev)
1342 reg_w1(gspca_dev, 0x18, reg18); 1412 reg_w1(gspca_dev, 0x18, reg18);
1343 1413
1344 reg_w1(gspca_dev, 0x17, reg17); 1414 reg_w1(gspca_dev, 0x17, reg17);
1415 reg_w1(gspca_dev, 0x01, reg1);
1345 switch (sd->sensor) { 1416 switch (sd->sensor) {
1346 case SENSOR_HV7131R:
1347 case SENSOR_MI0360: 1417 case SENSOR_MI0360:
1348 case SENSOR_MO4000: 1418 setinfrared(sd);
1349 case SENSOR_OM6802:
1350 setbrightness(gspca_dev);
1351 setcontrast(gspca_dev);
1352 break; 1419 break;
1353 case SENSOR_OV7630: 1420 case SENSOR_OV7630:
1354 setvflip(sd); 1421 setvflip(sd);
1355 /* fall thru */
1356 default: /* OV76xx */
1357 setbrightcont(gspca_dev);
1358 break; 1422 break;
1359 } 1423 }
1424 setbrightness(gspca_dev);
1425 setcontrast(gspca_dev);
1360 setautogain(gspca_dev); 1426 setautogain(gspca_dev);
1361 reg_w1(gspca_dev, 0x01, reg1);
1362 return 0; 1427 return 0;
1363} 1428}
1364 1429
@@ -1369,6 +1434,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1369 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; 1434 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1370 static const __u8 stopmi0360[] = 1435 static const __u8 stopmi0360[] =
1371 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; 1436 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1437 static const __u8 stopov7648[] =
1438 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1372 __u8 data; 1439 __u8 data;
1373 const __u8 *sn9c1xx; 1440 const __u8 *sn9c1xx;
1374 1441
@@ -1382,8 +1449,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1382 i2c_w8(gspca_dev, stopmi0360); 1449 i2c_w8(gspca_dev, stopmi0360);
1383 data = 0x29; 1450 data = 0x29;
1384 break; 1451 break;
1385 case SENSOR_OV7630:
1386 case SENSOR_OV7648: 1452 case SENSOR_OV7648:
1453 i2c_w8(gspca_dev, stopov7648);
1454 /* fall thru */
1455 case SENSOR_OV7630:
1387 data = 0x29; 1456 data = 0x29;
1388 break; 1457 break;
1389 default: 1458 default:
@@ -1437,7 +1506,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1437 expotimes = 0; 1506 expotimes = 0;
1438 sd->exposure = setexposure(gspca_dev, 1507 sd->exposure = setexposure(gspca_dev,
1439 (unsigned int) expotimes); 1508 (unsigned int) expotimes);
1440 setcolors(gspca_dev); 1509 setredblue(gspca_dev);
1441 break; 1510 break;
1442 } 1511 }
1443 } 1512 }
@@ -1491,19 +1560,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1491 struct sd *sd = (struct sd *) gspca_dev; 1560 struct sd *sd = (struct sd *) gspca_dev;
1492 1561
1493 sd->brightness = val; 1562 sd->brightness = val;
1494 if (gspca_dev->streaming) { 1563 if (gspca_dev->streaming)
1495 switch (sd->sensor) { 1564 setbrightness(gspca_dev);
1496 case SENSOR_HV7131R:
1497 case SENSOR_MI0360:
1498 case SENSOR_MO4000:
1499 case SENSOR_OM6802:
1500 setbrightness(gspca_dev);
1501 break;
1502 default: /* OV76xx */
1503 setbrightcont(gspca_dev);
1504 break;
1505 }
1506 }
1507 return 0; 1565 return 0;
1508} 1566}
1509 1567
@@ -1520,19 +1578,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1520 struct sd *sd = (struct sd *) gspca_dev; 1578 struct sd *sd = (struct sd *) gspca_dev;
1521 1579
1522 sd->contrast = val; 1580 sd->contrast = val;
1523 if (gspca_dev->streaming) { 1581 if (gspca_dev->streaming)
1524 switch (sd->sensor) { 1582 setcontrast(gspca_dev);
1525 case SENSOR_HV7131R:
1526 case SENSOR_MI0360:
1527 case SENSOR_MO4000:
1528 case SENSOR_OM6802:
1529 setcontrast(gspca_dev);
1530 break;
1531 default: /* OV76xx */
1532 setbrightcont(gspca_dev);
1533 break;
1534 }
1535 }
1536 return 0; 1583 return 0;
1537} 1584}
1538 1585
@@ -1562,6 +1609,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1562 return 0; 1609 return 0;
1563} 1610}
1564 1611
1612static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1613{
1614 struct sd *sd = (struct sd *) gspca_dev;
1615
1616 sd->blue = val;
1617 if (gspca_dev->streaming)
1618 setredblue(gspca_dev);
1619 return 0;
1620}
1621
1622static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1623{
1624 struct sd *sd = (struct sd *) gspca_dev;
1625
1626 *val = sd->blue;
1627 return 0;
1628}
1629
1630static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1631{
1632 struct sd *sd = (struct sd *) gspca_dev;
1633
1634 sd->red = val;
1635 if (gspca_dev->streaming)
1636 setredblue(gspca_dev);
1637 return 0;
1638}
1639
1640static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1641{
1642 struct sd *sd = (struct sd *) gspca_dev;
1643
1644 *val = sd->red;
1645 return 0;
1646}
1647
1565static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 1648static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1566{ 1649{
1567 struct sd *sd = (struct sd *) gspca_dev; 1650 struct sd *sd = (struct sd *) gspca_dev;
@@ -1598,6 +1681,24 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1598 return 0; 1681 return 0;
1599} 1682}
1600 1683
1684static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1685{
1686 struct sd *sd = (struct sd *) gspca_dev;
1687
1688 sd->infrared = val;
1689 if (gspca_dev->streaming)
1690 setinfrared(sd);
1691 return 0;
1692}
1693
1694static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1695{
1696 struct sd *sd = (struct sd *) gspca_dev;
1697
1698 *val = sd->infrared;
1699 return 0;
1700}
1701
1601/* sub-driver description */ 1702/* sub-driver description */
1602static const struct sd_desc sd_desc = { 1703static const struct sd_desc sd_desc = {
1603 .name = MODULE_NAME, 1704 .name = MODULE_NAME,
@@ -1620,12 +1721,15 @@ static const __devinitdata struct usb_device_id device_table[] = {
1620#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1721#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1621 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, 1722 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1622 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)}, 1723 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1724#endif
1623 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, 1725 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1624 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, 1726 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1727#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1625 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, 1728 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1626 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1627#endif 1729#endif
1730 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1628 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, 1731 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1732 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
1629 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, 1733 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1630/* bw600.inf: 1734/* bw600.inf:
1631 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ 1735 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
@@ -1649,7 +1753,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
1649/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 1753/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1650 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ 1754 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1651/*bw600.inf:*/ 1755/*bw600.inf:*/
1652 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/ 1756 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1653 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, 1757 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1654 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)}, 1758 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1655/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ 1759/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
@@ -1657,8 +1761,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
1657 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, 1761 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1658#endif 1762#endif
1659 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, 1763 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1764 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1660#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1765#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1661/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1662 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, 1766 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1663 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, 1767 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1664/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ 1768/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index bca106c153fa..942f04cd44dd 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -111,7 +111,7 @@ static struct ctrl sd_ctrls[] = {
111 }, 111 },
112}; 112};
113 113
114static struct v4l2_pix_format vga_mode[] = { 114static const struct v4l2_pix_format vga_mode[] = {
115 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 115 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
116 .bytesperline = 320, 116 .bytesperline = 320,
117 .sizeimage = 320 * 240 * 3 / 8 + 590, 117 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -124,7 +124,7 @@ static struct v4l2_pix_format vga_mode[] = {
124 .priv = 0}, 124 .priv = 0},
125}; 125};
126 126
127static struct v4l2_pix_format sif_mode[] = { 127static const struct v4l2_pix_format sif_mode[] = {
128 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 128 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
129 .bytesperline = 176, 129 .bytesperline = 176,
130 .sizeimage = 176 * 144 * 3 / 8 + 590, 130 .sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -633,10 +633,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
633 sd->subtype = id->driver_info; 633 sd->subtype = id->driver_info;
634 if (sd->subtype != LogitechClickSmart310) { 634 if (sd->subtype != LogitechClickSmart310) {
635 cam->cam_mode = vga_mode; 635 cam->cam_mode = vga_mode;
636 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 636 cam->nmodes = ARRAY_SIZE(vga_mode);
637 } else { 637 } else {
638 cam->cam_mode = sif_mode; 638 cam->cam_mode = sif_mode;
639 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; 639 cam->nmodes = ARRAY_SIZE(sif_mode);
640 } 640 }
641 sd->qindex = 5; 641 sd->qindex = 5;
642 sd->brightness = BRIGHTNESS_DEF; 642 sd->brightness = BRIGHTNESS_DEF;
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index e29954c1c38c..82e3e3e2ada1 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -34,6 +34,8 @@ struct sd {
34 unsigned short contrast; 34 unsigned short contrast;
35 __u8 brightness; 35 __u8 brightness;
36 __u8 colors; 36 __u8 colors;
37 __u8 blue_balance;
38 __u8 red_balance;
37 39
38 char subtype; 40 char subtype;
39#define Arowana300KCMOSCamera 0 41#define Arowana300KCMOSCamera 0
@@ -52,6 +54,10 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 54static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
53static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 55static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 56static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
57static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
58static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
59static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
60static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
55 61
56static struct ctrl sd_ctrls[] = { 62static struct ctrl sd_ctrls[] = {
57#define MY_BRIGHTNESS 0 63#define MY_BRIGHTNESS 0
@@ -63,7 +69,7 @@ static struct ctrl sd_ctrls[] = {
63 .minimum = 0, 69 .minimum = 0,
64 .maximum = 127, 70 .maximum = 127,
65 .step = 1, 71 .step = 1,
66 .default_value = 63, 72 .default_value = 0,
67 }, 73 },
68 .set = sd_setbrightness, 74 .set = sd_setbrightness,
69 .get = sd_getbrightness, 75 .get = sd_getbrightness,
@@ -75,9 +81,9 @@ static struct ctrl sd_ctrls[] = {
75 .type = V4L2_CTRL_TYPE_INTEGER, 81 .type = V4L2_CTRL_TYPE_INTEGER,
76 .name = "Contrast", 82 .name = "Contrast",
77 .minimum = 0, 83 .minimum = 0,
78 .maximum = 0xffff, 84 .maximum = 64725,
79 .step = 1, 85 .step = 1,
80 .default_value = 0xaa00, 86 .default_value = 64725,
81 }, 87 },
82 .set = sd_setcontrast, 88 .set = sd_setcontrast,
83 .get = sd_getcontrast, 89 .get = sd_getcontrast,
@@ -91,14 +97,42 @@ static struct ctrl sd_ctrls[] = {
91 .minimum = 0, 97 .minimum = 0,
92 .maximum = 63, 98 .maximum = 63,
93 .step = 1, 99 .step = 1,
94 .default_value = 31, 100 .default_value = 20,
95 }, 101 },
96 .set = sd_setcolors, 102 .set = sd_setcolors,
97 .get = sd_getcolors, 103 .get = sd_getcolors,
98 }, 104 },
105#define MY_BLUE_BALANCE 3
106 {
107 {
108 .id = V4L2_CID_BLUE_BALANCE,
109 .type = V4L2_CTRL_TYPE_INTEGER,
110 .name = "Blue Balance",
111 .minimum = 0,
112 .maximum = 127,
113 .step = 1,
114 .default_value = 0,
115 },
116 .set = sd_setblue_balance,
117 .get = sd_getblue_balance,
118 },
119#define MY_RED_BALANCE 4
120 {
121 {
122 .id = V4L2_CID_RED_BALANCE,
123 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Red Balance",
125 .minimum = 0,
126 .maximum = 127,
127 .step = 1,
128 .default_value = 0,
129 },
130 .set = sd_setred_balance,
131 .get = sd_getred_balance,
132 },
99}; 133};
100 134
101static struct v4l2_pix_format vga_mode[] = { 135static const struct v4l2_pix_format vga_mode[] = {
102 {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, 136 {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE,
103 .bytesperline = 160, 137 .bytesperline = 160,
104 .sizeimage = 160 * 120 * 3 / 2, 138 .sizeimage = 160 * 120 * 3 / 2,
@@ -1822,29 +1856,6 @@ static int reg_write(struct usb_device *dev,
1822 return ret; 1856 return ret;
1823} 1857}
1824 1858
1825/* returns: negative is error, pos or zero is data */
1826static int reg_read(struct gspca_dev *gspca_dev,
1827 __u16 req, /* bRequest */
1828 __u16 index, /* wIndex */
1829 __u16 length) /* wLength (1 or 2 only) */
1830{
1831 int ret;
1832
1833 gspca_dev->usb_buf[1] = 0;
1834 ret = usb_control_msg(gspca_dev->dev,
1835 usb_rcvctrlpipe(gspca_dev->dev, 0),
1836 req,
1837 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1838 0, /* value */
1839 index,
1840 gspca_dev->usb_buf, length,
1841 500); /* timeout */
1842 if (ret < 0) {
1843 PDEBUG(D_ERR, "reg_read err %d", ret);
1844 return -1;
1845 }
1846 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
1847}
1848 1859
1849static int write_vector(struct gspca_dev *gspca_dev, 1860static int write_vector(struct gspca_dev *gspca_dev,
1850 const __u16 data[][3]) 1861 const __u16 data[][3])
@@ -1869,18 +1880,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1869{ 1880{
1870 struct sd *sd = (struct sd *) gspca_dev; 1881 struct sd *sd = (struct sd *) gspca_dev;
1871 1882
1872 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->brightness);
1873 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); 1883 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness);
1874 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->brightness);
1875} 1884}
1876 1885
1877static void getbrightness(struct gspca_dev *gspca_dev) 1886static void getbrightness(struct gspca_dev *gspca_dev)
1878{ 1887{
1879 struct sd *sd = (struct sd *) gspca_dev;
1880 __u16 brightness;
1881
1882 brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x11, 2);
1883 sd->brightness = brightness << 1;
1884} 1888}
1885 1889
1886static void setcontrast(struct gspca_dev *gspca_dev) 1890static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1895,7 +1899,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1895 1899
1896static void getcontrast(struct gspca_dev *gspca_dev) 1900static void getcontrast(struct gspca_dev *gspca_dev)
1897{ 1901{
1898/* spca50x->contrast = 0xaa01; */
1899} 1902}
1900 1903
1901static void setcolors(struct gspca_dev *gspca_dev) 1904static void setcolors(struct gspca_dev *gspca_dev)
@@ -1907,11 +1910,20 @@ static void setcolors(struct gspca_dev *gspca_dev)
1907 1910
1908static void getcolors(struct gspca_dev *gspca_dev) 1911static void getcolors(struct gspca_dev *gspca_dev)
1909{ 1912{
1913}
1914
1915static void setblue_balance(struct gspca_dev *gspca_dev)
1916{
1917 struct sd *sd = (struct sd *) gspca_dev;
1918
1919 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->blue_balance);
1920}
1921
1922static void setred_balance(struct gspca_dev *gspca_dev)
1923{
1910 struct sd *sd = (struct sd *) gspca_dev; 1924 struct sd *sd = (struct sd *) gspca_dev;
1911 1925
1912 sd->colors = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x0c, 2); 1926 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->red_balance);
1913/* sd->hue = (reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x13, */
1914/* 2) & 0xFF) << 8; */
1915} 1927}
1916 1928
1917/* this function is called at probe time */ 1929/* this function is called at probe time */
@@ -1930,6 +1942,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
1930 sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; 1942 sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value;
1931 sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; 1943 sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value;
1932 1944
1945 return 0;
1946}
1947
1948/* this function is called at probe and resume time */
1949static int sd_init(struct gspca_dev *gspca_dev)
1950{
1951 struct sd *sd = (struct sd *) gspca_dev;
1952
1933 switch (sd->subtype) { 1953 switch (sd->subtype) {
1934 case Arowana300KCMOSCamera: 1954 case Arowana300KCMOSCamera:
1935 case SmileIntlCamera: 1955 case SmileIntlCamera:
@@ -1948,15 +1968,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
1948 goto error; 1968 goto error;
1949 break; 1969 break;
1950 } 1970 }
1971 PDEBUG(D_STREAM, "Initializing SPCA501 finished");
1951 return 0; 1972 return 0;
1952error: 1973error:
1953 return -EINVAL; 1974 return -EINVAL;
1954} 1975}
1955 1976
1956/* this function is called at probe and resume time */ 1977static int sd_start(struct gspca_dev *gspca_dev)
1957static int sd_init(struct gspca_dev *gspca_dev)
1958{ 1978{
1959 struct sd *sd = (struct sd *) gspca_dev; 1979 struct sd *sd = (struct sd *) gspca_dev;
1980 struct usb_device *dev = gspca_dev->dev;
1981 int mode;
1960 1982
1961 switch (sd->subtype) { 1983 switch (sd->subtype) {
1962 case ThreeComHomeConnectLite: 1984 case ThreeComHomeConnectLite:
@@ -1976,14 +1998,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
1976 /* Generic 501 open data */ 1998 /* Generic 501 open data */
1977 write_vector(gspca_dev, spca501_open_data); 1999 write_vector(gspca_dev, spca501_open_data);
1978 } 2000 }
1979 PDEBUG(D_STREAM, "Initializing SPCA501 finished");
1980 return 0;
1981}
1982
1983static int sd_start(struct gspca_dev *gspca_dev)
1984{
1985 struct usb_device *dev = gspca_dev->dev;
1986 int mode;
1987 2001
1988 /* memorize the wanted pixel format */ 2002 /* memorize the wanted pixel format */
1989 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 2003 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -2113,6 +2127,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2113 return 0; 2127 return 0;
2114} 2128}
2115 2129
2130static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
2131{
2132 struct sd *sd = (struct sd *) gspca_dev;
2133
2134 sd->blue_balance = val;
2135 if (gspca_dev->streaming)
2136 setblue_balance(gspca_dev);
2137 return 0;
2138}
2139
2140static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2141{
2142 struct sd *sd = (struct sd *) gspca_dev;
2143
2144 *val = sd->blue_balance;
2145 return 0;
2146}
2147
2148static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2149{
2150 struct sd *sd = (struct sd *) gspca_dev;
2151
2152 sd->red_balance = val;
2153 if (gspca_dev->streaming)
2154 setred_balance(gspca_dev);
2155 return 0;
2156}
2157
2158static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2159{
2160 struct sd *sd = (struct sd *) gspca_dev;
2161
2162 *val = sd->red_balance;
2163 return 0;
2164}
2165
2116/* sub-driver description */ 2166/* sub-driver description */
2117static const struct sd_desc sd_desc = { 2167static const struct sd_desc sd_desc = {
2118 .name = MODULE_NAME, 2168 .name = MODULE_NAME,
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 895b9fe4018c..2a33a29010ee 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -59,7 +59,7 @@ static struct ctrl sd_ctrls[] = {
59 }, 59 },
60}; 60};
61 61
62static struct v4l2_pix_format vga_mode[] = { 62static const 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, 64 .bytesperline = 160,
65 .sizeimage = 160 * 120 * 3 / 2, 65 .sizeimage = 160 * 120 * 3 / 2,
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 645ee9d44d02..96e2512e0621 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -110,7 +110,7 @@ static struct ctrl sd_ctrls[] = {
110 }, 110 },
111}; 111};
112 112
113static struct v4l2_pix_format vga_mode[] = { 113static const 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, 115 .bytesperline = 160,
116 .sizeimage = 160 * 120 * 3 / 2, 116 .sizeimage = 160 * 120 * 3 / 2,
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 63ec902c895d..be5d740a315d 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -62,7 +62,7 @@ static struct ctrl sd_ctrls[] = {
62 }, 62 },
63}; 63};
64 64
65static struct v4l2_pix_format sif_mode[] = { 65static const struct v4l2_pix_format sif_mode[] = {
66 {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, 66 {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
67 .bytesperline = 160, 67 .bytesperline = 160,
68 .sizeimage = 160 * 120 * 3 / 2, 68 .sizeimage = 160 * 120 * 3 / 2,
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index c3de4e44123d..3c9288019e96 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -32,22 +32,22 @@ 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 __u16 contrast; /* rev72a only */
36#define CONTRAST_MIN 0x0000
37#define CONTRAST_DEF 0x2000
38#define CONTRAST_MAX 0x3fff
39
40 __u16 exposure; /* rev12a only */ 35 __u16 exposure; /* rev12a only */
41#define EXPOSURE_MIN 1 36#define EXPOSURE_MIN 1
42#define EXPOSURE_DEF 200 37#define EXPOSURE_DEF 200
43#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */ 38#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
44 39
40 __u8 contrast; /* rev72a only */
41#define CONTRAST_MIN 0x00
42#define CONTRAST_DEF 0x20
43#define CONTRAST_MAX 0x3f
44
45 __u8 brightness; /* rev72a only */ 45 __u8 brightness; /* rev72a only */
46#define BRIGHTNESS_MIN 0 46#define BRIGHTNESS_MIN 0
47#define BRIGHTNESS_DEF 32 47#define BRIGHTNESS_DEF 0x20
48#define BRIGHTNESS_MAX 63 48#define BRIGHTNESS_MAX 0x3f
49 49
50 __u8 white; /* rev12a only */ 50 __u8 white;
51#define WHITE_MIN 1 51#define WHITE_MIN 1
52#define WHITE_DEF 0x40 52#define WHITE_DEF 0x40
53#define WHITE_MAX 0x7f 53#define WHITE_MAX 0x7f
@@ -73,7 +73,7 @@ struct sd {
73#define AG_CNT_START 13 73#define AG_CNT_START 13
74}; 74};
75 75
76static struct v4l2_pix_format sif_012a_mode[] = { 76static const struct v4l2_pix_format sif_012a_mode[] = {
77 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 77 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
78 .bytesperline = 160, 78 .bytesperline = 160,
79 .sizeimage = 160 * 120, 79 .sizeimage = 160 * 120,
@@ -96,7 +96,7 @@ static struct v4l2_pix_format sif_012a_mode[] = {
96 .priv = 0}, 96 .priv = 0},
97}; 97};
98 98
99static struct v4l2_pix_format sif_072a_mode[] = { 99static const struct v4l2_pix_format sif_072a_mode[] = {
100 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 100 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
101 .bytesperline = 160, 101 .bytesperline = 160,
102 .sizeimage = 160 * 120, 102 .sizeimage = 160 * 120,
@@ -146,98 +146,7 @@ static struct v4l2_pix_format sif_072a_mode[] = {
146#define SPCA561_SNAPBIT 0x20 146#define SPCA561_SNAPBIT 0x20
147#define SPCA561_SNAPCTRL 0x40 147#define SPCA561_SNAPCTRL 0x40
148 148
149static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value) 149static const __u16 rev72a_init_data1[][2] = {
150{
151 int ret;
152
153 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
154 0, /* request */
155 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
156 value, index, NULL, 0, 500);
157 PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
158 if (ret < 0)
159 PDEBUG(D_ERR, "reg write: error %d", ret);
160}
161
162static void write_vector(struct gspca_dev *gspca_dev,
163 const __u16 data[][2])
164{
165 struct usb_device *dev = gspca_dev->dev;
166 int i;
167
168 i = 0;
169 while (data[i][1] != 0) {
170 reg_w_val(dev, data[i][1], data[i][0]);
171 i++;
172 }
173}
174
175/* read 'len' bytes to gspca_dev->usb_buf */
176static void reg_r(struct gspca_dev *gspca_dev,
177 __u16 index, __u16 length)
178{
179 usb_control_msg(gspca_dev->dev,
180 usb_rcvctrlpipe(gspca_dev->dev, 0),
181 0, /* request */
182 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
183 0, /* value */
184 index, gspca_dev->usb_buf, length, 500);
185}
186
187static void reg_w_buf(struct gspca_dev *gspca_dev,
188 __u16 index, const __u8 *buffer, __u16 len)
189{
190 memcpy(gspca_dev->usb_buf, buffer, len);
191 usb_control_msg(gspca_dev->dev,
192 usb_sndctrlpipe(gspca_dev->dev, 0),
193 0, /* request */
194 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
195 0, /* value */
196 index, gspca_dev->usb_buf, len, 500);
197}
198
199static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
200{
201 int retry = 60;
202 __u8 DataLow;
203 __u8 DataHight;
204
205 DataLow = valeur;
206 DataHight = valeur >> 8;
207 reg_w_val(gspca_dev->dev, 0x8801, reg);
208 reg_w_val(gspca_dev->dev, 0x8805, DataLow);
209 reg_w_val(gspca_dev->dev, 0x8800, DataHight);
210 while (retry--) {
211 reg_r(gspca_dev, 0x8803, 1);
212 if (!gspca_dev->usb_buf[0])
213 break;
214 }
215}
216
217static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
218{
219 int retry = 60;
220 __u8 value;
221 __u8 vallsb;
222
223 reg_w_val(gspca_dev->dev, 0x8804, 0x92);
224 reg_w_val(gspca_dev->dev, 0x8801, reg);
225 reg_w_val(gspca_dev->dev, 0x8802, (mode | 0x01));
226 do {
227 reg_r(gspca_dev, 0x8803, 1);
228 if (!gspca_dev->usb_buf[0])
229 break;
230 } while (--retry);
231 if (retry == 0)
232 return -1;
233 reg_r(gspca_dev, 0x8800, 1);
234 value = gspca_dev->usb_buf[0];
235 reg_r(gspca_dev, 0x8805, 1);
236 vallsb = gspca_dev->usb_buf[0];
237 return ((int) value << 8) | vallsb;
238}
239
240static const __u16 spca561_init_data[][2] = {
241 {0x0000, 0x8114}, /* Software GPIO output data */ 150 {0x0000, 0x8114}, /* Software GPIO output data */
242 {0x0001, 0x8114}, /* Software GPIO output data */ 151 {0x0001, 0x8114}, /* Software GPIO output data */
243 {0x0000, 0x8112}, /* Some kind of reset */ 152 {0x0000, 0x8112}, /* Some kind of reset */
@@ -247,44 +156,26 @@ static const __u16 spca561_init_data[][2] = {
247 {0x0001, 0x8118}, /* Conf sensor */ 156 {0x0001, 0x8118}, /* Conf sensor */
248 {0x0092, 0x8804}, /* I know nothing about these */ 157 {0x0092, 0x8804}, /* I know nothing about these */
249 {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ 158 {0x0010, 0x8802}, /* 0x88xx registers, so I won't */
250 /***************/
251 {0x000d, 0x8805}, /* sensor default setting */ 159 {0x000d, 0x8805}, /* sensor default setting */
252 {0x0001, 0x8801}, /* 1 <- 0x0d */ 160 {}
253 {0x0000, 0x8800}, 161};
254 {0x0018, 0x8805}, 162static const __u16 rev72a_init_sensor1[][2] = {
255 {0x0002, 0x8801}, /* 2 <- 0x18 */ 163 /* ms-win values */
256 {0x0000, 0x8800}, 164 {0x0001, 0x0018}, /* 0x01 <- 0x0d */
257 {0x0065, 0x8805}, 165 {0x0002, 0x0065}, /* 0x02 <- 0x18 */
258 {0x0004, 0x8801}, /* 4 <- 0x01 0x65 */ 166 {0x0004, 0x0121}, /* 0x04 <- 0x0165 */
259 {0x0001, 0x8800}, 167 {0x0005, 0x00aa}, /* 0x05 <- 0x21 */
260 {0x0021, 0x8805}, 168 {0x0007, 0x0004}, /* 0x07 <- 0xaa */
261 {0x0005, 0x8801}, /* 5 <- 0x21 */ 169 {0x0020, 0x1502}, /* 0x20 <- 0x1504 */
262 {0x0000, 0x8800}, 170 {0x0039, 0x0010}, /* 0x39 <- 0x02 */
263 {0x00aa, 0x8805}, 171 {0x0035, 0x0049}, /* 0x35 <- 0x10 */
264 {0x0007, 0x8801}, /* 7 <- 0xaa */ 172 {0x0009, 0x100b}, /* 0x09 <- 0x1049 */
265 {0x0000, 0x8800}, 173 {0x0028, 0x000f}, /* 0x28 <- 0x0b */
266 {0x0004, 0x8805}, 174 {0x003b, 0x003c}, /* 0x3b <- 0x0f */
267 {0x0020, 0x8801}, /* 0x20 <- 0x15 0x04 */ 175 {0x003c, 0x0000}, /* 0x3c <- 0x00 */
268 {0x0015, 0x8800}, 176 {}
269 {0x0002, 0x8805}, 177};
270 {0x0039, 0x8801}, /* 0x39 <- 0x02 */ 178static const __u16 rev72a_init_data2[][2] = {
271 {0x0000, 0x8800},
272 {0x0010, 0x8805},
273 {0x0035, 0x8801}, /* 0x35 <- 0x10 */
274 {0x0000, 0x8800},
275 {0x0049, 0x8805},
276 {0x0009, 0x8801}, /* 0x09 <- 0x10 0x49 */
277 {0x0010, 0x8800},
278 {0x000b, 0x8805},
279 {0x0028, 0x8801}, /* 0x28 <- 0x0b */
280 {0x0000, 0x8800},
281 {0x000f, 0x8805},
282 {0x003b, 0x8801}, /* 0x3b <- 0x0f */
283 {0x0000, 0x8800},
284 {0x0000, 0x8805},
285 {0x003c, 0x8801}, /* 0x3c <- 0x00 */
286 {0x0000, 0x8800},
287 /***************/
288 {0x0018, 0x8601}, /* Pixel/line selection for color separation */ 179 {0x0018, 0x8601}, /* Pixel/line selection for color separation */
289 {0x0000, 0x8602}, /* Optical black level for user setting */ 180 {0x0000, 0x8602}, /* Optical black level for user setting */
290 {0x0060, 0x8604}, /* Optical black horizontal offset */ 181 {0x0060, 0x8604}, /* Optical black horizontal offset */
@@ -309,10 +200,11 @@ static const __u16 spca561_init_data[][2] = {
309 {0x0004, 0x8612}, /* Gr offset for white balance */ 200 {0x0004, 0x8612}, /* Gr offset for white balance */
310 {0x0007, 0x8613}, /* B offset for white balance */ 201 {0x0007, 0x8613}, /* B offset for white balance */
311 {0x0000, 0x8614}, /* Gb offset for white balance */ 202 {0x0000, 0x8614}, /* Gb offset for white balance */
312 {0x008c, 0x8651}, /* R gain for white balance */ 203/* from ms-win */
313 {0x008c, 0x8652}, /* Gr gain for white balance */ 204 {0x0035, 0x8651}, /* R gain for white balance */
314 {0x00b5, 0x8653}, /* B gain for white balance */ 205 {0x0040, 0x8652}, /* Gr gain for white balance */
315 {0x008c, 0x8654}, /* Gb gain for white balance */ 206 {0x005f, 0x8653}, /* B gain for white balance */
207 {0x0040, 0x8654}, /* Gb gain for white balance */
316 {0x0002, 0x8502}, /* Maximum average bit rate stuff */ 208 {0x0002, 0x8502}, /* Maximum average bit rate stuff */
317 209
318 {0x0011, 0x8802}, 210 {0x0011, 0x8802},
@@ -324,29 +216,22 @@ static const __u16 spca561_init_data[][2] = {
324 216
325 {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ 217 {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
326 {0x0003, 0x865c}, /* Vertical offset for valid lines */ 218 {0x0003, 0x865c}, /* Vertical offset for valid lines */
327 /***************//* sensor active */ 219 {}
328 {0x0003, 0x8801}, /* 0x03 <- 0x01 0x21 //289 */ 220};
329 {0x0021, 0x8805}, 221static const __u16 rev72a_init_sensor2[][2] = {
330 {0x0001, 0x8800}, 222 /* ms-win values */
331 {0x0004, 0x8801}, /* 0x04 <- 0x01 0x65 //357 */ 223 {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */
332 {0x0065, 0x8805}, 224 {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */
333 {0x0001, 0x8800}, 225 {0x0005, 0x002f}, /* 0x05 <- 0x2f */
334 {0x0005, 0x8801}, /* 0x05 <- 0x2f */ 226 {0x0006, 0x0000}, /* 0x06 <- 0 */
335 {0x002f, 0x8805}, 227 {0x000a, 0x0002}, /* 0x0a <- 2 */
336 {0x0000, 0x8800}, 228 {0x0009, 0x1061}, /* 0x09 <- 0x1061 */
337 {0x0006, 0x8801}, /* 0x06 <- 0 */ 229 {0x0035, 0x0014}, /* 0x35 <- 0x14 */
338 {0x0000, 0x8805}, 230 {}
339 {0x0000, 0x8800}, 231};
340 {0x000a, 0x8801}, /* 0x0a <- 2 */ 232static const __u16 rev72a_init_data3[][2] = {
341 {0x0002, 0x8805},
342 {0x0000, 0x8800},
343 {0x0009, 0x8801}, /* 0x09 <- 0x1061 */
344 {0x0061, 0x8805},
345 {0x0010, 0x8800},
346 {0x0035, 0x8801}, /* 0x35 <-0x14 */
347 {0x0014, 0x8805},
348 {0x0000, 0x8800},
349 {0x0030, 0x8112}, /* ISO and drop packet enable */ 233 {0x0030, 0x8112}, /* ISO and drop packet enable */
234/*fixme: should stop here*/
350 {0x0000, 0x8112}, /* Some kind of reset ???? */ 235 {0x0000, 0x8112}, /* Some kind of reset ???? */
351 {0x0009, 0x8118}, /* Enable sensor and set standby */ 236 {0x0009, 0x8118}, /* Enable sensor and set standby */
352 {0x0000, 0x8114}, /* Software GPIO output data */ 237 {0x0000, 0x8114}, /* Software GPIO output data */
@@ -434,7 +319,6 @@ static const __u16 spca561_init_data[][2] = {
434 {} 319 {}
435}; 320};
436 321
437
438/******************** QC Express etch2 stuff ********************/ 322/******************** QC Express etch2 stuff ********************/
439static const __u16 Pb100_1map8300[][2] = { 323static const __u16 Pb100_1map8300[][2] = {
440 /* reg, value */ 324 /* reg, value */
@@ -515,22 +399,112 @@ static const __u16 spca561_161rev12A_data2[][2] = {
515 {} 399 {}
516}; 400};
517 401
518static void sensor_mapwrite(struct gspca_dev *gspca_dev, 402static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
519 const __u16 sensormap[][2]) 403{
404 int ret;
405
406 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
407 0, /* request */
408 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
409 value, index, NULL, 0, 500);
410 PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
411 if (ret < 0)
412 PDEBUG(D_ERR, "reg write: error %d", ret);
413}
414
415static void write_vector(struct gspca_dev *gspca_dev,
416 const __u16 data[][2])
520{ 417{
521 int i = 0; 418 struct usb_device *dev = gspca_dev->dev;
522 __u8 usbval[2]; 419 int i;
523 420
524 while (sensormap[i][0]) { 421 i = 0;
525 usbval[0] = sensormap[i][1]; 422 while (data[i][1] != 0) {
526 usbval[1] = sensormap[i][1] >> 8; 423 reg_w_val(dev, data[i][1], data[i][0]);
527 reg_w_buf(gspca_dev, sensormap[i][0], usbval, 2);
528 i++; 424 i++;
529 } 425 }
530} 426}
427
428/* read 'len' bytes to gspca_dev->usb_buf */
429static void reg_r(struct gspca_dev *gspca_dev,
430 __u16 index, __u16 length)
431{
432 usb_control_msg(gspca_dev->dev,
433 usb_rcvctrlpipe(gspca_dev->dev, 0),
434 0, /* request */
435 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
436 0, /* value */
437 index, gspca_dev->usb_buf, length, 500);
438}
439
440/* write 'len' bytes from gspca_dev->usb_buf */
441static void reg_w_buf(struct gspca_dev *gspca_dev,
442 __u16 index, __u16 len)
443{
444 usb_control_msg(gspca_dev->dev,
445 usb_sndctrlpipe(gspca_dev->dev, 0),
446 0, /* request */
447 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
448 0, /* value */
449 index, gspca_dev->usb_buf, len, 500);
450}
451
452static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
453{
454 int retry = 60;
455
456 reg_w_val(gspca_dev->dev, 0x8801, reg);
457 reg_w_val(gspca_dev->dev, 0x8805, value);
458 reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
459 do {
460 reg_r(gspca_dev, 0x8803, 1);
461 if (!gspca_dev->usb_buf[0])
462 return;
463 } while (--retry);
464}
465
466static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
467{
468 int retry = 60;
469 __u8 value;
470
471 reg_w_val(gspca_dev->dev, 0x8804, 0x92);
472 reg_w_val(gspca_dev->dev, 0x8801, reg);
473 reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
474 do {
475 reg_r(gspca_dev, 0x8803, 1);
476 if (!gspca_dev->usb_buf[0]) {
477 reg_r(gspca_dev, 0x8800, 1);
478 value = gspca_dev->usb_buf[0];
479 reg_r(gspca_dev, 0x8805, 1);
480 return ((int) value << 8) | gspca_dev->usb_buf[0];
481 }
482 } while (--retry);
483 return -1;
484}
485
486static void sensor_mapwrite(struct gspca_dev *gspca_dev,
487 const __u16 (*sensormap)[2])
488{
489 while ((*sensormap)[0]) {
490 gspca_dev->usb_buf[0] = (*sensormap)[1];
491 gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
492 reg_w_buf(gspca_dev, (*sensormap)[0], 2);
493 sensormap++;
494 }
495}
496
497static void write_sensor_72a(struct gspca_dev *gspca_dev,
498 const __u16 (*sensor)[2])
499{
500 while ((*sensor)[0]) {
501 i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
502 sensor++;
503 }
504}
505
531static void init_161rev12A(struct gspca_dev *gspca_dev) 506static void init_161rev12A(struct gspca_dev *gspca_dev)
532{ 507{
533/* sensor_reset(gspca_dev); (not in win) */
534 write_vector(gspca_dev, spca561_161rev12A_data1); 508 write_vector(gspca_dev, spca561_161rev12A_data1);
535 sensor_mapwrite(gspca_dev, Pb100_1map8300); 509 sensor_mapwrite(gspca_dev, Pb100_1map8300);
536/*fixme: should be in sd_start*/ 510/*fixme: should be in sd_start*/
@@ -598,49 +572,68 @@ static int sd_init_12a(struct gspca_dev *gspca_dev)
598static int sd_init_72a(struct gspca_dev *gspca_dev) 572static int sd_init_72a(struct gspca_dev *gspca_dev)
599{ 573{
600 PDEBUG(D_STREAM, "Chip revision: 072a"); 574 PDEBUG(D_STREAM, "Chip revision: 072a");
601 write_vector(gspca_dev, spca561_init_data); 575 write_vector(gspca_dev, rev72a_init_data1);
576 write_sensor_72a(gspca_dev, rev72a_init_sensor1);
577 write_vector(gspca_dev, rev72a_init_data2);
578 write_sensor_72a(gspca_dev, rev72a_init_sensor2);
579 write_vector(gspca_dev, rev72a_init_data3);
602 return 0; 580 return 0;
603} 581}
604 582
605static void setcontrast(struct gspca_dev *gspca_dev) 583/* rev 72a only */
584static void setbrightness(struct gspca_dev *gspca_dev)
606{ 585{
607 struct sd *sd = (struct sd *) gspca_dev; 586 struct sd *sd = (struct sd *) gspca_dev;
608 struct usb_device *dev = gspca_dev->dev; 587 struct usb_device *dev = gspca_dev->dev;
609 __u8 lowb; 588 __u8 value;
610 589
611 switch (sd->chip_revision) { 590 value = sd->brightness;
612 case Rev072A:
613 lowb = sd->contrast >> 8;
614 reg_w_val(dev, 0x8651, lowb);
615 reg_w_val(dev, 0x8652, lowb);
616 reg_w_val(dev, 0x8653, lowb);
617 reg_w_val(dev, 0x8654, lowb);
618 break;
619 default: {
620/* case Rev012A: { */
621 static const __u8 Reg8391[] =
622 { 0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00 };
623 591
624 reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); 592 /* offsets for white balance */
625 reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); 593 reg_w_val(dev, 0x8611, value); /* R */
626 break; 594 reg_w_val(dev, 0x8612, value); /* Gr */
627 } 595 reg_w_val(dev, 0x8613, value); /* B */
628 } 596 reg_w_val(dev, 0x8614, value); /* Gb */
629} 597}
630 598
631/* rev12a only */
632static void setwhite(struct gspca_dev *gspca_dev) 599static void setwhite(struct gspca_dev *gspca_dev)
633{ 600{
634 struct sd *sd = (struct sd *) gspca_dev; 601 struct sd *sd = (struct sd *) gspca_dev;
635 __u16 white; 602 __u16 white;
636 __u8 reg8614, reg8616; 603 __u8 blue, red;
604 __u16 reg;
637 605
638 white = sd->white;
639 /* try to emulate MS-win as possible */ 606 /* try to emulate MS-win as possible */
640 reg8616 = 0x90 - white * 5 / 8; 607 white = sd->white;
641 reg_w_val(gspca_dev->dev, 0x8616, reg8616); 608 red = 0x20 + white * 3 / 8;
642 reg8614 = 0x20 + white * 3 / 8; 609 blue = 0x90 - white * 5 / 8;
643 reg_w_val(gspca_dev->dev, 0x8614, reg8614); 610 if (sd->chip_revision == Rev012A) {
611 reg = 0x8614;
612 } else {
613 reg = 0x8651;
614 red += sd->contrast - 0x20;
615 blue += sd->contrast - 0x20;
616 }
617 reg_w_val(gspca_dev->dev, reg, red);
618 reg_w_val(gspca_dev->dev, reg + 2, blue);
619}
620
621static void setcontrast(struct gspca_dev *gspca_dev)
622{
623 struct sd *sd = (struct sd *) gspca_dev;
624 struct usb_device *dev = gspca_dev->dev;
625 __u8 value;
626
627 if (sd->chip_revision != Rev072A)
628 return;
629 value = sd->contrast + 0x20;
630
631 /* gains for white balance */
632 setwhite(gspca_dev);
633/* reg_w_val(dev, 0x8651, value); * R - done by setwhite */
634 reg_w_val(dev, 0x8652, value); /* Gr */
635/* reg_w_val(dev, 0x8653, value); * B - done by setwhite */
636 reg_w_val(dev, 0x8654, value); /* Gb */
644} 637}
645 638
646/* rev 12a only */ 639/* rev 12a only */
@@ -649,7 +642,6 @@ static void setexposure(struct gspca_dev *gspca_dev)
649 struct sd *sd = (struct sd *) gspca_dev; 642 struct sd *sd = (struct sd *) gspca_dev;
650 int expo; 643 int expo;
651 int clock_divider; 644 int clock_divider;
652 __u8 data[2];
653 645
654 /* Register 0x8309 controls exposure for the spca561, 646 /* Register 0x8309 controls exposure for the spca561,
655 the basic exposure setting goes from 1-2047, where 1 is completely 647 the basic exposure setting goes from 1-2047, where 1 is completely
@@ -673,20 +665,19 @@ static void setexposure(struct gspca_dev *gspca_dev)
673 clock_divider = 3; 665 clock_divider = 3;
674 } 666 }
675 expo |= clock_divider << 11; 667 expo |= clock_divider << 11;
676 data[0] = expo; 668 gspca_dev->usb_buf[0] = expo;
677 data[1] = expo >> 8; 669 gspca_dev->usb_buf[1] = expo >> 8;
678 reg_w_buf(gspca_dev, 0x8309, data, 2); 670 reg_w_buf(gspca_dev, 0x8309, 2);
679} 671}
680 672
681/* rev 12a only */ 673/* rev 12a only */
682static void setgain(struct gspca_dev *gspca_dev) 674static void setgain(struct gspca_dev *gspca_dev)
683{ 675{
684 struct sd *sd = (struct sd *) gspca_dev; 676 struct sd *sd = (struct sd *) gspca_dev;
685 __u8 data[2];
686 677
687 data[0] = sd->gain; 678 gspca_dev->usb_buf[0] = sd->gain;
688 data[1] = 0; 679 gspca_dev->usb_buf[1] = 0;
689 reg_w_buf(gspca_dev, 0x8335, data, 2); 680 reg_w_buf(gspca_dev, 0x8335, 2);
690} 681}
691 682
692static void setautogain(struct gspca_dev *gspca_dev) 683static void setautogain(struct gspca_dev *gspca_dev)
@@ -702,9 +693,9 @@ static void setautogain(struct gspca_dev *gspca_dev)
702static int sd_start_12a(struct gspca_dev *gspca_dev) 693static int sd_start_12a(struct gspca_dev *gspca_dev)
703{ 694{
704 struct usb_device *dev = gspca_dev->dev; 695 struct usb_device *dev = gspca_dev->dev;
705 int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */
706 __u8 Reg8307[] = { 0xaa, 0x00 };
707 int mode; 696 int mode;
697 static const __u8 Reg8391[8] =
698 {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
708 699
709 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 700 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
710 if (mode <= 1) { 701 if (mode <= 1) {
@@ -716,14 +707,21 @@ static int sd_start_12a(struct gspca_dev *gspca_dev)
716 * is sufficient to push raw frames at ~20fps */ 707 * is sufficient to push raw frames at ~20fps */
717 reg_w_val(dev, 0x8500, mode); 708 reg_w_val(dev, 0x8500, mode);
718 } /* -- qq@kuku.eu.org */ 709 } /* -- qq@kuku.eu.org */
719 reg_w_buf(gspca_dev, 0x8307, Reg8307, 2); 710
720 reg_w_val(gspca_dev->dev, 0x8700, Clck); 711 gspca_dev->usb_buf[0] = 0xaa;
712 gspca_dev->usb_buf[1] = 0x00;
713 reg_w_buf(gspca_dev, 0x8307, 2);
714 /* clock - lower 0x8X values lead to fps > 30 */
715 reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
721 /* 0x8f 0x85 0x27 clock */ 716 /* 0x8f 0x85 0x27 clock */
722 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20); 717 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
723 reg_w_val(gspca_dev->dev, 0x850b, 0x03); 718 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
724 setcontrast(gspca_dev); 719 memcpy(gspca_dev->usb_buf, Reg8391, 8);
720 reg_w_buf(gspca_dev, 0x8391, 8);
721 reg_w_buf(gspca_dev, 0x8390, 8);
725 setwhite(gspca_dev); 722 setwhite(gspca_dev);
726 setautogain(gspca_dev); 723 setautogain(gspca_dev);
724/* setgain(gspca_dev); */
727 setexposure(gspca_dev); 725 setexposure(gspca_dev);
728 return 0; 726 return 0;
729} 727}
@@ -750,6 +748,9 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
750 reg_w_val(dev, 0x8500, mode); /* mode */ 748 reg_w_val(dev, 0x8500, mode); /* mode */
751 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ 749 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
752 reg_w_val(dev, 0x8112, 0x10 | 0x20); 750 reg_w_val(dev, 0x8112, 0x10 | 0x20);
751 setcontrast(gspca_dev);
752/* setbrightness(gspca_dev); * fixme: bad values */
753 setwhite(gspca_dev);
753 setautogain(gspca_dev); 754 setautogain(gspca_dev);
754 return 0; 755 return 0;
755} 756}
@@ -791,7 +792,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
791 __u8 luma_mean = 110; 792 __u8 luma_mean = 110;
792 __u8 luma_delta = 20; 793 __u8 luma_delta = 20;
793 __u8 spring = 4; 794 __u8 spring = 4;
794 __u8 reg8339[2];
795 795
796 if (sd->ag_cnt < 0) 796 if (sd->ag_cnt < 0)
797 return; 797 return;
@@ -834,13 +834,13 @@ static void do_autogain(struct gspca_dev *gspca_dev)
834 834
835 if (gainG > 0x3f) 835 if (gainG > 0x3f)
836 gainG = 0x3f; 836 gainG = 0x3f;
837 else if (gainG < 4) 837 else if (gainG < 3)
838 gainG = 3; 838 gainG = 3;
839 i2c_write(gspca_dev, gainG, 0x35); 839 i2c_write(gspca_dev, gainG, 0x35);
840 840
841 if (expotimes >= 0x0256) 841 if (expotimes > 0x0256)
842 expotimes = 0x0256; 842 expotimes = 0x0256;
843 else if (expotimes < 4) 843 else if (expotimes < 3)
844 expotimes = 3; 844 expotimes = 3;
845 i2c_write(gspca_dev, expotimes | pixelclk, 0x09); 845 i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
846 } 846 }
@@ -848,13 +848,13 @@ static void do_autogain(struct gspca_dev *gspca_dev)
848 case Rev012A: 848 case Rev012A:
849 reg_r(gspca_dev, 0x8330, 2); 849 reg_r(gspca_dev, 0x8330, 2);
850 if (gspca_dev->usb_buf[1] > 0x08) { 850 if (gspca_dev->usb_buf[1] > 0x08) {
851 reg8339[0] = ++sd->expo12a; 851 gspca_dev->usb_buf[0] = ++sd->expo12a;
852 reg8339[1] = 0; 852 gspca_dev->usb_buf[1] = 0;
853 reg_w_buf(gspca_dev, 0x8339, reg8339, 2); 853 reg_w_buf(gspca_dev, 0x8339, 2);
854 } else if (gspca_dev->usb_buf[1] < 0x02) { 854 } else if (gspca_dev->usb_buf[1] < 0x02) {
855 reg8339[0] = --sd->expo12a; 855 gspca_dev->usb_buf[0] = --sd->expo12a;
856 reg8339[1] = 0; 856 gspca_dev->usb_buf[1] = 0;
857 reg_w_buf(gspca_dev, 0x8339, reg8339, 2); 857 reg_w_buf(gspca_dev, 0x8339, 2);
858 } 858 }
859 break; 859 break;
860 } 860 }
@@ -867,8 +867,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
867{ 867{
868 struct sd *sd = (struct sd *) gspca_dev; 868 struct sd *sd = (struct sd *) gspca_dev;
869 869
870 switch (data[0]) { 870 switch (data[0]) { /* sequence number */
871 case 0: /* start of frame */ 871 case 0: /* start of frame */
872 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 872 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
873 data, 0); 873 data, 0);
874 data += SPCA561_OFFSET_DATA; 874 data += SPCA561_OFFSET_DATA;
@@ -890,8 +890,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
890 frame, data, len); 890 frame, data, len);
891 } 891 }
892 return; 892 return;
893 case 0xff: /* drop */ 893 case 0xff: /* drop (empty mpackets) */
894/* gspca_dev->last_packet_type = DISCARD_PACKET; */
895 return; 894 return;
896 } 895 }
897 data++; 896 data++;
@@ -900,55 +899,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
900} 899}
901 900
902/* rev 72a only */ 901/* rev 72a only */
903static void setbrightness(struct gspca_dev *gspca_dev)
904{
905 struct sd *sd = (struct sd *) gspca_dev;
906 __u8 value;
907
908 value = sd->brightness;
909 reg_w_val(gspca_dev->dev, 0x8611, value);
910 reg_w_val(gspca_dev->dev, 0x8612, value);
911 reg_w_val(gspca_dev->dev, 0x8613, value);
912 reg_w_val(gspca_dev->dev, 0x8614, value);
913}
914
915static void getbrightness(struct gspca_dev *gspca_dev)
916{
917 struct sd *sd = (struct sd *) gspca_dev;
918 __u16 tot;
919
920 tot = 0;
921 reg_r(gspca_dev, 0x8611, 1);
922 tot += gspca_dev->usb_buf[0];
923 reg_r(gspca_dev, 0x8612, 1);
924 tot += gspca_dev->usb_buf[0];
925 reg_r(gspca_dev, 0x8613, 1);
926 tot += gspca_dev->usb_buf[0];
927 reg_r(gspca_dev, 0x8614, 1);
928 tot += gspca_dev->usb_buf[0];
929 sd->brightness = tot >> 2;
930}
931
932/* rev72a only */
933static void getcontrast(struct gspca_dev *gspca_dev)
934{
935 struct sd *sd = (struct sd *) gspca_dev;
936 __u16 tot;
937
938 tot = 0;
939 reg_r(gspca_dev, 0x8651, 1);
940 tot += gspca_dev->usb_buf[0];
941 reg_r(gspca_dev, 0x8652, 1);
942 tot += gspca_dev->usb_buf[0];
943 reg_r(gspca_dev, 0x8653, 1);
944 tot += gspca_dev->usb_buf[0];
945 reg_r(gspca_dev, 0x8654, 1);
946 tot += gspca_dev->usb_buf[0];
947 sd->contrast = tot << 6;
948 PDEBUG(D_CONF, "get contrast %d", sd->contrast);
949}
950
951/* rev 72a only */
952static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 902static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
953{ 903{
954 struct sd *sd = (struct sd *) gspca_dev; 904 struct sd *sd = (struct sd *) gspca_dev;
@@ -963,7 +913,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
963{ 913{
964 struct sd *sd = (struct sd *) gspca_dev; 914 struct sd *sd = (struct sd *) gspca_dev;
965 915
966 getbrightness(gspca_dev);
967 *val = sd->brightness; 916 *val = sd->brightness;
968 return 0; 917 return 0;
969} 918}
@@ -983,7 +932,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
983{ 932{
984 struct sd *sd = (struct sd *) gspca_dev; 933 struct sd *sd = (struct sd *) gspca_dev;
985 934
986 getcontrast(gspca_dev);
987 *val = sd->contrast; 935 *val = sd->contrast;
988 return 0; 936 return 0;
989} 937}
@@ -1006,7 +954,6 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1006 return 0; 954 return 0;
1007} 955}
1008 956
1009/* rev12a only */
1010static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val) 957static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
1011{ 958{
1012 struct sd *sd = (struct sd *) gspca_dev; 959 struct sd *sd = (struct sd *) gspca_dev;
@@ -1121,6 +1068,19 @@ static struct ctrl sd_ctrls_12a[] = {
1121 1068
1122static struct ctrl sd_ctrls_72a[] = { 1069static struct ctrl sd_ctrls_72a[] = {
1123 { 1070 {
1071 {
1072 .id = V4L2_CID_DO_WHITE_BALANCE,
1073 .type = V4L2_CTRL_TYPE_INTEGER,
1074 .name = "White Balance",
1075 .minimum = WHITE_MIN,
1076 .maximum = WHITE_MAX,
1077 .step = 1,
1078 .default_value = WHITE_DEF,
1079 },
1080 .set = sd_setwhite,
1081 .get = sd_getwhite,
1082 },
1083 {
1124 { 1084 {
1125 .id = V4L2_CID_BRIGHTNESS, 1085 .id = V4L2_CID_BRIGHTNESS,
1126 .type = V4L2_CTRL_TYPE_INTEGER, 1086 .type = V4L2_CTRL_TYPE_INTEGER,
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index d9d64911f22a..60de9af87fbb 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -109,7 +109,7 @@ static struct ctrl sd_ctrls[] = {
109 }, 109 },
110}; 110};
111 111
112static struct v4l2_pix_format vga_mode[] = { 112static const struct v4l2_pix_format vga_mode[] = {
113 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 113 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
114 .bytesperline = 320, 114 .bytesperline = 320,
115 .sizeimage = 320 * 240 * 3 / 8 + 590, 115 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -424,10 +424,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
424 424
425 /* beginning of the frame */ 425 /* beginning of the frame */
426#define STKHDRSZ 12 426#define STKHDRSZ 12
427 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 427 data += STKHDRSZ;
428 data + STKHDRSZ, len - STKHDRSZ); 428 len -= STKHDRSZ;
429#undef STKHDRSZ
430 return;
431 } 429 }
432 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 430 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
433} 431}
diff --git a/drivers/media/video/gspca/stv06xx/Kconfig b/drivers/media/video/gspca/stv06xx/Kconfig
new file mode 100644
index 000000000000..634ad38d9fb8
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/Kconfig
@@ -0,0 +1,9 @@
1config USB_STV06XX
2 tristate "STV06XX USB Camera Driver"
3 depends on USB_GSPCA
4 help
5 Say Y here if you want support for cameras based on
6 the ST STV06XX chip.
7
8 To compile this driver as a module, choose M here: the
9 module will be called gspca_stv06xx.
diff --git a/drivers/media/video/gspca/stv06xx/Makefile b/drivers/media/video/gspca/stv06xx/Makefile
new file mode 100644
index 000000000000..feeaa94ab588
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/Makefile
@@ -0,0 +1,9 @@
1obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o
2
3gspca_stv06xx-objs := stv06xx.o \
4 stv06xx_vv6410.o \
5 stv06xx_hdcs.o \
6 stv06xx_pb0100.o
7
8EXTRA_CFLAGS += -Idrivers/media/video/gspca
9
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
new file mode 100644
index 000000000000..13a021e3cbb7
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -0,0 +1,522 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#include "stv06xx_sensor.h"
31
32MODULE_AUTHOR("Erik Andrén");
33MODULE_DESCRIPTION("STV06XX USB Camera Driver");
34MODULE_LICENSE("GPL");
35
36static int dump_bridge;
37static int dump_sensor;
38
39int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
40{
41 int err;
42 struct usb_device *udev = sd->gspca_dev.dev;
43 __u8 *buf = sd->gspca_dev.usb_buf;
44 u8 len = (i2c_data > 0xff) ? 2 : 1;
45
46 buf[0] = i2c_data & 0xff;
47 buf[1] = (i2c_data >> 8) & 0xff;
48
49 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
50 0x04, 0x40, address, 0, buf, len,
51 STV06XX_URB_MSG_TIMEOUT);
52
53
54 PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d",
55 i2c_data, address, err);
56
57 return (err < 0) ? err : 0;
58}
59
60int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data)
61{
62 int err;
63 struct usb_device *udev = sd->gspca_dev.dev;
64 __u8 *buf = sd->gspca_dev.usb_buf;
65
66 err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
67 0x04, 0xc0, address, 0, buf, 1,
68 STV06XX_URB_MSG_TIMEOUT);
69
70 *i2c_data = buf[0];
71
72 PDEBUG(D_CONF, "Read 0x%x from address 0x%x, status %d",
73 *i2c_data, address, err);
74
75 return (err < 0) ? err : 0;
76}
77
78/* Wraps the normal write sensor bytes / words functions for writing a
79 single value */
80int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value)
81{
82 if (sd->sensor->i2c_len == 2) {
83 u16 data[2] = { address, value };
84 return stv06xx_write_sensor_words(sd, data, 1);
85 } else {
86 u8 data[2] = { address, value };
87 return stv06xx_write_sensor_bytes(sd, data, 1);
88 }
89}
90
91static int stv06xx_write_sensor_finish(struct sd *sd)
92{
93 int err = 0;
94
95 if (IS_850(sd)) {
96 struct usb_device *udev = sd->gspca_dev.dev;
97 __u8 *buf = sd->gspca_dev.usb_buf;
98
99 /* Quickam Web needs an extra packet */
100 buf[0] = 0;
101 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
102 0x04, 0x40, 0x1704, 0, buf, 1,
103 STV06XX_URB_MSG_TIMEOUT);
104 }
105
106 return (err < 0) ? err : 0;
107}
108
109int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
110{
111 int err, i, j;
112 struct usb_device *udev = sd->gspca_dev.dev;
113 __u8 *buf = sd->gspca_dev.usb_buf;
114
115 PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len);
116 for (i = 0; i < len;) {
117 /* Build the command buffer */
118 memset(buf, 0, I2C_BUFFER_LENGTH);
119 for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) {
120 buf[j] = data[2*i];
121 buf[0x10 + j] = data[2*i+1];
122 PDEBUG(D_USBO, "I2C: Writing 0x%02x to reg 0x%02x",
123 data[2*i+1], data[2*i]);
124 }
125 buf[0x20] = sd->sensor->i2c_addr;
126 buf[0x21] = j - 1; /* Number of commands to send - 1 */
127 buf[0x22] = I2C_WRITE_CMD;
128 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
129 0x04, 0x40, 0x0400, 0, buf,
130 I2C_BUFFER_LENGTH,
131 STV06XX_URB_MSG_TIMEOUT);
132 if (err < 0)
133 return err;
134 }
135 return stv06xx_write_sensor_finish(sd);
136}
137
138int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
139{
140 int err, i, j;
141 struct usb_device *udev = sd->gspca_dev.dev;
142 __u8 *buf = sd->gspca_dev.usb_buf;
143
144 PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len);
145
146 for (i = 0; i < len;) {
147 /* Build the command buffer */
148 memset(buf, 0, I2C_BUFFER_LENGTH);
149 for (j = 0; j < I2C_MAX_WORDS && i < len; j++, i++) {
150 buf[j] = data[2*i];
151 buf[0x10 + j * 2] = data[2*i+1];
152 buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8;
153 PDEBUG(D_USBO, "I2C: Writing 0x%04x to reg 0x%02x",
154 data[2*i+1], data[2*i]);
155 }
156 buf[0x20] = sd->sensor->i2c_addr;
157 buf[0x21] = j - 1; /* Number of commands to send - 1 */
158 buf[0x22] = I2C_WRITE_CMD;
159 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
160 0x04, 0x40, 0x0400, 0, buf,
161 I2C_BUFFER_LENGTH,
162 STV06XX_URB_MSG_TIMEOUT);
163 if (err < 0)
164 return err;
165 }
166 return stv06xx_write_sensor_finish(sd);
167}
168
169int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
170{
171 int err;
172 struct usb_device *udev = sd->gspca_dev.dev;
173 __u8 *buf = sd->gspca_dev.usb_buf;
174
175 err = stv06xx_write_bridge(sd, STV_I2C_FLUSH, sd->sensor->i2c_flush);
176 if (err < 0)
177 return err;
178
179 /* Clear mem */
180 memset(buf, 0, I2C_BUFFER_LENGTH);
181
182 buf[0] = address;
183 buf[0x20] = sd->sensor->i2c_addr;
184 buf[0x21] = 0;
185
186 /* Read I2C register */
187 buf[0x22] = I2C_READ_CMD;
188
189 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
190 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH,
191 STV06XX_URB_MSG_TIMEOUT);
192 if (err < 0) {
193 PDEBUG(D_ERR, "I2C Read: error writing address: %d", err);
194 return err;
195 }
196
197 err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
198 0x04, 0xc0, 0x1410, 0, buf, sd->sensor->i2c_len,
199 STV06XX_URB_MSG_TIMEOUT);
200 if (sd->sensor->i2c_len == 2)
201 *value = buf[0] | (buf[1] << 8);
202 else
203 *value = buf[0];
204
205 PDEBUG(D_USBO, "I2C: Read 0x%x from address 0x%x, status: %d",
206 *value, address, err);
207
208 return (err < 0) ? err : 0;
209}
210
211/* Dumps all bridge registers */
212static void stv06xx_dump_bridge(struct sd *sd)
213{
214 int i;
215 u8 data, buf;
216
217 info("Dumping all stv06xx bridge registers");
218 for (i = 0x1400; i < 0x160f; i++) {
219 stv06xx_read_bridge(sd, i, &data);
220
221 info("Read 0x%x from address 0x%x", data, i);
222 }
223
224 for (i = 0x1400; i < 0x160f; i++) {
225 stv06xx_read_bridge(sd, i, &data);
226 buf = data;
227
228 stv06xx_write_bridge(sd, i, 0xff);
229 stv06xx_read_bridge(sd, i, &data);
230 if (data == 0xff)
231 info("Register 0x%x is read/write", i);
232 else if (data != buf)
233 info("Register 0x%x is read/write,"
234 "but only partially", i);
235 else
236 info("Register 0x%x is read-only", i);
237
238 stv06xx_write_bridge(sd, i, buf);
239 }
240}
241
242/* this function is called at probe and resume time */
243static int stv06xx_init(struct gspca_dev *gspca_dev)
244{
245 struct sd *sd = (struct sd *) gspca_dev;
246 int err;
247
248 PDEBUG(D_PROBE, "Initializing camera");
249
250 /* Let the usb init settle for a bit
251 before performing the initialization */
252 msleep(250);
253
254 err = sd->sensor->init(sd);
255
256 if (dump_sensor)
257 sd->sensor->dump(sd);
258
259 return (err < 0) ? err : 0;
260}
261
262/* Start the camera */
263static int stv06xx_start(struct gspca_dev *gspca_dev)
264{
265 struct sd *sd = (struct sd *) gspca_dev;
266 int err;
267
268 /* Prepare the sensor for start */
269 err = sd->sensor->start(sd);
270 if (err < 0)
271 goto out;
272
273 /* Start isochronous streaming */
274 err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 1);
275
276out:
277 if (err < 0)
278 PDEBUG(D_STREAM, "Starting stream failed");
279 else
280 PDEBUG(D_STREAM, "Started streaming");
281
282 return (err < 0) ? err : 0;
283}
284
285static void stv06xx_stopN(struct gspca_dev *gspca_dev)
286{
287 int err;
288 struct sd *sd = (struct sd *) gspca_dev;
289
290 /* stop ISO-streaming */
291 err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 0);
292 if (err < 0)
293 goto out;
294
295 err = sd->sensor->stop(sd);
296 if (err < 0)
297 goto out;
298
299out:
300 if (err < 0)
301 PDEBUG(D_STREAM, "Failed to stop stream");
302 else
303 PDEBUG(D_STREAM, "Stopped streaming");
304}
305
306/*
307 * Analyse an USB packet of the data stream and store it appropriately.
308 * Each packet contains an integral number of chunks. Each chunk has
309 * 2-bytes identification, followed by 2-bytes that describe the chunk
310 * length. Known/guessed chunk identifications are:
311 * 8001/8005/C001/C005 - Begin new frame
312 * 8002/8006/C002/C006 - End frame
313 * 0200/4200 - Contains actual image data, bayer or compressed
314 * 0005 - 11 bytes of unknown data
315 * 0100 - 2 bytes of unknown data
316 * The 0005 and 0100 chunks seem to appear only in compressed stream.
317 */
318static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
319 struct gspca_frame *frame, /* target */
320 __u8 *data, /* isoc packet */
321 int len) /* iso packet length */
322{
323 PDEBUG(D_PACK, "Packet of length %d arrived", len);
324
325 /* A packet may contain several frames
326 loop until the whole packet is reached */
327 while (len) {
328 int id, chunk_len;
329
330 if (len < 4) {
331 PDEBUG(D_PACK, "Packet is smaller than 4 bytes");
332 return;
333 }
334
335 /* Capture the id */
336 id = (data[0] << 8) | data[1];
337
338 /* Capture the chunk length */
339 chunk_len = (data[2] << 8) | data[3];
340 PDEBUG(D_PACK, "Chunk id: %x, length: %d", id, chunk_len);
341
342 data += 4;
343 len -= 4;
344
345 if (len < chunk_len) {
346 PDEBUG(D_ERR, "URB packet length is smaller"
347 " than the specified chunk length");
348 return;
349 }
350
351 switch (id) {
352 case 0x0200:
353 case 0x4200:
354 PDEBUG(D_PACK, "Frame data packet detected");
355
356 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
357 data, chunk_len);
358 break;
359
360 case 0x8001:
361 case 0x8005:
362 case 0xc001:
363 case 0xc005:
364 PDEBUG(D_PACK, "Starting new frame");
365
366 /* Create a new frame, chunk length should be zero */
367 gspca_frame_add(gspca_dev, FIRST_PACKET,
368 frame, data, 0);
369
370 if (chunk_len)
371 PDEBUG(D_ERR, "Chunk length is "
372 "non-zero on a SOF");
373 break;
374
375 case 0x8002:
376 case 0x8006:
377 case 0xc002:
378 PDEBUG(D_PACK, "End of frame detected");
379
380 /* Complete the last frame (if any) */
381 gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
382
383 if (chunk_len)
384 PDEBUG(D_ERR, "Chunk length is "
385 "non-zero on a EOF");
386 break;
387
388 case 0x0005:
389 PDEBUG(D_PACK, "Chunk 0x005 detected");
390 /* Unknown chunk with 11 bytes of data,
391 occurs just before end of each frame
392 in compressed mode */
393 break;
394
395 case 0x0100:
396 PDEBUG(D_PACK, "Chunk 0x0100 detected");
397 /* Unknown chunk with 2 bytes of data,
398 occurs 2-3 times per USB interrupt */
399 break;
400 default:
401 PDEBUG(D_PACK, "Unknown chunk %d detected", id);
402 /* Unknown chunk */
403 }
404 data += chunk_len;
405 len -= chunk_len;
406 }
407}
408
409static int stv06xx_config(struct gspca_dev *gspca_dev,
410 const struct usb_device_id *id);
411
412/* sub-driver description */
413static const struct sd_desc sd_desc = {
414 .name = MODULE_NAME,
415 .config = stv06xx_config,
416 .init = stv06xx_init,
417 .start = stv06xx_start,
418 .stopN = stv06xx_stopN,
419 .pkt_scan = stv06xx_pkt_scan
420};
421
422/* This function is called at probe time */
423static int stv06xx_config(struct gspca_dev *gspca_dev,
424 const struct usb_device_id *id)
425{
426 struct sd *sd = (struct sd *) gspca_dev;
427 struct cam *cam;
428
429 PDEBUG(D_PROBE, "Configuring camera");
430
431 cam = &gspca_dev->cam;
432 cam->epaddr = STV_ISOC_ENDPOINT_ADDR;
433 sd->desc = sd_desc;
434 gspca_dev->sd_desc = &sd->desc;
435
436 if (dump_bridge)
437 stv06xx_dump_bridge(sd);
438
439 sd->sensor = &stv06xx_sensor_vv6410;
440 if (!sd->sensor->probe(sd))
441 return 0;
442
443 sd->sensor = &stv06xx_sensor_hdcs1x00;
444 if (!sd->sensor->probe(sd))
445 return 0;
446
447 sd->sensor = &stv06xx_sensor_hdcs1020;
448 if (!sd->sensor->probe(sd))
449 return 0;
450
451 sd->sensor = &stv06xx_sensor_pb0100;
452 if (!sd->sensor->probe(sd))
453 return 0;
454
455 sd->sensor = NULL;
456 return -ENODEV;
457}
458
459
460
461/* -- module initialisation -- */
462static const __devinitdata struct usb_device_id device_table[] = {
463 {USB_DEVICE(0x046d, 0x0840)}, /* QuickCam Express */
464 {USB_DEVICE(0x046d, 0x0850)}, /* LEGO cam / QuickCam Web */
465 {USB_DEVICE(0x046d, 0x0870)}, /* Dexxa WebCam USB */
466 {}
467};
468MODULE_DEVICE_TABLE(usb, device_table);
469
470/* -- device connect -- */
471static int sd_probe(struct usb_interface *intf,
472 const struct usb_device_id *id)
473{
474 PDEBUG(D_PROBE, "Probing for a stv06xx device");
475 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
476 THIS_MODULE);
477}
478
479static void sd_disconnect(struct usb_interface *intf)
480{
481 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
482 struct sd *sd = (struct sd *) gspca_dev;
483 PDEBUG(D_PROBE, "Disconnecting the stv06xx device");
484
485 if (sd->sensor->disconnect)
486 sd->sensor->disconnect(sd);
487 gspca_disconnect(intf);
488}
489
490static struct usb_driver sd_driver = {
491 .name = MODULE_NAME,
492 .id_table = device_table,
493 .probe = sd_probe,
494 .disconnect = sd_disconnect,
495#ifdef CONFIG_PM
496 .suspend = gspca_suspend,
497 .resume = gspca_resume,
498#endif
499};
500
501/* -- module insert / remove -- */
502static int __init sd_mod_init(void)
503{
504 if (usb_register(&sd_driver) < 0)
505 return -1;
506 PDEBUG(D_PROBE, "registered");
507 return 0;
508}
509static void __exit sd_mod_exit(void)
510{
511 usb_deregister(&sd_driver);
512 PDEBUG(D_PROBE, "deregistered");
513}
514
515module_init(sd_mod_init);
516module_exit(sd_mod_exit);
517
518module_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
519MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
520
521module_param(dump_sensor, bool, S_IRUGO | S_IWUSR);
522MODULE_PARM_DESC(dump_sensor, "Dumps all sensor registers at startup");
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h
new file mode 100644
index 000000000000..1207e7d17f14
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.h
@@ -0,0 +1,107 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#ifndef STV06XX_H_
31#define STV06XX_H_
32
33#include "gspca.h"
34
35#define MODULE_NAME "STV06xx"
36
37#define STV_ISOC_ENDPOINT_ADDR 0x81
38
39#ifndef V4L2_PIX_FMT_SGRBG8
40#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G')
41#endif
42
43#define STV_REG23 0x0423
44
45/* Control registers of the STV0600 ASIC */
46#define STV_I2C_PARTNER 0x1420
47#define STV_I2C_VAL_REG_VAL_PAIRS_MIN1 0x1421
48#define STV_I2C_READ_WRITE_TOGGLE 0x1422
49#define STV_I2C_FLUSH 0x1423
50#define STV_I2C_SUCC_READ_REG_VALS 0x1424
51
52#define STV_ISO_ENABLE 0x1440
53#define STV_SCAN_RATE 0x1443
54#define STV_LED_CTRL 0x1445
55#define STV_STV0600_EMULATION 0x1446
56#define STV_REG00 0x1500
57#define STV_REG01 0x1501
58#define STV_REG02 0x1502
59#define STV_REG03 0x1503
60#define STV_REG04 0x1504
61
62#define STV_ISO_SIZE_L 0x15c1
63#define STV_ISO_SIZE_H 0x15c2
64
65/* Refers to the CIF 352x288 and QCIF 176x144 */
66/* 1: 288 lines, 2: 144 lines */
67#define STV_Y_CTRL 0x15c3
68
69/* 0xa: 352 columns, 0x6: 176 columns */
70#define STV_X_CTRL 0x1680
71
72#define STV06XX_URB_MSG_TIMEOUT 5000
73
74#define I2C_MAX_BYTES 16
75#define I2C_MAX_WORDS 8
76
77#define I2C_BUFFER_LENGTH 0x23
78#define I2C_READ_CMD 3
79#define I2C_WRITE_CMD 1
80
81#define LED_ON 1
82#define LED_OFF 0
83
84/* STV06xx device descriptor */
85struct sd {
86 struct gspca_dev gspca_dev;
87
88 /* A pointer to the currently connected sensor */
89 const struct stv06xx_sensor *sensor;
90
91 /* A pointer to the sd_desc struct */
92 struct sd_desc desc;
93
94 /* Sensor private data */
95 void *sensor_priv;
96};
97
98int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data);
99int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data);
100
101int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len);
102int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len);
103
104int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value);
105int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value);
106
107#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
new file mode 100644
index 000000000000..14335a9e4bb5
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -0,0 +1,535 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 * Copyright (c) 2008 Chia-I Wu
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * P/N 861037: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
24 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
25 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
26 * P/N 861075-0040: Sensor HDCS1000 ASIC
27 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
28 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
29 */
30
31#include "stv06xx_hdcs.h"
32
33enum hdcs_power_state {
34 HDCS_STATE_SLEEP,
35 HDCS_STATE_IDLE,
36 HDCS_STATE_RUN
37};
38
39/* no lock? */
40struct hdcs {
41 enum hdcs_power_state state;
42 int w, h;
43
44 /* visible area of the sensor array */
45 struct {
46 int left, top;
47 int width, height;
48 int border;
49 } array;
50
51 struct {
52 /* Column timing overhead */
53 u8 cto;
54 /* Column processing overhead */
55 u8 cpo;
56 /* Row sample period constant */
57 u16 rs;
58 /* Exposure reset duration */
59 u16 er;
60 } exp;
61
62 int psmp;
63};
64
65static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
66{
67 u8 regs[I2C_MAX_BYTES * 2];
68 int i;
69
70 if (unlikely((len <= 0) || (len >= I2C_MAX_BYTES) ||
71 (reg + len > 0xff)))
72 return -EINVAL;
73
74 for (i = 0; i < len; i++, reg++) {
75 regs[2*i] = reg;
76 regs[2*i+1] = vals[i];
77 }
78
79 return stv06xx_write_sensor_bytes(sd, regs, len);
80}
81
82static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state)
83{
84 struct hdcs *hdcs = sd->sensor_priv;
85 u8 val;
86 int ret;
87
88 if (hdcs->state == state)
89 return 0;
90
91 /* we need to go idle before running or sleeping */
92 if (hdcs->state != HDCS_STATE_IDLE) {
93 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
94 if (ret)
95 return ret;
96 }
97
98 hdcs->state = HDCS_STATE_IDLE;
99
100 if (state == HDCS_STATE_IDLE)
101 return 0;
102
103 switch (state) {
104 case HDCS_STATE_SLEEP:
105 val = HDCS_SLEEP_MODE;
106 break;
107
108 case HDCS_STATE_RUN:
109 val = HDCS_RUN_ENABLE;
110 break;
111
112 default:
113 return -EINVAL;
114 }
115
116 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val);
117 if (ret < 0)
118 hdcs->state = state;
119
120 return ret;
121}
122
123static int hdcs_reset(struct sd *sd)
124{
125 struct hdcs *hdcs = sd->sensor_priv;
126 int err;
127
128 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 1);
129 if (err < 0)
130 return err;
131
132 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
133 if (err < 0)
134 hdcs->state = HDCS_STATE_IDLE;
135
136 return err;
137}
138
139static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
140{
141 struct sd *sd = (struct sd *) gspca_dev;
142 struct hdcs *hdcs = sd->sensor_priv;
143
144 /* Column time period */
145 int ct;
146 /* Column processing period */
147 int cp;
148 /* Row processing period */
149 int rp;
150 int cycles;
151 int err;
152 int rowexp;
153 u16 data[2];
154
155 err = stv06xx_read_sensor(sd, HDCS_ROWEXPL, &data[0]);
156 if (err < 0)
157 return err;
158
159 err = stv06xx_read_sensor(sd, HDCS_ROWEXPH, &data[1]);
160 if (err < 0)
161 return err;
162
163 rowexp = (data[1] << 8) | data[0];
164
165 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
166 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
167 rp = hdcs->exp.rs + cp;
168
169 cycles = rp * rowexp;
170 *val = cycles / HDCS_CLK_FREQ_MHZ;
171 PDEBUG(D_V4L2, "Read exposure %d", *val);
172 return 0;
173}
174
175static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
176{
177 struct sd *sd = (struct sd *) gspca_dev;
178 struct hdcs *hdcs = sd->sensor_priv;
179 int rowexp, srowexp;
180 int max_srowexp;
181 /* Column time period */
182 int ct;
183 /* Column processing period */
184 int cp;
185 /* Row processing period */
186 int rp;
187 /* Minimum number of column timing periods
188 within the column processing period */
189 int mnct;
190 int cycles, err;
191 u8 exp[4];
192
193 cycles = val * HDCS_CLK_FREQ_MHZ;
194
195 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
196 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
197
198 /* the cycles one row takes */
199 rp = hdcs->exp.rs + cp;
200
201 rowexp = cycles / rp;
202
203 /* the remaining cycles */
204 cycles -= rowexp * rp;
205
206 /* calculate sub-row exposure */
207 if (IS_1020(sd)) {
208 /* see HDCS-1020 datasheet 3.5.6.4, p. 63 */
209 srowexp = hdcs->w - (cycles + hdcs->exp.er + 13) / ct;
210
211 mnct = (hdcs->exp.er + 12 + ct - 1) / ct;
212 max_srowexp = hdcs->w - mnct;
213 } else {
214 /* see HDCS-1000 datasheet 3.4.5.5, p. 61 */
215 srowexp = cp - hdcs->exp.er - 6 - cycles;
216
217 mnct = (hdcs->exp.er + 5 + ct - 1) / ct;
218 max_srowexp = cp - mnct * ct - 1;
219 }
220
221 if (srowexp < 0)
222 srowexp = 0;
223 else if (srowexp > max_srowexp)
224 srowexp = max_srowexp;
225
226 if (IS_1020(sd)) {
227 exp[0] = rowexp & 0xff;
228 exp[1] = rowexp >> 8;
229 exp[2] = (srowexp >> 2) & 0xff;
230 /* this clears exposure error flag */
231 exp[3] = 0x1;
232 err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4);
233 } else {
234 exp[0] = rowexp & 0xff;
235 exp[1] = rowexp >> 8;
236 exp[2] = srowexp & 0xff;
237 exp[3] = srowexp >> 8;
238 err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4);
239 if (err < 0)
240 return err;
241
242 /* clear exposure error flag */
243 err = stv06xx_write_sensor(sd,
244 HDCS_STATUS, BIT(4));
245 }
246 PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d",
247 val, rowexp, srowexp);
248 return err;
249}
250
251static int hdcs_set_gains(struct sd *sd, u8 r, u8 g, u8 b)
252{
253 u8 gains[4];
254
255 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
256 if (r > 127)
257 r = 0x80 | (r / 2);
258 if (g > 127)
259 g = 0x80 | (g / 2);
260 if (b > 127)
261 b = 0x80 | (b / 2);
262
263 gains[0] = g;
264 gains[1] = r;
265 gains[2] = b;
266 gains[3] = g;
267
268 return hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
269}
270
271static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
272{
273 struct sd *sd = (struct sd *) gspca_dev;
274 int err;
275 u16 data;
276
277 err = stv06xx_read_sensor(sd, HDCS_ERECPGA, &data);
278
279 /* Bit 7 doubles the gain */
280 if (data & 0x80)
281 *val = (data & 0x7f) * 2;
282 else
283 *val = data;
284
285 PDEBUG(D_V4L2, "Read gain %d", *val);
286 return err;
287}
288
289static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
290{
291 PDEBUG(D_V4L2, "Writing gain %d", val);
292 return hdcs_set_gains((struct sd *) gspca_dev,
293 val & 0xff, val & 0xff, val & 0xff);
294}
295
296static int hdcs_set_size(struct sd *sd,
297 unsigned int width, unsigned int height)
298{
299 struct hdcs *hdcs = sd->sensor_priv;
300 u8 win[4];
301 unsigned int x, y;
302 int err;
303
304 /* must be multiple of 4 */
305 width = (width + 3) & ~0x3;
306 height = (height + 3) & ~0x3;
307
308 if (width > hdcs->array.width)
309 width = hdcs->array.width;
310
311 if (IS_1020(sd)) {
312 /* the borders are also invalid */
313 if (height + 2 * hdcs->array.border + HDCS_1020_BOTTOM_Y_SKIP
314 > hdcs->array.height)
315 height = hdcs->array.height - 2 * hdcs->array.border -
316 HDCS_1020_BOTTOM_Y_SKIP;
317
318 y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2
319 + hdcs->array.top;
320 } else {
321 if (height > hdcs->array.height)
322 height = hdcs->array.height;
323
324 y = hdcs->array.top + (hdcs->array.height - height) / 2;
325 }
326
327 x = hdcs->array.left + (hdcs->array.width - width) / 2;
328
329 win[0] = y / 4;
330 win[1] = x / 4;
331 win[2] = (y + height) / 4 - 1;
332 win[3] = (x + width) / 4 - 1;
333
334 err = hdcs_reg_write_seq(sd, HDCS_FWROW, win, 4);
335 if (err < 0)
336 return err;
337
338 /* Update the current width and height */
339 hdcs->w = width;
340 hdcs->h = height;
341 return err;
342}
343
344static int hdcs_probe_1x00(struct sd *sd)
345{
346 struct hdcs *hdcs;
347 u16 sensor;
348 int ret;
349
350 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
351 if (ret < 0 || sensor != 0x08)
352 return -ENODEV;
353
354 info("HDCS-1000/1100 sensor detected");
355
356 sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes;
357 sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes;
358 sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls;
359 sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls;
360
361 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
362 if (!hdcs)
363 return -ENOMEM;
364
365 hdcs->array.left = 8;
366 hdcs->array.top = 8;
367 hdcs->array.width = HDCS_1X00_DEF_WIDTH;
368 hdcs->array.height = HDCS_1X00_DEF_HEIGHT;
369 hdcs->array.border = 4;
370
371 hdcs->exp.cto = 4;
372 hdcs->exp.cpo = 2;
373 hdcs->exp.rs = 186;
374 hdcs->exp.er = 100;
375
376 /*
377 * Frame rate on HDCS-1000 0x46D:0x840 depends on PSMP:
378 * 4 = doesn't work at all
379 * 5 = 7.8 fps,
380 * 6 = 6.9 fps,
381 * 8 = 6.3 fps,
382 * 10 = 5.5 fps,
383 * 15 = 4.4 fps,
384 * 31 = 2.8 fps
385 *
386 * Frame rate on HDCS-1000 0x46D:0x870 depends on PSMP:
387 * 15 = doesn't work at all
388 * 18 = doesn't work at all
389 * 19 = 7.3 fps
390 * 20 = 7.4 fps
391 * 21 = 7.4 fps
392 * 22 = 7.4 fps
393 * 24 = 6.3 fps
394 * 30 = 5.4 fps
395 */
396 hdcs->psmp = IS_870(sd) ? 20 : 5;
397
398 sd->sensor_priv = hdcs;
399
400 return 0;
401}
402
403static int hdcs_probe_1020(struct sd *sd)
404{
405 struct hdcs *hdcs;
406 u16 sensor;
407 int ret;
408
409 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
410 if (ret < 0 || sensor != 0x10)
411 return -ENODEV;
412
413 info("HDCS-1020 sensor detected");
414
415 sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes;
416 sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes;
417 sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls;
418 sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls;
419
420 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
421 if (!hdcs)
422 return -ENOMEM;
423
424 /*
425 * From Andrey's test image: looks like HDCS-1020 upper-left
426 * visible pixel is at 24,8 (y maybe even smaller?) and lower-right
427 * visible pixel at 375,299 (x maybe even larger?)
428 */
429 hdcs->array.left = 24;
430 hdcs->array.top = 4;
431 hdcs->array.width = HDCS_1020_DEF_WIDTH;
432 hdcs->array.height = 304;
433 hdcs->array.border = 4;
434
435 hdcs->psmp = 6;
436
437 hdcs->exp.cto = 3;
438 hdcs->exp.cpo = 3;
439 hdcs->exp.rs = 155;
440 hdcs->exp.er = 96;
441
442 sd->sensor_priv = hdcs;
443
444 return 0;
445}
446
447static int hdcs_start(struct sd *sd)
448{
449 PDEBUG(D_STREAM, "Starting stream");
450
451 return hdcs_set_state(sd, HDCS_STATE_RUN);
452}
453
454static int hdcs_stop(struct sd *sd)
455{
456 PDEBUG(D_STREAM, "Halting stream");
457
458 return hdcs_set_state(sd, HDCS_STATE_SLEEP);
459}
460
461static void hdcs_disconnect(struct sd *sd)
462{
463 PDEBUG(D_PROBE, "Disconnecting the sensor");
464 kfree(sd->sensor_priv);
465}
466
467static int hdcs_init(struct sd *sd)
468{
469 struct hdcs *hdcs = sd->sensor_priv;
470 int i, err = 0;
471
472 /* Set the STV0602AA in STV0600 emulation mode */
473 if (IS_870(sd))
474 stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1);
475
476 /* Execute the bridge init */
477 for (i = 0; i < ARRAY_SIZE(stv_bridge_init) && !err; i++) {
478 err = stv06xx_write_bridge(sd, stv_bridge_init[i][0],
479 stv_bridge_init[i][1]);
480 }
481 if (err < 0)
482 return err;
483
484 /* sensor soft reset */
485 hdcs_reset(sd);
486
487 /* Execute the sensor init */
488 for (i = 0; i < ARRAY_SIZE(stv_sensor_init) && !err; i++) {
489 err = stv06xx_write_sensor(sd, stv_sensor_init[i][0],
490 stv_sensor_init[i][1]);
491 }
492 if (err < 0)
493 return err;
494
495 /* Enable continous frame capture, bit 2: stop when frame complete */
496 err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3));
497 if (err < 0)
498 return err;
499
500 /* Set PGA sample duration
501 (was 0x7E for IS_870, but caused slow framerate with HDCS-1020) */
502 if (IS_1020(sd))
503 err = stv06xx_write_sensor(sd, HDCS_TCTRL,
504 (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp);
505 else
506 err = stv06xx_write_sensor(sd, HDCS_TCTRL,
507 (HDCS_ADC_START_SIG_DUR << 5) | hdcs->psmp);
508 if (err < 0)
509 return err;
510
511 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN, HDCS_DEFAULT_GAIN,
512 HDCS_DEFAULT_GAIN);
513 if (err < 0)
514 return err;
515
516 err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE);
517 if (err < 0)
518 return err;
519
520 err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
521 return err;
522}
523
524static int hdcs_dump(struct sd *sd)
525{
526 u16 reg, val;
527
528 info("Dumping sensor registers:");
529
530 for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) {
531 stv06xx_read_sensor(sd, reg, &val);
532 info("reg 0x%02x = 0x%02x", reg, val);
533 }
534 return 0;
535}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
new file mode 100644
index 000000000000..9c7279a4cd88
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -0,0 +1,263 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 * Copyright (c) 2008 Chia-I Wu
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * P/N 861037: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
24 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
25 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
26 * P/N 861075-0040: Sensor HDCS1000 ASIC
27 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
28 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
29 */
30
31#ifndef STV06XX_HDCS_H_
32#define STV06XX_HDCS_H_
33
34#include "stv06xx_sensor.h"
35
36#define HDCS_REG_CONFIG(sd) (IS_1020(sd) ? HDCS20_CONFIG : HDCS00_CONFIG)
37#define HDCS_REG_CONTROL(sd) (IS_1020(sd) ? HDCS20_CONTROL : HDCS00_CONTROL)
38
39#define HDCS_1X00_DEF_WIDTH 360
40#define HDCS_1X00_DEF_HEIGHT 296
41
42#define HDCS_1020_DEF_WIDTH 352
43#define HDCS_1020_DEF_HEIGHT 292
44
45#define HDCS_1020_BOTTOM_Y_SKIP 4
46
47#define HDCS_CLK_FREQ_MHZ 25
48
49#define HDCS_ADC_START_SIG_DUR 3
50
51/* LSB bit of I2C or register address signifies write (0) or read (1) */
52/* I2C Registers common for both HDCS-1000/1100 and HDCS-1020 */
53/* Identifications Register */
54#define HDCS_IDENT (0x00 << 1)
55/* Status Register */
56#define HDCS_STATUS (0x01 << 1)
57/* Interrupt Mask Register */
58#define HDCS_IMASK (0x02 << 1)
59/* Pad Control Register */
60#define HDCS_PCTRL (0x03 << 1)
61/* Pad Drive Control Register */
62#define HDCS_PDRV (0x04 << 1)
63/* Interface Control Register */
64#define HDCS_ICTRL (0x05 << 1)
65/* Interface Timing Register */
66#define HDCS_ITMG (0x06 << 1)
67/* Baud Fraction Register */
68#define HDCS_BFRAC (0x07 << 1)
69/* Baud Rate Register */
70#define HDCS_BRATE (0x08 << 1)
71/* ADC Control Register */
72#define HDCS_ADCCTRL (0x09 << 1)
73/* First Window Row Register */
74#define HDCS_FWROW (0x0a << 1)
75/* First Window Column Register */
76#define HDCS_FWCOL (0x0b << 1)
77/* Last Window Row Register */
78#define HDCS_LWROW (0x0c << 1)
79/* Last Window Column Register */
80#define HDCS_LWCOL (0x0d << 1)
81/* Timing Control Register */
82#define HDCS_TCTRL (0x0e << 1)
83/* PGA Gain Register: Even Row, Even Column */
84#define HDCS_ERECPGA (0x0f << 1)
85/* PGA Gain Register: Even Row, Odd Column */
86#define HDCS_EROCPGA (0x10 << 1)
87/* PGA Gain Register: Odd Row, Even Column */
88#define HDCS_ORECPGA (0x11 << 1)
89/* PGA Gain Register: Odd Row, Odd Column */
90#define HDCS_OROCPGA (0x12 << 1)
91/* Row Exposure Low Register */
92#define HDCS_ROWEXPL (0x13 << 1)
93/* Row Exposure High Register */
94#define HDCS_ROWEXPH (0x14 << 1)
95
96/* I2C Registers only for HDCS-1000/1100 */
97/* Sub-Row Exposure Low Register */
98#define HDCS00_SROWEXPL (0x15 << 1)
99/* Sub-Row Exposure High Register */
100#define HDCS00_SROWEXPH (0x16 << 1)
101/* Configuration Register */
102#define HDCS00_CONFIG (0x17 << 1)
103/* Control Register */
104#define HDCS00_CONTROL (0x18 << 1)
105
106/* I2C Registers only for HDCS-1020 */
107/* Sub-Row Exposure Register */
108#define HDCS20_SROWEXP (0x15 << 1)
109/* Error Control Register */
110#define HDCS20_ERROR (0x16 << 1)
111/* Interface Timing 2 Register */
112#define HDCS20_ITMG2 (0x17 << 1)
113/* Interface Control 2 Register */
114#define HDCS20_ICTRL2 (0x18 << 1)
115/* Horizontal Blank Register */
116#define HDCS20_HBLANK (0x19 << 1)
117/* Vertical Blank Register */
118#define HDCS20_VBLANK (0x1a << 1)
119/* Configuration Register */
120#define HDCS20_CONFIG (0x1b << 1)
121/* Control Register */
122#define HDCS20_CONTROL (0x1c << 1)
123
124#define HDCS_RUN_ENABLE (1 << 2)
125#define HDCS_SLEEP_MODE (1 << 1)
126
127#define HDCS_DEFAULT_EXPOSURE 5000
128#define HDCS_DEFAULT_GAIN 128
129
130static int hdcs_probe_1x00(struct sd *sd);
131static int hdcs_probe_1020(struct sd *sd);
132static int hdcs_start(struct sd *sd);
133static int hdcs_init(struct sd *sd);
134static int hdcs_stop(struct sd *sd);
135static int hdcs_dump(struct sd *sd);
136static void hdcs_disconnect(struct sd *sd);
137
138static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
139static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
140static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val);
141static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
142
143const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
144 .name = "HP HDCS-1000/1100",
145 .i2c_flush = 0,
146 .i2c_addr = (0x55 << 1),
147 .i2c_len = 1,
148
149 .init = hdcs_init,
150 .probe = hdcs_probe_1x00,
151 .start = hdcs_start,
152 .stop = hdcs_stop,
153 .disconnect = hdcs_disconnect,
154 .dump = hdcs_dump,
155
156 .nctrls = 2,
157 .ctrls = {
158 {
159 {
160 .id = V4L2_CID_EXPOSURE,
161 .type = V4L2_CTRL_TYPE_INTEGER,
162 .name = "exposure",
163 .minimum = 0x00,
164 .maximum = 0xffff,
165 .step = 0x1,
166 .default_value = HDCS_DEFAULT_EXPOSURE,
167 .flags = V4L2_CTRL_FLAG_SLIDER
168 },
169 .set = hdcs_set_exposure,
170 .get = hdcs_get_exposure
171 },
172 {
173 {
174 .id = V4L2_CID_GAIN,
175 .type = V4L2_CTRL_TYPE_INTEGER,
176 .name = "gain",
177 .minimum = 0x00,
178 .maximum = 0xff,
179 .step = 0x1,
180 .default_value = HDCS_DEFAULT_GAIN,
181 .flags = V4L2_CTRL_FLAG_SLIDER
182 },
183 .set = hdcs_set_gain,
184 .get = hdcs_get_gain
185 }
186 },
187
188 .nmodes = 1,
189 .modes = {
190 {
191 HDCS_1X00_DEF_WIDTH,
192 HDCS_1X00_DEF_HEIGHT,
193 V4L2_PIX_FMT_SBGGR8,
194 V4L2_FIELD_NONE,
195 .sizeimage =
196 HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
197 .bytesperline = HDCS_1X00_DEF_WIDTH,
198 .colorspace = V4L2_COLORSPACE_SRGB,
199 .priv = 1
200 }
201 }
202};
203
204const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
205 .name = "HDCS-1020",
206 .i2c_flush = 0,
207 .i2c_addr = (0x55 << 1),
208 .i2c_len = 1,
209
210 .nctrls = 0,
211 .ctrls = {},
212
213 .init = hdcs_init,
214 .probe = hdcs_probe_1020,
215 .start = hdcs_start,
216 .stop = hdcs_stop,
217 .dump = hdcs_dump,
218
219 .nmodes = 1,
220 .modes = {
221 {
222 HDCS_1020_DEF_WIDTH,
223 HDCS_1020_DEF_HEIGHT,
224 V4L2_PIX_FMT_SBGGR8,
225 V4L2_FIELD_NONE,
226 .sizeimage =
227 HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
228 .bytesperline = HDCS_1020_DEF_WIDTH,
229 .colorspace = V4L2_COLORSPACE_SRGB,
230 .priv = 1
231 }
232 }
233};
234
235static const u16 stv_bridge_init[][2] = {
236 {STV_ISO_ENABLE, 0},
237 {STV_REG23, 0},
238 {STV_REG00, 0x1d},
239 {STV_REG01, 0xb5},
240 {STV_REG02, 0xa8},
241 {STV_REG03, 0x95},
242 {STV_REG04, 0x07},
243
244 {STV_SCAN_RATE, 0x20},
245 {STV_ISO_SIZE_L, 847},
246 {STV_Y_CTRL, 0x01},
247 {STV_X_CTRL, 0x0a}
248};
249
250static const u8 stv_sensor_init[][2] = {
251 /* Clear status (writing 1 will clear the corresponding status bit) */
252 {HDCS_STATUS, BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1)},
253 /* Disable all interrupts */
254 {HDCS_IMASK, 0x00},
255 {HDCS_PCTRL, BIT(6) | BIT(5) | BIT(1) | BIT(0)},
256 {HDCS_PDRV, 0x00},
257 {HDCS_ICTRL, BIT(5)},
258 {HDCS_ITMG, BIT(4) | BIT(1)},
259 /* ADC output resolution to 10 bits */
260 {HDCS_ADCCTRL, 10}
261};
262
263#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
new file mode 100644
index 000000000000..d0a0f8596454
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -0,0 +1,430 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30/*
31 * The spec file for the PB-0100 suggests the following for best quality
32 * images after the sensor has been reset :
33 *
34 * PB_ADCGAINL = R60 = 0x03 (3 dec) : sets low reference of ADC
35 to produce good black level
36 * PB_PREADCTRL = R32 = 0x1400 (5120 dec) : Enables global gain changes
37 through R53
38 * PB_ADCMINGAIN = R52 = 0x10 (16 dec) : Sets the minimum gain for
39 auto-exposure
40 * PB_ADCGLOBALGAIN = R53 = 0x10 (16 dec) : Sets the global gain
41 * PB_EXPGAIN = R14 = 0x11 (17 dec) : Sets the auto-exposure value
42 * PB_UPDATEINT = R23 = 0x02 (2 dec) : Sets the speed on
43 auto-exposure routine
44 * PB_CFILLIN = R5 = 0x0E (14 dec) : Sets the frame rate
45 */
46
47#include "stv06xx_pb0100.h"
48
49static int pb0100_probe(struct sd *sd)
50{
51 u16 sensor;
52 int i, err;
53 s32 *sensor_settings;
54
55 err = stv06xx_read_sensor(sd, PB_IDENT, &sensor);
56
57 if (err < 0)
58 return -ENODEV;
59
60 if ((sensor >> 8) == 0x64) {
61 sensor_settings = kmalloc(
62 stv06xx_sensor_pb0100.nctrls * sizeof(s32),
63 GFP_KERNEL);
64 if (!sensor_settings)
65 return -ENOMEM;
66
67 info("Photobit pb0100 sensor detected");
68
69 sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes;
70 sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes;
71 sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls;
72 sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls;
73 for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++)
74 sensor_settings[i] = stv06xx_sensor_pb0100.
75 ctrls[i].qctrl.default_value;
76 sd->sensor_priv = sensor_settings;
77
78 return 0;
79 }
80
81 return -ENODEV;
82}
83
84static int pb0100_start(struct sd *sd)
85{
86 int err;
87 struct cam *cam = &sd->gspca_dev.cam;
88 s32 *sensor_settings = sd->sensor_priv;
89 u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
90
91 /* Setup sensor window */
92 if (mode & PB0100_CROP_TO_VGA) {
93 stv06xx_write_sensor(sd, PB_RSTART, 30);
94 stv06xx_write_sensor(sd, PB_CSTART, 20);
95 stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1);
96 stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1);
97 } else {
98 stv06xx_write_sensor(sd, PB_RSTART, 8);
99 stv06xx_write_sensor(sd, PB_CSTART, 4);
100 stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1);
101 stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1);
102 }
103
104 if (mode & PB0100_SUBSAMPLE) {
105 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */
106 stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
107
108 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
109 } else {
110 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
111 stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
112 /* larger -> slower */
113 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
114 }
115
116 /* set_gain also sets red and blue balance */
117 pb0100_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
118 pb0100_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
119 pb0100_set_autogain_target(&sd->gspca_dev,
120 sensor_settings[AUTOGAIN_TARGET_IDX]);
121 pb0100_set_autogain(&sd->gspca_dev, sensor_settings[AUTOGAIN_IDX]);
122
123 err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
124 PDEBUG(D_STREAM, "Started stream, status: %d", err);
125
126 return (err < 0) ? err : 0;
127}
128
129static int pb0100_stop(struct sd *sd)
130{
131 int err;
132
133 err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1);
134
135 if (err < 0)
136 goto out;
137
138 /* Set bit 1 to zero */
139 err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
140
141 PDEBUG(D_STREAM, "Halting stream");
142out:
143 return (err < 0) ? err : 0;
144}
145
146/* FIXME: Sort the init commands out and put them into tables,
147 this is only for getting the camera to work */
148/* FIXME: No error handling for now,
149 add this once the init has been converted to proper tables */
150static int pb0100_init(struct sd *sd)
151{
152 stv06xx_write_bridge(sd, STV_REG00, 1);
153 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0);
154
155 /* Reset sensor */
156 stv06xx_write_sensor(sd, PB_RESET, 1);
157 stv06xx_write_sensor(sd, PB_RESET, 0);
158
159 /* Disable chip */
160 stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
161
162 /* Gain stuff...*/
163 stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6));
164 stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12);
165
166 /* Set up auto-exposure */
167 /* ADC VREF_HI new setting for a transition
168 from the Expose1 to the Expose2 setting */
169 stv06xx_write_sensor(sd, PB_R28, 12);
170 /* gain max for autoexposure */
171 stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180);
172 /* gain min for autoexposure */
173 stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12);
174 /* Maximum frame integration time (programmed into R8)
175 allowed for auto-exposure routine */
176 stv06xx_write_sensor(sd, PB_R54, 3);
177 /* Minimum frame integration time (programmed into R8)
178 allowed for auto-exposure routine */
179 stv06xx_write_sensor(sd, PB_R55, 0);
180 stv06xx_write_sensor(sd, PB_UPDATEINT, 1);
181 /* R15 Expose0 (maximum that auto-exposure may use) */
182 stv06xx_write_sensor(sd, PB_R15, 800);
183 /* R17 Expose2 (minimum that auto-exposure may use) */
184 stv06xx_write_sensor(sd, PB_R17, 10);
185
186 stv06xx_write_sensor(sd, PB_EXPGAIN, 0);
187
188 /* 0x14 */
189 stv06xx_write_sensor(sd, PB_VOFFSET, 0);
190 /* 0x0D */
191 stv06xx_write_sensor(sd, PB_ADCGAINH, 11);
192 /* Set black level (important!) */
193 stv06xx_write_sensor(sd, PB_ADCGAINL, 0);
194
195 /* ??? */
196 stv06xx_write_bridge(sd, STV_REG00, 0x11);
197 stv06xx_write_bridge(sd, STV_REG03, 0x45);
198 stv06xx_write_bridge(sd, STV_REG04, 0x07);
199
200 /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */
201 stv06xx_write_bridge(sd, STV_ISO_SIZE_L, 847);
202
203 /* Scan/timing for the sensor */
204 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
205 stv06xx_write_sensor(sd, PB_CFILLIN, 14);
206 stv06xx_write_sensor(sd, PB_VBL, 0);
207 stv06xx_write_sensor(sd, PB_FINTTIME, 0);
208 stv06xx_write_sensor(sd, PB_RINTTIME, 123);
209
210 stv06xx_write_bridge(sd, STV_REG01, 0xc2);
211 stv06xx_write_bridge(sd, STV_REG02, 0xb0);
212 return 0;
213}
214
215static int pb0100_dump(struct sd *sd)
216{
217 return 0;
218}
219
220static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
221{
222 struct sd *sd = (struct sd *) gspca_dev;
223 s32 *sensor_settings = sd->sensor_priv;
224
225 *val = sensor_settings[GAIN_IDX];
226
227 return 0;
228}
229
230static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
231{
232 int err;
233 struct sd *sd = (struct sd *) gspca_dev;
234 s32 *sensor_settings = sd->sensor_priv;
235
236 if (sensor_settings[AUTOGAIN_IDX])
237 return -EBUSY;
238
239 sensor_settings[GAIN_IDX] = val;
240 err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
241 if (!err)
242 err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
243 PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
244
245 if (!err)
246 err = pb0100_set_red_balance(gspca_dev,
247 sensor_settings[RED_BALANCE_IDX]);
248 if (!err)
249 err = pb0100_set_blue_balance(gspca_dev,
250 sensor_settings[BLUE_BALANCE_IDX]);
251
252 return err;
253}
254
255static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
256{
257 struct sd *sd = (struct sd *) gspca_dev;
258 s32 *sensor_settings = sd->sensor_priv;
259
260 *val = sensor_settings[RED_BALANCE_IDX];
261
262 return 0;
263}
264
265static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
266{
267 int err;
268 struct sd *sd = (struct sd *) gspca_dev;
269 s32 *sensor_settings = sd->sensor_priv;
270
271 if (sensor_settings[AUTOGAIN_IDX])
272 return -EBUSY;
273
274 sensor_settings[RED_BALANCE_IDX] = val;
275 val += sensor_settings[GAIN_IDX];
276 if (val < 0)
277 val = 0;
278 else if (val > 255)
279 val = 255;
280
281 err = stv06xx_write_sensor(sd, PB_RGAIN, val);
282 PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err);
283
284 return err;
285}
286
287static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
288{
289 struct sd *sd = (struct sd *) gspca_dev;
290 s32 *sensor_settings = sd->sensor_priv;
291
292 *val = sensor_settings[BLUE_BALANCE_IDX];
293
294 return 0;
295}
296
297static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
298{
299 int err;
300 struct sd *sd = (struct sd *) gspca_dev;
301 s32 *sensor_settings = sd->sensor_priv;
302
303 if (sensor_settings[AUTOGAIN_IDX])
304 return -EBUSY;
305
306 sensor_settings[BLUE_BALANCE_IDX] = val;
307 val += sensor_settings[GAIN_IDX];
308 if (val < 0)
309 val = 0;
310 else if (val > 255)
311 val = 255;
312
313 err = stv06xx_write_sensor(sd, PB_BGAIN, val);
314 PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err);
315
316 return err;
317}
318
319static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
320{
321 struct sd *sd = (struct sd *) gspca_dev;
322 s32 *sensor_settings = sd->sensor_priv;
323
324 *val = sensor_settings[EXPOSURE_IDX];
325
326 return 0;
327}
328
329static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
330{
331 int err;
332 struct sd *sd = (struct sd *) gspca_dev;
333 s32 *sensor_settings = sd->sensor_priv;
334
335 if (sensor_settings[AUTOGAIN_IDX])
336 return -EBUSY;
337
338 sensor_settings[EXPOSURE_IDX] = val;
339 err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
340 PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
341
342 return err;
343}
344
345static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val)
346{
347 struct sd *sd = (struct sd *) gspca_dev;
348 s32 *sensor_settings = sd->sensor_priv;
349
350 *val = sensor_settings[AUTOGAIN_IDX];
351
352 return 0;
353}
354
355static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
356{
357 int err;
358 struct sd *sd = (struct sd *) gspca_dev;
359 s32 *sensor_settings = sd->sensor_priv;
360
361 sensor_settings[AUTOGAIN_IDX] = val;
362 if (sensor_settings[AUTOGAIN_IDX]) {
363 if (sensor_settings[NATURAL_IDX])
364 val = BIT(6)|BIT(4)|BIT(0);
365 else
366 val = BIT(4)|BIT(0);
367 } else
368 val = 0;
369
370 err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
371 PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
372 sensor_settings[AUTOGAIN_IDX], sensor_settings[NATURAL_IDX],
373 err);
374
375 return err;
376}
377
378static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val)
379{
380 struct sd *sd = (struct sd *) gspca_dev;
381 s32 *sensor_settings = sd->sensor_priv;
382
383 *val = sensor_settings[AUTOGAIN_TARGET_IDX];
384
385 return 0;
386}
387
388static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
389{
390 int err, totalpixels, brightpixels, darkpixels;
391 struct sd *sd = (struct sd *) gspca_dev;
392 s32 *sensor_settings = sd->sensor_priv;
393
394 sensor_settings[AUTOGAIN_TARGET_IDX] = val;
395
396 /* Number of pixels counted by the sensor when subsampling the pixels.
397 * Slightly larger than the real value to avoid oscillation */
398 totalpixels = gspca_dev->width * gspca_dev->height;
399 totalpixels = totalpixels/(8*8) + totalpixels/(64*64);
400
401 brightpixels = (totalpixels * val) >> 8;
402 darkpixels = totalpixels - brightpixels;
403 err = stv06xx_write_sensor(sd, PB_R21, brightpixels);
404 if (!err)
405 err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
406
407 PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err);
408
409 return err;
410}
411
412static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val)
413{
414 struct sd *sd = (struct sd *) gspca_dev;
415 s32 *sensor_settings = sd->sensor_priv;
416
417 *val = sensor_settings[NATURAL_IDX];
418
419 return 0;
420}
421
422static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val)
423{
424 struct sd *sd = (struct sd *) gspca_dev;
425 s32 *sensor_settings = sd->sensor_priv;
426
427 sensor_settings[NATURAL_IDX] = val;
428
429 return pb0100_set_autogain(gspca_dev, sensor_settings[AUTOGAIN_IDX]);
430}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
new file mode 100644
index 000000000000..5ea21a1154c4
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
@@ -0,0 +1,275 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#ifndef STV06XX_PB0100_H_
31#define STV06XX_PB0100_H_
32
33#include "stv06xx_sensor.h"
34
35/* mode priv field flags */
36#define PB0100_CROP_TO_VGA 0x01
37#define PB0100_SUBSAMPLE 0x02
38
39/* I2C Registers */
40#define PB_IDENT 0x00 /* Chip Version */
41#define PB_RSTART 0x01 /* Row Window Start */
42#define PB_CSTART 0x02 /* Column Window Start */
43#define PB_RWSIZE 0x03 /* Row Window Size */
44#define PB_CWSIZE 0x04 /* Column Window Size */
45#define PB_CFILLIN 0x05 /* Column Fill-In */
46#define PB_VBL 0x06 /* Vertical Blank Count */
47#define PB_CONTROL 0x07 /* Control Mode */
48#define PB_FINTTIME 0x08 /* Integration Time/Frame Unit Count */
49#define PB_RINTTIME 0x09 /* Integration Time/Row Unit Count */
50#define PB_ROWSPEED 0x0a /* Row Speed Control */
51#define PB_ABORTFRAME 0x0b /* Abort Frame */
52#define PB_R12 0x0c /* Reserved */
53#define PB_RESET 0x0d /* Reset */
54#define PB_EXPGAIN 0x0e /* Exposure Gain Command */
55#define PB_R15 0x0f /* Expose0 */
56#define PB_R16 0x10 /* Expose1 */
57#define PB_R17 0x11 /* Expose2 */
58#define PB_R18 0x12 /* Low0_DAC */
59#define PB_R19 0x13 /* Low1_DAC */
60#define PB_R20 0x14 /* Low2_DAC */
61#define PB_R21 0x15 /* Threshold11 */
62#define PB_R22 0x16 /* Threshold0x */
63#define PB_UPDATEINT 0x17 /* Update Interval */
64#define PB_R24 0x18 /* High_DAC */
65#define PB_R25 0x19 /* Trans0H */
66#define PB_R26 0x1a /* Trans1L */
67#define PB_R27 0x1b /* Trans1H */
68#define PB_R28 0x1c /* Trans2L */
69#define PB_R29 0x1d /* Reserved */
70#define PB_R30 0x1e /* Reserved */
71#define PB_R31 0x1f /* Wait to Read */
72#define PB_PREADCTRL 0x20 /* Pixel Read Control Mode */
73#define PB_R33 0x21 /* IREF_VLN */
74#define PB_R34 0x22 /* IREF_VLP */
75#define PB_R35 0x23 /* IREF_VLN_INTEG */
76#define PB_R36 0x24 /* IREF_MASTER */
77#define PB_R37 0x25 /* IDACP */
78#define PB_R38 0x26 /* IDACN */
79#define PB_R39 0x27 /* DAC_Control_Reg */
80#define PB_R40 0x28 /* VCL */
81#define PB_R41 0x29 /* IREF_VLN_ADCIN */
82#define PB_R42 0x2a /* Reserved */
83#define PB_G1GAIN 0x2b /* Green 1 Gain */
84#define PB_BGAIN 0x2c /* Blue Gain */
85#define PB_RGAIN 0x2d /* Red Gain */
86#define PB_G2GAIN 0x2e /* Green 2 Gain */
87#define PB_R47 0x2f /* Dark Row Address */
88#define PB_R48 0x30 /* Dark Row Options */
89#define PB_R49 0x31 /* Reserved */
90#define PB_R50 0x32 /* Image Test Data */
91#define PB_ADCMAXGAIN 0x33 /* Maximum Gain */
92#define PB_ADCMINGAIN 0x34 /* Minimum Gain */
93#define PB_ADCGLOBALGAIN 0x35 /* Global Gain */
94#define PB_R54 0x36 /* Maximum Frame */
95#define PB_R55 0x37 /* Minimum Frame */
96#define PB_R56 0x38 /* Reserved */
97#define PB_VOFFSET 0x39 /* VOFFSET */
98#define PB_R58 0x3a /* Snap-Shot Sequence Trigger */
99#define PB_ADCGAINH 0x3b /* VREF_HI */
100#define PB_ADCGAINL 0x3c /* VREF_LO */
101#define PB_R61 0x3d /* Reserved */
102#define PB_R62 0x3e /* Reserved */
103#define PB_R63 0x3f /* Reserved */
104#define PB_R64 0x40 /* Red/Blue Gain */
105#define PB_R65 0x41 /* Green 2/Green 1 Gain */
106#define PB_R66 0x42 /* VREF_HI/LO */
107#define PB_R67 0x43 /* Integration Time/Row Unit Count */
108#define PB_R240 0xf0 /* ADC Test */
109#define PB_R241 0xf1 /* Chip Enable */
110#define PB_R242 0xf2 /* Reserved */
111
112static int pb0100_probe(struct sd *sd);
113static int pb0100_start(struct sd *sd);
114static int pb0100_init(struct sd *sd);
115static int pb0100_stop(struct sd *sd);
116static int pb0100_dump(struct sd *sd);
117
118/* V4L2 controls supported by the driver */
119static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
120static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val);
121static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
122static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
123static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
124static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
125static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
126static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
127static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val);
128static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val);
129static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val);
130static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val);
131static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val);
132static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val);
133
134const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
135 .name = "PB-0100",
136 .i2c_flush = 1,
137 .i2c_addr = 0xba,
138 .i2c_len = 2,
139
140 .nctrls = 7,
141 .ctrls = {
142#define GAIN_IDX 0
143 {
144 {
145 .id = V4L2_CID_GAIN,
146 .type = V4L2_CTRL_TYPE_INTEGER,
147 .name = "Gain",
148 .minimum = 0,
149 .maximum = 255,
150 .step = 1,
151 .default_value = 128
152 },
153 .set = pb0100_set_gain,
154 .get = pb0100_get_gain
155 },
156#define RED_BALANCE_IDX 1
157 {
158 {
159 .id = V4L2_CID_RED_BALANCE,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "Red Balance",
162 .minimum = -255,
163 .maximum = 255,
164 .step = 1,
165 .default_value = 0
166 },
167 .set = pb0100_set_red_balance,
168 .get = pb0100_get_red_balance
169 },
170#define BLUE_BALANCE_IDX 2
171 {
172 {
173 .id = V4L2_CID_BLUE_BALANCE,
174 .type = V4L2_CTRL_TYPE_INTEGER,
175 .name = "Blue Balance",
176 .minimum = -255,
177 .maximum = 255,
178 .step = 1,
179 .default_value = 0
180 },
181 .set = pb0100_set_blue_balance,
182 .get = pb0100_get_blue_balance
183 },
184#define EXPOSURE_IDX 3
185 {
186 {
187 .id = V4L2_CID_EXPOSURE,
188 .type = V4L2_CTRL_TYPE_INTEGER,
189 .name = "Exposure",
190 .minimum = 0,
191 .maximum = 511,
192 .step = 1,
193 .default_value = 12
194 },
195 .set = pb0100_set_exposure,
196 .get = pb0100_get_exposure
197 },
198#define AUTOGAIN_IDX 4
199 {
200 {
201 .id = V4L2_CID_AUTOGAIN,
202 .type = V4L2_CTRL_TYPE_BOOLEAN,
203 .name = "Automatic Gain and Exposure",
204 .minimum = 0,
205 .maximum = 1,
206 .step = 1,
207 .default_value = 1
208 },
209 .set = pb0100_set_autogain,
210 .get = pb0100_get_autogain
211 },
212#define AUTOGAIN_TARGET_IDX 5
213 {
214 {
215 .id = V4L2_CTRL_CLASS_USER + 0x1000,
216 .type = V4L2_CTRL_TYPE_INTEGER,
217 .name = "Automatic Gain Target",
218 .minimum = 0,
219 .maximum = 255,
220 .step = 1,
221 .default_value = 128
222 },
223 .set = pb0100_set_autogain_target,
224 .get = pb0100_get_autogain_target
225 },
226#define NATURAL_IDX 6
227 {
228 {
229 .id = V4L2_CTRL_CLASS_USER + 0x1001,
230 .type = V4L2_CTRL_TYPE_BOOLEAN,
231 .name = "Natural Light Source",
232 .minimum = 0,
233 .maximum = 1,
234 .step = 1,
235 .default_value = 1
236 },
237 .set = pb0100_set_natural,
238 .get = pb0100_get_natural
239 },
240 },
241
242 .init = pb0100_init,
243 .probe = pb0100_probe,
244 .start = pb0100_start,
245 .stop = pb0100_stop,
246 .dump = pb0100_dump,
247
248 .nmodes = 2,
249 .modes = {
250/* low res / subsample modes disabled as they are only half res horizontal,
251 halving the vertical resolution does not seem to work */
252 {
253 320,
254 240,
255 V4L2_PIX_FMT_SGRBG8,
256 V4L2_FIELD_NONE,
257 .sizeimage = 320 * 240,
258 .bytesperline = 320,
259 .colorspace = V4L2_COLORSPACE_SRGB,
260 .priv = PB0100_CROP_TO_VGA
261 },
262 {
263 352,
264 288,
265 V4L2_PIX_FMT_SGRBG8,
266 V4L2_FIELD_NONE,
267 .sizeimage = 352 * 288,
268 .bytesperline = 352,
269 .colorspace = V4L2_COLORSPACE_SRGB,
270 .priv = 0
271 },
272 }
273};
274
275#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
new file mode 100644
index 000000000000..c726dacefa1f
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#ifndef STV06XX_SENSOR_H_
31#define STV06XX_SENSOR_H_
32
33#include "stv06xx.h"
34
35#define IS_850(sd) ((sd)->gspca_dev.dev->descriptor.idProduct == 0x850)
36#define IS_870(sd) ((sd)->gspca_dev.dev->descriptor.idProduct == 0x870)
37#define IS_1020(sd) ((sd)->sensor == &stv06xx_sensor_hdcs1020)
38
39extern const struct stv06xx_sensor stv06xx_sensor_vv6410;
40extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00;
41extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
42extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
43
44#define STV06XX_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
45
46struct stv06xx_sensor {
47 /* Defines the name of a sensor */
48 char name[32];
49
50 /* Sensor i2c address */
51 u8 i2c_addr;
52
53 /* Flush value*/
54 u8 i2c_flush;
55
56 /* length of an i2c word */
57 u8 i2c_len;
58
59 /* Probes if the sensor is connected */
60 int (*probe)(struct sd *sd);
61
62 /* Performs a initialization sequence */
63 int (*init)(struct sd *sd);
64
65 /* Executed at device disconnect */
66 void (*disconnect)(struct sd *sd);
67
68 /* Reads a sensor register */
69 int (*read_sensor)(struct sd *sd, const u8 address,
70 u8 *i2c_data, const u8 len);
71
72 /* Writes to a sensor register */
73 int (*write_sensor)(struct sd *sd, const u8 address,
74 u8 *i2c_data, const u8 len);
75
76 /* Instructs the sensor to start streaming */
77 int (*start)(struct sd *sd);
78
79 /* Instructs the sensor to stop streaming */
80 int (*stop)(struct sd *sd);
81
82 /* Instructs the sensor to dump all its contents */
83 int (*dump)(struct sd *sd);
84
85 int nctrls;
86 struct ctrl ctrls[STV06XX_MAX_CTRLS];
87
88 char nmodes;
89 struct v4l2_pix_format modes[];
90};
91
92#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
new file mode 100644
index 000000000000..1ca91f2a6dee
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -0,0 +1,251 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#include "stv06xx_vv6410.h"
31
32static int vv6410_probe(struct sd *sd)
33{
34 u16 data;
35 int err;
36
37 err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data);
38
39 if (err < 0)
40 return -ENODEV;
41
42 if (data == 0x19) {
43 info("vv6410 sensor detected");
44
45 sd->gspca_dev.cam.cam_mode = stv06xx_sensor_vv6410.modes;
46 sd->gspca_dev.cam.nmodes = stv06xx_sensor_vv6410.nmodes;
47 sd->desc.ctrls = stv06xx_sensor_vv6410.ctrls;
48 sd->desc.nctrls = stv06xx_sensor_vv6410.nctrls;
49 return 0;
50 }
51
52 return -ENODEV;
53}
54
55static int vv6410_init(struct sd *sd)
56{
57 int err = 0, i;
58
59 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) {
60 /* if NULL then len contains single value */
61 if (stv_bridge_init[i].data == NULL) {
62 err = stv06xx_write_bridge(sd,
63 stv_bridge_init[i].start,
64 stv_bridge_init[i].len);
65 } else {
66 int j;
67 for (j = 0; j < stv_bridge_init[i].len; j++)
68 err = stv06xx_write_bridge(sd,
69 stv_bridge_init[i].start + j,
70 stv_bridge_init[i].data[j]);
71 }
72 }
73
74 if (err < 0)
75 return err;
76
77 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
78 ARRAY_SIZE(vv6410_sensor_init));
79
80 return (err < 0) ? err : 0;
81}
82
83static int vv6410_start(struct sd *sd)
84{
85 int err;
86 struct cam *cam = &sd->gspca_dev.cam;
87 u32 priv = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
88
89 if (priv & VV6410_CROP_TO_QVGA) {
90 PDEBUG(D_CONF, "Cropping to QVGA");
91 stv06xx_write_sensor(sd, VV6410_XENDH, 320 - 1);
92 stv06xx_write_sensor(sd, VV6410_YENDH, 240 - 1);
93 } else {
94 stv06xx_write_sensor(sd, VV6410_XENDH, 360 - 1);
95 stv06xx_write_sensor(sd, VV6410_YENDH, 294 - 1);
96 }
97
98 if (priv & VV6410_SUBSAMPLE) {
99 PDEBUG(D_CONF, "Enabling subsampling");
100 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02);
101 stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
102
103 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
104 } else {
105 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
106 stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
107
108 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
109 }
110
111 /* Turn on LED */
112 err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_ON);
113 if (err < 0)
114 return err;
115
116 err = stv06xx_write_sensor(sd, VV6410_SETUP0, 0);
117 if (err < 0)
118 return err;
119
120 PDEBUG(D_STREAM, "Starting stream");
121
122 return 0;
123}
124
125static int vv6410_stop(struct sd *sd)
126{
127 int err;
128
129 /* Turn off LED */
130 err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_OFF);
131 if (err < 0)
132 return err;
133
134 err = stv06xx_write_sensor(sd, VV6410_SETUP0, VV6410_LOW_POWER_MODE);
135 if (err < 0)
136 return err;
137
138 PDEBUG(D_STREAM, "Halting stream");
139
140 return (err < 0) ? err : 0;
141}
142
143static int vv6410_dump(struct sd *sd)
144{
145 u8 i;
146 int err = 0;
147
148 info("Dumping all vv6410 sensor registers");
149 for (i = 0; i < 0xff && !err; i++) {
150 u16 data;
151 err = stv06xx_read_sensor(sd, i, &data);
152 info("Register 0x%x contained 0x%x", i, data);
153 }
154 return (err < 0) ? err : 0;
155}
156
157static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
158{
159 int err;
160 u16 i2c_data;
161 struct sd *sd = (struct sd *) gspca_dev;
162
163 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
164
165 *val = (i2c_data & VV6410_HFLIP) ? 1 : 0;
166
167 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
168
169 return (err < 0) ? err : 0;
170}
171
172static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
173{
174 int err;
175 u16 i2c_data;
176 struct sd *sd = (struct sd *) gspca_dev;
177 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
178 if (err < 0)
179 return err;
180
181 if (val)
182 i2c_data |= VV6410_HFLIP;
183 else
184 i2c_data &= ~VV6410_HFLIP;
185
186 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
187 err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
188
189 return (err < 0) ? err : 0;
190}
191
192static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
193{
194 int err;
195 u16 i2c_data;
196 struct sd *sd = (struct sd *) gspca_dev;
197
198 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
199
200 *val = (i2c_data & VV6410_VFLIP) ? 1 : 0;
201
202 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
203
204 return (err < 0) ? err : 0;
205}
206
207static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
208{
209 int err;
210 u16 i2c_data;
211 struct sd *sd = (struct sd *) gspca_dev;
212 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
213 if (err < 0)
214 return err;
215
216 if (val)
217 i2c_data |= VV6410_VFLIP;
218 else
219 i2c_data &= ~VV6410_VFLIP;
220
221 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
222 err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
223
224 return (err < 0) ? err : 0;
225}
226
227static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val)
228{
229 int err;
230 u16 i2c_data;
231 struct sd *sd = (struct sd *) gspca_dev;
232
233 err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data);
234
235 *val = i2c_data & 0xf;
236
237 PDEBUG(D_V4L2, "Read analog gain %d", *val);
238
239 return (err < 0) ? err : 0;
240}
241
242static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
243{
244 int err;
245 struct sd *sd = (struct sd *) gspca_dev;
246
247 PDEBUG(D_V4L2, "Set analog gain to %d", val);
248 err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
249
250 return (err < 0) ? err : 0;
251}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
new file mode 100644
index 000000000000..3ff8c4ea3362
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -0,0 +1,315 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#ifndef STV06XX_VV6410_H_
31#define STV06XX_VV6410_H_
32
33#include "stv06xx_sensor.h"
34
35#define VV6410_COLS 416
36#define VV6410_ROWS 320
37
38/* Status registers */
39/* Chip identification number including revision indicator */
40#define VV6410_DEVICEH 0x00
41#define VV6410_DEVICEL 0x01
42
43/* User can determine whether timed I2C data
44 has been consumed by interrogating flag states */
45#define VV6410_STATUS0 0x02
46
47/* Current line counter value */
48#define VV6410_LINECOUNTH 0x03
49#define VV6410_LINECOUNTL 0x04
50
51/* End x coordinate of image size */
52#define VV6410_XENDH 0x05
53#define VV6410_XENDL 0x06
54
55/* End y coordinate of image size */
56#define VV6410_YENDH 0x07
57#define VV6410_YENDL 0x08
58
59/* This is the average pixel value returned from the
60 dark line offset cancellation algorithm */
61#define VV6410_DARKAVGH 0x09
62#define VV6410_DARKAVGL 0x0a
63
64/* This is the average pixel value returned from the
65 black line offset cancellation algorithm */
66#define VV6410_BLACKAVGH 0x0b
67#define VV6410_BLACKAVGL 0x0c
68
69/* Flags to indicate whether the x or y image coordinates have been clipped */
70#define VV6410_STATUS1 0x0d
71
72/* Setup registers */
73
74/* Low-power/sleep modes & video timing */
75#define VV6410_SETUP0 0x10
76
77/* Various parameters */
78#define VV6410_SETUP1 0x11
79
80/* Contains pixel counter reset value used by external sync */
81#define VV6410_SYNCVALUE 0x12
82
83/* Frame grabbing modes (FST, LST and QCK) */
84#define VV6410_FGMODES 0x14
85
86/* FST and QCK mapping modes. */
87#define VV6410_PINMAPPING 0x15
88
89/* Data resolution */
90#define VV6410_DATAFORMAT 0x16
91
92/* Output coding formats */
93#define VV6410_OPFORMAT 0x17
94
95/* Various mode select bits */
96#define VV6410_MODESELECT 0x18
97
98/* Exposure registers */
99/* Fine exposure. */
100#define VV6410_FINEH 0x20
101#define VV6410_FINEL 0x21
102
103/* Coarse exposure */
104#define VV6410_COARSEH 0x22
105#define VV6410_COARSEL 0x23
106
107/* Analog gain setting */
108#define VV6410_ANALOGGAIN 0x24
109
110/* Clock division */
111#define VV6410_CLKDIV 0x25
112
113/* Dark line offset cancellation value */
114#define VV6410_DARKOFFSETH 0x2c
115#define VV6410_DARKOFFSETL 0x2d
116
117/* Dark line offset cancellation enable */
118#define VV6410_DARKOFFSETSETUP 0x2e
119
120/* Video timing registers */
121/* Line Length (Pixel Clocks) */
122#define VV6410_LINELENGTHH 0x52
123#define VV6410_LINELENGTHL 0x53
124
125/* X-co-ordinate of top left corner of region of interest (x-offset) */
126#define VV6410_XOFFSETH 0x57
127#define VV6410_XOFFSETL 0x58
128
129/* Y-coordinate of top left corner of region of interest (y-offset) */
130#define VV6410_YOFFSETH 0x59
131#define VV6410_YOFFSETL 0x5a
132
133/* Field length (Lines) */
134#define VV6410_FIELDLENGTHH 0x61
135#define VV6410_FIELDLENGTHL 0x62
136
137/* System registers */
138/* Black offset cancellation default value */
139#define VV6410_BLACKOFFSETH 0x70
140#define VV6410_BLACKOFFSETL 0x71
141
142/* Black offset cancellation setup */
143#define VV6410_BLACKOFFSETSETUP 0x72
144
145/* Analog Control Register 0 */
146#define VV6410_CR0 0x75
147
148/* Analog Control Register 1 */
149#define VV6410_CR1 0x76
150
151/* ADC Setup Register */
152#define VV6410_AS0 0x77
153
154/* Analog Test Register */
155#define VV6410_AT0 0x78
156
157/* Audio Amplifier Setup Register */
158#define VV6410_AT1 0x79
159
160#define VV6410_HFLIP (1 << 3)
161#define VV6410_VFLIP (1 << 4)
162
163#define VV6410_LOW_POWER_MODE (1 << 0)
164#define VV6410_SOFT_RESET (1 << 2)
165#define VV6410_PAL_25_FPS (0 << 3)
166
167#define VV6410_CLK_DIV_2 (1 << 1)
168
169#define VV6410_FINE_EXPOSURE 320
170#define VV6410_COARSE_EXPOSURE 192
171#define VV6410_DEFAULT_GAIN 5
172
173#define VV6410_SUBSAMPLE 0x01
174#define VV6410_CROP_TO_QVGA 0x02
175
176static int vv6410_probe(struct sd *sd);
177static int vv6410_start(struct sd *sd);
178static int vv6410_init(struct sd *sd);
179static int vv6410_stop(struct sd *sd);
180static int vv6410_dump(struct sd *sd);
181
182/* V4L2 controls supported by the driver */
183static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
184static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
185static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
186static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
187static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val);
188static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
189
190const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
191 .name = "ST VV6410",
192 .i2c_flush = 5,
193 .i2c_addr = 0x20,
194 .i2c_len = 1,
195 .init = vv6410_init,
196 .probe = vv6410_probe,
197 .start = vv6410_start,
198 .stop = vv6410_stop,
199 .dump = vv6410_dump,
200
201 .nctrls = 3,
202 .ctrls = {
203 {
204 {
205 .id = V4L2_CID_HFLIP,
206 .type = V4L2_CTRL_TYPE_BOOLEAN,
207 .name = "horizontal flip",
208 .minimum = 0,
209 .maximum = 1,
210 .step = 1,
211 .default_value = 0
212 },
213 .set = vv6410_set_hflip,
214 .get = vv6410_get_hflip
215 }, {
216 {
217 .id = V4L2_CID_VFLIP,
218 .type = V4L2_CTRL_TYPE_BOOLEAN,
219 .name = "vertical flip",
220 .minimum = 0,
221 .maximum = 1,
222 .step = 1,
223 .default_value = 0
224 },
225 .set = vv6410_set_vflip,
226 .get = vv6410_get_vflip
227 }, {
228 {
229 .id = V4L2_CID_GAIN,
230 .type = V4L2_CTRL_TYPE_INTEGER,
231 .name = "analog gain",
232 .minimum = 0,
233 .maximum = 15,
234 .step = 1,
235 .default_value = 0
236 },
237 .set = vv6410_set_analog_gain,
238 .get = vv6410_get_analog_gain
239 }
240 },
241
242 .nmodes = 1,
243 .modes = {
244 {
245 356,
246 292,
247 V4L2_PIX_FMT_SGRBG8,
248 V4L2_FIELD_NONE,
249 .sizeimage =
250 356 * 292,
251 .bytesperline = 356,
252 .colorspace = V4L2_COLORSPACE_SRGB,
253 .priv = 0
254 }
255 }
256};
257
258/* If NULL, only single value to write, stored in len */
259struct stv_init {
260 const u8 *data;
261 u16 start;
262 u8 len;
263};
264
265static const u8 x1500[] = { /* 0x1500 - 0x150f */
266 0x0b, 0xa7, 0xb7, 0x00, 0x00
267};
268
269static const u8 x1536[] = { /* 0x1536 - 0x153b */
270 0x02, 0x00, 0x60, 0x01, 0x20, 0x01
271};
272
273static const u8 x15c1[] = { /* 0x15c1 - 0x15c2 */
274 0xff, 0x03 /* Output word 0x03ff = 1023 (ISO size) */
275};
276
277static const struct stv_init stv_bridge_init[] = {
278 /* This reg is written twice. Some kind of reset? */
279 {NULL, 0x1620, 0x80},
280 {NULL, 0x1620, 0x00},
281 {NULL, 0x1423, 0x04},
282 {x1500, 0x1500, ARRAY_SIZE(x1500)},
283 {x1536, 0x1536, ARRAY_SIZE(x1536)},
284 {x15c1, 0x15c1, ARRAY_SIZE(x15c1)}
285};
286
287static const u8 vv6410_sensor_init[][2] = {
288 /* Setup registers */
289 {VV6410_SETUP0, VV6410_SOFT_RESET},
290 {VV6410_SETUP0, VV6410_LOW_POWER_MODE},
291 /* Use shuffled read-out mode */
292 {VV6410_SETUP1, BIT(6)},
293 /* All modes to 1 */
294 {VV6410_FGMODES, BIT(6) | BIT(4) | BIT(2) | BIT(0)},
295 {VV6410_PINMAPPING, 0x00},
296 /* Pre-clock generator divide off */
297 {VV6410_DATAFORMAT, BIT(7) | BIT(0)},
298
299 /* Exposure registers */
300 {VV6410_FINEH, VV6410_FINE_EXPOSURE >> 8},
301 {VV6410_FINEL, VV6410_FINE_EXPOSURE & 0xff},
302 {VV6410_COARSEH, VV6410_COARSE_EXPOSURE >> 8},
303 {VV6410_COARSEL, VV6410_COARSE_EXPOSURE & 0xff},
304 {VV6410_ANALOGGAIN, 0xf0 | VV6410_DEFAULT_GAIN},
305 {VV6410_CLKDIV, VV6410_CLK_DIV_2},
306
307 /* System registers */
308 /* Enable voltage doubler */
309 {VV6410_AS0, BIT(6) | BIT(4) | BIT(3) | BIT(2) | BIT(1)},
310 {VV6410_AT0, 0x00},
311 /* Power up audio, differential */
312 {VV6410_AT1, BIT(4)|BIT(0)},
313};
314
315#endif
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index bd9288665a80..6d904d5e4c74 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -123,7 +123,7 @@ static struct ctrl sd_ctrls[] = {
123 }, 123 },
124}; 124};
125 125
126static struct v4l2_pix_format vga_mode[] = { 126static const struct v4l2_pix_format vga_mode[] = {
127 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 127 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
128 .bytesperline = 320, 128 .bytesperline = 320,
129 .sizeimage = 320 * 240 * 3 / 8 + 590, 129 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -136,7 +136,7 @@ static struct v4l2_pix_format vga_mode[] = {
136 .priv = 1}, 136 .priv = 1},
137}; 137};
138 138
139static struct v4l2_pix_format custom_mode[] = { 139static const struct v4l2_pix_format custom_mode[] = {
140 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 140 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
141 .bytesperline = 320, 141 .bytesperline = 320,
142 .sizeimage = 320 * 240 * 3 / 8 + 590, 142 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -149,7 +149,7 @@ static struct v4l2_pix_format custom_mode[] = {
149 .priv = 1}, 149 .priv = 1},
150}; 150};
151 151
152static struct v4l2_pix_format vga_mode2[] = { 152static const struct v4l2_pix_format vga_mode2[] = {
153 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 153 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
154 .bytesperline = 176, 154 .bytesperline = 176,
155 .sizeimage = 176 * 144 * 3 / 8 + 590, 155 .sizeimage = 176 * 144 * 3 / 8 + 590,
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index eac245d7a756..6ee111a3cbd1 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -233,7 +233,7 @@ static char *effects_control[] = {
233 "Negative", 233 "Negative",
234}; 234};
235 235
236static struct v4l2_pix_format vga_mode_t16[] = { 236static const struct v4l2_pix_format vga_mode_t16[] = {
237 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 237 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
238 .bytesperline = 160, 238 .bytesperline = 160,
239 .sizeimage = 160 * 120 * 4 / 8 + 590, 239 .sizeimage = 160 * 120 * 4 / 8 + 590,
@@ -499,7 +499,7 @@ static void om6802_sensor_init(struct gspca_dev *gspca_dev)
499 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); 499 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
500 msleep(5); 500 msleep(5);
501 i = 4; 501 i = 4;
502 while (--i < 0) { 502 while (--i > 0) {
503 byte = reg_r(gspca_dev, 0x0060); 503 byte = reg_r(gspca_dev, 0x0060);
504 if (!(byte & 0x01)) 504 if (!(byte & 0x01))
505 break; 505 break;
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 968a5911704f..94163cceb28a 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -30,15 +30,10 @@ MODULE_LICENSE("GPL");
30struct sd { 30struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */ 31 struct gspca_dev gspca_dev; /* !! must be the first item */
32 32
33 int buflen; /* current length of tmpbuf */ 33 __u16 brightness;
34 __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */ 34 __u16 contrast;
35 __u8 tmpbuf2[352 * 288]; /* no protection... */
36 35
37 unsigned short brightness; 36 __u8 packet;
38 unsigned short contrast;
39
40 char packet;
41 char synchro;
42}; 37};
43 38
44/* V4L2 controls supported by the driver */ 39/* V4L2 controls supported by the driver */
@@ -78,7 +73,7 @@ static struct ctrl sd_ctrls[] = {
78 }, 73 },
79}; 74};
80 75
81static struct v4l2_pix_format sif_mode[] = { 76static const struct v4l2_pix_format sif_mode[] = {
82 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 77 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
83 .bytesperline = 176, 78 .bytesperline = 176,
84 .sizeimage = 176 * 144, 79 .sizeimage = 176 * 144,
@@ -392,6 +387,8 @@ static void setbrightness(struct gspca_dev *gspca_dev)
392/* -- start the camera -- */ 387/* -- start the camera -- */
393static int sd_start(struct gspca_dev *gspca_dev) 388static int sd_start(struct gspca_dev *gspca_dev)
394{ 389{
390 struct sd *sd = (struct sd *) gspca_dev;
391
395 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); 392 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
396 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); 393 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
397 tv_8532ReadRegisters(gspca_dev); 394 tv_8532ReadRegisters(gspca_dev);
@@ -443,6 +440,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
443 /************************************************/ 440 /************************************************/
444 tv_8532_PollReg(gspca_dev); 441 tv_8532_PollReg(gspca_dev);
445 reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ 442 reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
443
444 gspca_dev->empty_packet = 0; /* check the empty packets */
445 sd->packet = 0; /* ignore the first packets */
446
446 return 0; 447 return 0;
447} 448}
448 449
@@ -451,111 +452,36 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
451 reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); 452 reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
452} 453}
453 454
454static void tv8532_preprocess(struct gspca_dev *gspca_dev)
455{
456 struct sd *sd = (struct sd *) gspca_dev;
457/* we should received a whole frame with header and EOL marker
458 * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2
459 * sequence 2bytes header the Alternate pixels bayer GB 4 bytes
460 * Alternate pixels bayer RG 4 bytes EOL */
461 int width = gspca_dev->width;
462 int height = gspca_dev->height;
463 unsigned char *dst = sd->tmpbuf2;
464 unsigned char *data = sd->tmpbuf;
465 int i;
466
467 /* precompute where is the good bayer line */
468 if (((data[3] + data[width + 7]) >> 1)
469 + (data[4] >> 2)
470 + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1)
471 + (data[3] >> 2)
472 + (data[width + 5] >> 1))
473 data += 3;
474 else
475 data += 2;
476 for (i = 0; i < height / 2; i++) {
477 memcpy(dst, data, width);
478 data += width + 3;
479 dst += width;
480 memcpy(dst, data, width);
481 data += width + 7;
482 dst += width;
483 }
484}
485
486static void sd_pkt_scan(struct gspca_dev *gspca_dev, 455static void sd_pkt_scan(struct gspca_dev *gspca_dev,
487 struct gspca_frame *frame, /* target */ 456 struct gspca_frame *frame, /* target */
488 __u8 *data, /* isoc packet */ 457 __u8 *data, /* isoc packet */
489 int len) /* iso packet length */ 458 int len) /* iso packet length */
490{ 459{
491 struct sd *sd = (struct sd *) gspca_dev; 460 struct sd *sd = (struct sd *) gspca_dev;
492 461 int packet_type0, packet_type1;
493 if (data[0] != 0x80) { 462
494 sd->packet++; 463 packet_type0 = packet_type1 = INTER_PACKET;
495 if (sd->buflen + len > sizeof sd->tmpbuf) { 464 if (gspca_dev->empty_packet) {
496 if (gspca_dev->last_packet_type != DISCARD_PACKET) { 465 gspca_dev->empty_packet = 0;
497 PDEBUG(D_PACK, "buffer overflow"); 466 sd->packet = gspca_dev->height / 2;
498 gspca_dev->last_packet_type = DISCARD_PACKET; 467 packet_type0 = FIRST_PACKET;
499 } 468 } else if (sd->packet == 0)
500 return; 469 return; /* 2 more lines in 352x288 ! */
501 } 470 sd->packet--;
502 memcpy(&sd->tmpbuf[sd->buflen], data, len); 471 if (sd->packet == 0)
503 sd->buflen += len; 472 packet_type1 = LAST_PACKET;
504 return; 473
505 } 474 /* each packet contains:
506 475 * - header 2 bytes
507 /* here we detect 0x80 */ 476 * - RG line
508 /* counter is limited so we need few header for a frame :) */ 477 * - 4 bytes
509 478 * - GB line
510 /* header 0x80 0x80 0x80 0x80 0x80 */ 479 * - 4 bytes
511 /* packet 00 63 127 145 00 */ 480 */
512 /* sof 0 1 1 0 0 */ 481 gspca_frame_add(gspca_dev, packet_type0,
513 482 frame, data + 2, gspca_dev->width);
514 /* update sequence */ 483 gspca_frame_add(gspca_dev, packet_type1,
515 if (sd->packet == 63 || sd->packet == 127) 484 frame, data + gspca_dev->width + 6, gspca_dev->width);
516 sd->synchro = 1;
517
518 /* is there a frame start ? */
519 if (sd->packet >= (gspca_dev->height >> 1) - 1) {
520 PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro,
521 sd->packet);
522 if (!sd->synchro) { /* start of frame */
523 if (gspca_dev->last_packet_type == FIRST_PACKET) {
524 tv8532_preprocess(gspca_dev);
525 frame = gspca_frame_add(gspca_dev,
526 LAST_PACKET,
527 frame, sd->tmpbuf2,
528 gspca_dev->width *
529 gspca_dev->width);
530 }
531 gspca_frame_add(gspca_dev, FIRST_PACKET,
532 frame, data, 0);
533 memcpy(sd->tmpbuf, data, len);
534 sd->buflen = len;
535 sd->packet = 0;
536 return;
537 }
538 if (gspca_dev->last_packet_type != DISCARD_PACKET) {
539 PDEBUG(D_PACK,
540 "Warning wrong TV8532 frame detection %d",
541 sd->packet);
542 gspca_dev->last_packet_type = DISCARD_PACKET;
543 }
544 return;
545 }
546
547 if (!sd->synchro) {
548 /* Drop packet frame corrupt */
549 PDEBUG(D_PACK, "DROP SOF %d packet %d",
550 sd->synchro, sd->packet);
551 sd->packet = 0;
552 gspca_dev->last_packet_type = DISCARD_PACKET;
553 return;
554 }
555 sd->synchro = 1;
556 sd->packet++;
557 memcpy(&sd->tmpbuf[sd->buflen], data, len);
558 sd->buflen += len;
559} 485}
560 486
561static void setcontrast(struct gspca_dev *gspca_dev) 487static void setcontrast(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 17af353ddd1c..0525ea51a6de 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -32,44 +32,68 @@ 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 unsigned char autogain; 35 __u8 hflip;
36 unsigned char lightfreq; 36 __u8 vflip;
37 __u8 lightfreq;
38 __u8 sharpness;
37 39
38 char qindex;
39 char bridge; 40 char bridge;
40#define BRIDGE_VC0321 0 41#define BRIDGE_VC0321 0
41#define BRIDGE_VC0323 1 42#define BRIDGE_VC0323 1
42 char sensor; 43 char sensor;
43#define SENSOR_HV7131R 0 44#define SENSOR_HV7131R 0
44#define SENSOR_MI1320 1 45#define SENSOR_MI0360 1
45#define SENSOR_MI1310_SOC 2 46#define SENSOR_MI1320 2
46#define SENSOR_OV7660 3 47#define SENSOR_MI1310_SOC 3
47#define SENSOR_OV7670 4 48#define SENSOR_OV7660 4
48#define SENSOR_PO3130NC 5 49#define SENSOR_OV7670 5
50#define SENSOR_PO1200 6
51#define SENSOR_PO3130NC 7
49}; 52};
50 53
51/* V4L2 controls supported by the driver */ 54/* V4L2 controls supported by the driver */
52static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 55static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 56static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
57static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
58static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 59static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 60static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
61static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
62static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
56 63
57static struct ctrl sd_ctrls[] = { 64static struct ctrl sd_ctrls[] = {
65/* next 2 controls work with ov7660 and ov7670 only */
66#define HFLIP_IDX 0
58 { 67 {
59 { 68 {
60 .id = V4L2_CID_AUTOGAIN, 69 .id = V4L2_CID_HFLIP,
61 .type = V4L2_CTRL_TYPE_BOOLEAN, 70 .type = V4L2_CTRL_TYPE_BOOLEAN,
62 .name = "Auto Gain", 71 .name = "Mirror",
63 .minimum = 0, 72 .minimum = 0,
64 .maximum = 1, 73 .maximum = 1,
65 .step = 1, 74 .step = 1,
66#define AUTOGAIN_DEF 1 75#define HFLIP_DEF 0
67 .default_value = AUTOGAIN_DEF, 76 .default_value = HFLIP_DEF,
68 }, 77 },
69 .set = sd_setautogain, 78 .set = sd_sethflip,
70 .get = sd_getautogain, 79 .get = sd_gethflip,
71 }, 80 },
72#define LIGHTFREQ_IDX 1 81#define VFLIP_IDX 1
82 {
83 {
84 .id = V4L2_CID_VFLIP,
85 .type = V4L2_CTRL_TYPE_BOOLEAN,
86 .name = "Vflip",
87 .minimum = 0,
88 .maximum = 1,
89 .step = 1,
90#define VFLIP_DEF 0
91 .default_value = VFLIP_DEF,
92 },
93 .set = sd_setvflip,
94 .get = sd_getvflip,
95 },
96#define LIGHTFREQ_IDX 2
73 { 97 {
74 { 98 {
75 .id = V4L2_CID_POWER_LINE_FREQUENCY, 99 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -84,9 +108,25 @@ static struct ctrl sd_ctrls[] = {
84 .set = sd_setfreq, 108 .set = sd_setfreq,
85 .get = sd_getfreq, 109 .get = sd_getfreq,
86 }, 110 },
111/* po1200 only */
112#define SHARPNESS_IDX 3
113 {
114 {
115 .id = V4L2_CID_SHARPNESS,
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 .name = "Sharpness",
118 .minimum = 0,
119 .maximum = 2,
120 .step = 1,
121#define SHARPNESS_DEF 1
122 .default_value = SHARPNESS_DEF,
123 },
124 .set = sd_setsharpness,
125 .get = sd_getsharpness,
126 },
87}; 127};
88 128
89static struct v4l2_pix_format vc0321_mode[] = { 129static const struct v4l2_pix_format vc0321_mode[] = {
90 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 130 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
91 .bytesperline = 320, 131 .bytesperline = 320,
92 .sizeimage = 320 * 240 * 2, 132 .sizeimage = 320 * 240 * 2,
@@ -98,7 +138,7 @@ static struct v4l2_pix_format vc0321_mode[] = {
98 .colorspace = V4L2_COLORSPACE_SRGB, 138 .colorspace = V4L2_COLORSPACE_SRGB,
99 .priv = 0}, 139 .priv = 0},
100}; 140};
101static struct v4l2_pix_format vc0323_mode[] = { 141static const struct v4l2_pix_format vc0323_mode[] = {
102 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 142 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
103 .bytesperline = 320, 143 .bytesperline = 320,
104 .sizeimage = 320 * 240 * 3 / 8 + 590, 144 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -111,6 +151,252 @@ static struct v4l2_pix_format vc0323_mode[] = {
111 .priv = 0}, 151 .priv = 0},
112}; 152};
113 153
154static const struct v4l2_pix_format svga_mode[] = {
155 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
156 .bytesperline = 800,
157 .sizeimage = 800 * 600 * 1 / 4 + 590,
158 .colorspace = V4L2_COLORSPACE_JPEG,
159 .priv = 0},
160};
161
162/* OV7660/7670 registers */
163#define OV7660_REG_MVFP 0x1e
164#define OV7660_MVFP_MIRROR 0x20
165#define OV7660_MVFP_VFLIP 0x10
166
167static const __u8 mi0360_matrix[9] = {
168 0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50
169};
170
171static const __u8 mi0360_initVGA_JPG[][4] = {
172 {0xb0, 0x03, 0x19, 0xcc},
173 {0xb0, 0x04, 0x02, 0xcc},
174 {0xb3, 0x00, 0x24, 0xcc},
175 {0xb3, 0x00, 0x25, 0xcc},
176 {0xb3, 0x08, 0x01, 0xcc},
177 {0xb3, 0x09, 0x0c, 0xcc},
178 {0xb3, 0x05, 0x01, 0xcc},
179 {0xb3, 0x06, 0x03, 0xcc},
180 {0xb3, 0x03, 0x0a, 0xcc},
181 {0xb3, 0x20, 0x00, 0xcc},
182 {0xb3, 0x21, 0x00, 0xcc},
183 {0xb3, 0x22, 0x01, 0xcc},
184 {0xb3, 0x23, 0xe0, 0xcc},
185 {0xb3, 0x04, 0x05, 0xcc},
186 {0xb3, 0x14, 0x00, 0xcc},
187 {0xb3, 0x15, 0x00, 0xcc},
188 {0xb3, 0x16, 0x02, 0xcc},
189 {0xb3, 0x17, 0x7f, 0xcc},
190 {0xb3, 0x35, 0xdd, 0xcc},
191 {0xb3, 0x34, 0x02, 0xcc},
192 {0xb3, 0x00, 0x25, 0xcc},
193 {0xbc, 0x00, 0x71, 0xcc},
194 {0xb8, 0x00, 0x13, 0xcc},
195 {0xb8, 0x27, 0x20, 0xcc},
196 {0xb8, 0x2c, 0x50, 0xcc},
197 {0xb8, 0x2d, 0xf8, 0xcc},
198 {0xb8, 0x2e, 0xf8, 0xcc},
199 {0xb8, 0x2f, 0xf8, 0xcc},
200 {0xb8, 0x30, 0x50, 0xcc},
201 {0xb8, 0x31, 0xf8, 0xcc},
202 {0xb8, 0x32, 0xf8, 0xcc},
203 {0xb8, 0x33, 0xf8, 0xcc},
204 {0xb8, 0x34, 0x50, 0xcc},
205 {0xb8, 0x35, 0x00, 0xcc},
206 {0xb8, 0x36, 0x00, 0xcc},
207 {0xb8, 0x37, 0x00, 0xcc},
208 {0xb8, 0x01, 0x79, 0xcc},
209 {0xb8, 0x08, 0xe0, 0xcc},
210 {0xb3, 0x01, 0x41, 0xcc},
211 {0xb8, 0x01, 0x79, 0xcc},
212 {0xb8, 0x14, 0x18, 0xcc},
213 {0xb8, 0xb2, 0x0a, 0xcc},
214 {0xb8, 0xb4, 0x0a, 0xcc},
215 {0xb8, 0xb5, 0x0a, 0xcc},
216 {0xb8, 0xfe, 0x00, 0xcc},
217 {0xb8, 0xff, 0x28, 0xcc},
218 {0xb9, 0x00, 0x28, 0xcc},
219 {0xb9, 0x01, 0x28, 0xcc},
220 {0xb9, 0x02, 0x28, 0xcc},
221 {0xb9, 0x03, 0x00, 0xcc},
222 {0xb9, 0x04, 0x00, 0xcc},
223 {0xb9, 0x05, 0x3c, 0xcc},
224 {0xb9, 0x06, 0x3c, 0xcc},
225 {0xb9, 0x07, 0x3c, 0xcc},
226 {0xb9, 0x08, 0x3c, 0xcc},
227 {0xb8, 0x8e, 0x00, 0xcc},
228 {0xb8, 0x8f, 0xff, 0xcc},
229 {0xb8, 0x81, 0x09, 0xcc},
230 {0x31, 0x00, 0x00, 0xbb},
231 {0x09, 0x01, 0xc7, 0xbb},
232 {0x34, 0x01, 0x00, 0xbb},
233 {0x2b, 0x00, 0x28, 0xbb},
234 {0x2c, 0x00, 0x30, 0xbb},
235 {0x2d, 0x00, 0x30, 0xbb},
236 {0x2e, 0x00, 0x28, 0xbb},
237 {0x62, 0x04, 0x11, 0xbb},
238 {0x03, 0x01, 0xe0, 0xbb},
239 {0x2c, 0x00, 0x2c, 0xbb},
240 {0x20, 0xd0, 0x00, 0xbb},
241 {0x01, 0x00, 0x08, 0xbb},
242 {0x06, 0x00, 0x10, 0xbb},
243 {0x05, 0x00, 0x20, 0xbb},
244 {0x20, 0x00, 0x00, 0xbb},
245 {0xb6, 0x00, 0x00, 0xcc},
246 {0xb6, 0x03, 0x02, 0xcc},
247 {0xb6, 0x02, 0x80, 0xcc},
248 {0xb6, 0x05, 0x01, 0xcc},
249 {0xb6, 0x04, 0xe0, 0xcc},
250 {0xb6, 0x12, 0x78, 0xcc},
251 {0xb6, 0x18, 0x02, 0xcc},
252 {0xb6, 0x17, 0x58, 0xcc},
253 {0xb6, 0x16, 0x00, 0xcc},
254 {0xb6, 0x22, 0x12, 0xcc},
255 {0xb6, 0x23, 0x0b, 0xcc},
256 {0xb3, 0x02, 0x02, 0xcc},
257 {0xbf, 0xc0, 0x39, 0xcc},
258 {0xbf, 0xc1, 0x04, 0xcc},
259 {0xbf, 0xcc, 0x10, 0xcc},
260 {0xb9, 0x12, 0x00, 0xcc},
261 {0xb9, 0x13, 0x0a, 0xcc},
262 {0xb9, 0x14, 0x0a, 0xcc},
263 {0xb9, 0x15, 0x0a, 0xcc},
264 {0xb9, 0x16, 0x0a, 0xcc},
265 {0xb9, 0x18, 0x00, 0xcc},
266 {0xb9, 0x19, 0x0f, 0xcc},
267 {0xb9, 0x1a, 0x0f, 0xcc},
268 {0xb9, 0x1b, 0x0f, 0xcc},
269 {0xb9, 0x1c, 0x0f, 0xcc},
270 {0xb8, 0x8e, 0x00, 0xcc},
271 {0xb8, 0x8f, 0xff, 0xcc},
272 {0xb6, 0x12, 0xf8, 0xcc},
273 {0xb8, 0x0c, 0x20, 0xcc},
274 {0xb8, 0x0d, 0x70, 0xcc},
275 {0xb6, 0x13, 0x13, 0xcc},
276 {0x35, 0x00, 0x60, 0xbb},
277 {0xb3, 0x5c, 0x01, 0xcc},
278 {}
279};
280static const __u8 mi0360_initQVGA_JPG[][4] = {
281 {0xb0, 0x03, 0x19, 0xcc},
282 {0xb0, 0x04, 0x02, 0xcc},
283 {0xb3, 0x00, 0x24, 0xcc},
284 {0xb3, 0x00, 0x25, 0xcc},
285 {0xb3, 0x08, 0x01, 0xcc},
286 {0xb3, 0x09, 0x0c, 0xcc},
287 {0xb3, 0x05, 0x01, 0xcc},
288 {0xb3, 0x06, 0x03, 0xcc},
289 {0xb3, 0x03, 0x0a, 0xcc},
290 {0xb3, 0x20, 0x00, 0xcc},
291 {0xb3, 0x21, 0x00, 0xcc},
292 {0xb3, 0x22, 0x01, 0xcc},
293 {0xb3, 0x23, 0xe0, 0xcc},
294 {0xb3, 0x04, 0x05, 0xcc},
295 {0xb3, 0x14, 0x00, 0xcc},
296 {0xb3, 0x15, 0x00, 0xcc},
297 {0xb3, 0x16, 0x02, 0xcc},
298 {0xb3, 0x17, 0x7f, 0xcc},
299 {0xb3, 0x35, 0xdd, 0xcc},
300 {0xb3, 0x34, 0x02, 0xcc},
301 {0xb3, 0x00, 0x25, 0xcc},
302 {0xbc, 0x00, 0xd1, 0xcc},
303 {0xb8, 0x00, 0x13, 0xcc},
304 {0xb8, 0x27, 0x20, 0xcc},
305 {0xb8, 0x2c, 0x50, 0xcc},
306 {0xb8, 0x2d, 0xf8, 0xcc},
307 {0xb8, 0x2e, 0xf8, 0xcc},
308 {0xb8, 0x2f, 0xf8, 0xcc},
309 {0xb8, 0x30, 0x50, 0xcc},
310 {0xb8, 0x31, 0xf8, 0xcc},
311 {0xb8, 0x32, 0xf8, 0xcc},
312 {0xb8, 0x33, 0xf8, 0xcc},
313 {0xb8, 0x34, 0x50, 0xcc},
314 {0xb8, 0x35, 0x00, 0xcc},
315 {0xb8, 0x36, 0x00, 0xcc},
316 {0xb8, 0x37, 0x00, 0xcc},
317 {0xb8, 0x01, 0x79, 0xcc},
318 {0xb8, 0x08, 0xe0, 0xcc},
319 {0xb3, 0x01, 0x41, 0xcc},
320 {0xb8, 0x01, 0x79, 0xcc},
321 {0xb8, 0x14, 0x18, 0xcc},
322 {0xb8, 0xb2, 0x0a, 0xcc},
323 {0xb8, 0xb4, 0x0a, 0xcc},
324 {0xb8, 0xb5, 0x0a, 0xcc},
325 {0xb8, 0xfe, 0x00, 0xcc},
326 {0xb8, 0xff, 0x28, 0xcc},
327 {0xb9, 0x00, 0x28, 0xcc},
328 {0xb9, 0x01, 0x28, 0xcc},
329 {0xb9, 0x02, 0x28, 0xcc},
330 {0xb9, 0x03, 0x00, 0xcc},
331 {0xb9, 0x04, 0x00, 0xcc},
332 {0xb9, 0x05, 0x3c, 0xcc},
333 {0xb9, 0x06, 0x3c, 0xcc},
334 {0xb9, 0x07, 0x3c, 0xcc},
335 {0xb9, 0x08, 0x3c, 0xcc},
336 {0xb8, 0x8e, 0x00, 0xcc},
337 {0xb8, 0x8f, 0xff, 0xcc},
338 {0xb8, 0x81, 0x09, 0xcc},
339 {0x31, 0x00, 0x00, 0xbb},
340 {0x09, 0x01, 0xc7, 0xbb},
341 {0x34, 0x01, 0x00, 0xbb},
342 {0x2b, 0x00, 0x28, 0xbb},
343 {0x2c, 0x00, 0x30, 0xbb},
344 {0x2d, 0x00, 0x30, 0xbb},
345 {0x2e, 0x00, 0x28, 0xbb},
346 {0x62, 0x04, 0x11, 0xbb},
347 {0x03, 0x01, 0xe0, 0xbb},
348 {0x2c, 0x00, 0x2c, 0xbb},
349 {0x20, 0xd0, 0x00, 0xbb},
350 {0x01, 0x00, 0x08, 0xbb},
351 {0x06, 0x00, 0x10, 0xbb},
352 {0x05, 0x00, 0x20, 0xbb},
353 {0x20, 0x00, 0x00, 0xbb},
354 {0xb6, 0x00, 0x00, 0xcc},
355 {0xb6, 0x03, 0x01, 0xcc},
356 {0xb6, 0x02, 0x40, 0xcc},
357 {0xb6, 0x05, 0x00, 0xcc},
358 {0xb6, 0x04, 0xf0, 0xcc},
359 {0xb6, 0x12, 0x78, 0xcc},
360 {0xb6, 0x18, 0x00, 0xcc},
361 {0xb6, 0x17, 0x96, 0xcc},
362 {0xb6, 0x16, 0x00, 0xcc},
363 {0xb6, 0x22, 0x12, 0xcc},
364 {0xb6, 0x23, 0x0b, 0xcc},
365 {0xb3, 0x02, 0x02, 0xcc},
366 {0xbf, 0xc0, 0x39, 0xcc},
367 {0xbf, 0xc1, 0x04, 0xcc},
368 {0xbf, 0xcc, 0x10, 0xcc},
369 {0xb9, 0x12, 0x00, 0xcc},
370 {0xb9, 0x13, 0x0a, 0xcc},
371 {0xb9, 0x14, 0x0a, 0xcc},
372 {0xb9, 0x15, 0x0a, 0xcc},
373 {0xb9, 0x16, 0x0a, 0xcc},
374 {0xb9, 0x18, 0x00, 0xcc},
375 {0xb9, 0x19, 0x0f, 0xcc},
376 {0xb9, 0x1a, 0x0f, 0xcc},
377 {0xb9, 0x1b, 0x0f, 0xcc},
378 {0xb9, 0x1c, 0x0f, 0xcc},
379 {0xb8, 0x8e, 0x00, 0xcc},
380 {0xb8, 0x8f, 0xff, 0xcc},
381 {0xb6, 0x12, 0xf8, 0xcc},
382 {0xb6, 0x13, 0x13, 0xcc},
383 {0xbc, 0x02, 0x18, 0xcc},
384 {0xbc, 0x03, 0x50, 0xcc},
385 {0xbc, 0x04, 0x18, 0xcc},
386 {0xbc, 0x05, 0x00, 0xcc},
387 {0xbc, 0x06, 0x00, 0xcc},
388 {0xbc, 0x08, 0x30, 0xcc},
389 {0xbc, 0x09, 0x40, 0xcc},
390 {0xbc, 0x0a, 0x10, 0xcc},
391 {0xb8, 0x0c, 0x20, 0xcc},
392 {0xb8, 0x0d, 0x70, 0xcc},
393 {0xbc, 0x0b, 0x00, 0xcc},
394 {0xbc, 0x0c, 0x00, 0xcc},
395 {0x35, 0x00, 0xef, 0xbb},
396 {0xb3, 0x5c, 0x01, 0xcc},
397 {}
398};
399
114static const __u8 mi1310_socinitVGA_JPG[][4] = { 400static const __u8 mi1310_socinitVGA_JPG[][4] = {
115 {0xb0, 0x03, 0x19, 0xcc}, 401 {0xb0, 0x03, 0x19, 0xcc},
116 {0xb0, 0x04, 0x02, 0xcc}, 402 {0xb0, 0x04, 0x02, 0xcc},
@@ -823,7 +1109,7 @@ static const __u8 ov7660_initVGA_data[][4] = {
823 {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, 1109 {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa},
824 {0x00, 0x12, 0x80, 0xaa}, 1110 {0x00, 0x12, 0x80, 0xaa},
825 {0x00, 0x12, 0x05, 0xaa}, 1111 {0x00, 0x12, 0x05, 0xaa},
826 {0x00, 0x1e, 0x01, 0xaa}, 1112 {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */
827 {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ 1113 {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */
828 {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ 1114 {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */
829 {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, 1115 {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa},
@@ -877,7 +1163,7 @@ static const __u8 ov7660_initQVGA_data[][4] = {
877 {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc}, 1163 {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc},
878 {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, 1164 {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa},
879 {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa}, 1165 {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa},
880 {0x00, 0x1e, 0x01, 0xaa}, 1166 {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */
881 {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ 1167 {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */
882 {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ 1168 {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */
883 {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, 1169 {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa},
@@ -983,7 +1269,8 @@ static const __u8 ov7670_initVGA_JPG[][4] = {
983 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 1269 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa},
984 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, 1270 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa},
985 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, 1271 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa},
986 {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, 1272 {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */
1273 {0x00, 0x21, 0x02, 0xaa},
987 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, 1274 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa},
988 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, 1275 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa},
989 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, 1276 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa},
@@ -1048,7 +1335,8 @@ static const __u8 ov7670_initVGA_JPG[][4] = {
1048 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, 1335 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa},
1049 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, 1336 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa},
1050 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, 1337 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa},
1051 {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 1338 {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */
1339 {0x00, 0xaa, 0x14, 0xaa},
1052 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, 1340 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa},
1053 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, 1341 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa},
1054 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, 1342 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa},
@@ -1110,7 +1398,8 @@ static const __u8 ov7670_initQVGA_JPG[][4] = {
1110 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 1398 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa},
1111 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, 1399 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa},
1112 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, 1400 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa},
1113 {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, 1401 {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */
1402 {0x00, 0x21, 0x02, 0xaa},
1114 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, 1403 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa},
1115 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, 1404 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa},
1116 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, 1405 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa},
@@ -1175,7 +1464,8 @@ static const __u8 ov7670_initQVGA_JPG[][4] = {
1175 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, 1464 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa},
1176 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, 1465 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa},
1177 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, 1466 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa},
1178 {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 1467 {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */
1468 {0x00, 0xaa, 0x14, 0xaa},
1179 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, 1469 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa},
1180 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, 1470 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa},
1181 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, 1471 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa},
@@ -1204,6 +1494,275 @@ static const __u8 ov7670_initQVGA_JPG[][4] = {
1204 {}, 1494 {},
1205}; 1495};
1206 1496
1497/* PO1200 - values from usbvm326.inf and ms-win trace */
1498static const __u8 po1200_gamma[17] = {
1499 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
1500 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
1501};
1502static const __u8 po1200_matrix[9] = {
1503 0x60, 0xf9, 0xe5, 0xe7, 0x50, 0x05, 0xf3, 0xe6, 0x5e
1504};
1505static const __u8 po1200_initVGA_data[][4] = {
1506 {0xb0, 0x03, 0x19, 0xcc}, /* reset? */
1507 {0xb0, 0x03, 0x19, 0xcc},
1508/* {0x00, 0x00, 0x33, 0xdd}, */
1509 {0xb0, 0x04, 0x02, 0xcc},
1510 {0xb0, 0x02, 0x02, 0xcc},
1511 {0xb3, 0x5d, 0x00, 0xcc},
1512 {0xb3, 0x01, 0x01, 0xcc},
1513 {0xb3, 0x00, 0x64, 0xcc},
1514 {0xb3, 0x00, 0x65, 0xcc},
1515 {0xb3, 0x05, 0x01, 0xcc},
1516 {0xb3, 0x06, 0x01, 0xcc},
1517 {0xb3, 0x5c, 0x01, 0xcc},
1518 {0xb3, 0x08, 0x01, 0xcc},
1519 {0xb3, 0x09, 0x0c, 0xcc},
1520 {0xb3, 0x00, 0x67, 0xcc},
1521 {0xb3, 0x02, 0xb2, 0xcc},
1522 {0xb3, 0x03, 0x18, 0xcc},
1523 {0xb3, 0x04, 0x15, 0xcc},
1524 {0xb3, 0x20, 0x00, 0xcc},
1525 {0xb3, 0x21, 0x00, 0xcc},
1526 {0xb3, 0x22, 0x02, 0xcc},
1527 {0xb3, 0x23, 0x58, 0xcc},
1528 {0xb3, 0x14, 0x00, 0xcc},
1529 {0xb3, 0x15, 0x00, 0xcc},
1530 {0xb3, 0x16, 0x03, 0xcc},
1531 {0xb3, 0x17, 0x1f, 0xcc},
1532 {0xbc, 0x00, 0x71, 0xcc},
1533 {0xbc, 0x01, 0x01, 0xcc},
1534 {0xb0, 0x54, 0x13, 0xcc},
1535 {0xb3, 0x00, 0x67, 0xcc},
1536 {0xb3, 0x34, 0x01, 0xcc},
1537 {0xb3, 0x35, 0xdc, 0xcc},
1538 {0x00, 0x03, 0x00, 0xaa},
1539 {0x00, 0x12, 0x05, 0xaa},
1540 {0x00, 0x13, 0x02, 0xaa},
1541 {0x00, 0x1e, 0xc6, 0xaa}, /* h/v flip */
1542 {0x00, 0x21, 0x00, 0xaa},
1543 {0x00, 0x25, 0x02, 0xaa},
1544 {0x00, 0x3c, 0x4f, 0xaa},
1545 {0x00, 0x3f, 0xe0, 0xaa},
1546 {0x00, 0x42, 0xff, 0xaa},
1547 {0x00, 0x45, 0x34, 0xaa},
1548 {0x00, 0x55, 0xfe, 0xaa},
1549 {0x00, 0x59, 0xd3, 0xaa},
1550 {0x00, 0x5e, 0x04, 0xaa},
1551 {0x00, 0x61, 0xb8, 0xaa}, /* sharpness */
1552 {0x00, 0x62, 0x02, 0xaa},
1553 {0x00, 0xa7, 0x31, 0xaa},
1554 {0x00, 0xa9, 0x66, 0xaa},
1555 {0x00, 0xb0, 0x00, 0xaa},
1556 {0x00, 0xb1, 0x00, 0xaa},
1557 {0x00, 0xb3, 0x11, 0xaa},
1558 {0x00, 0xb6, 0x26, 0xaa},
1559 {0x00, 0xb7, 0x20, 0xaa},
1560 {0x00, 0xba, 0x04, 0xaa},
1561 {0x00, 0x88, 0x42, 0xaa},
1562 {0x00, 0x89, 0x9a, 0xaa},
1563 {0x00, 0x8a, 0x88, 0xaa},
1564 {0x00, 0x8b, 0x8e, 0xaa},
1565 {0x00, 0x8c, 0x3e, 0xaa},
1566 {0x00, 0x8d, 0x90, 0xaa},
1567 {0x00, 0x8e, 0x87, 0xaa},
1568 {0x00, 0x8f, 0x96, 0xaa},
1569 {0x00, 0x90, 0x3d, 0xaa},
1570 {0x00, 0x64, 0x00, 0xaa},
1571 {0x00, 0x65, 0x10, 0xaa},
1572 {0x00, 0x66, 0x20, 0xaa},
1573 {0x00, 0x67, 0x2b, 0xaa},
1574 {0x00, 0x68, 0x36, 0xaa},
1575 {0x00, 0x69, 0x49, 0xaa},
1576 {0x00, 0x6a, 0x5a, 0xaa},
1577 {0x00, 0x6b, 0x7f, 0xaa},
1578 {0x00, 0x6c, 0x9b, 0xaa},
1579 {0x00, 0x6d, 0xba, 0xaa},
1580 {0x00, 0x6e, 0xd4, 0xaa},
1581 {0x00, 0x6f, 0xea, 0xaa},
1582 {0x00, 0x70, 0x00, 0xaa},
1583 {0x00, 0x71, 0x10, 0xaa},
1584 {0x00, 0x72, 0x20, 0xaa},
1585 {0x00, 0x73, 0x2b, 0xaa},
1586 {0x00, 0x74, 0x36, 0xaa},
1587 {0x00, 0x75, 0x49, 0xaa},
1588 {0x00, 0x76, 0x5a, 0xaa},
1589 {0x00, 0x77, 0x7f, 0xaa},
1590 {0x00, 0x78, 0x9b, 0xaa},
1591 {0x00, 0x79, 0xba, 0xaa},
1592 {0x00, 0x7a, 0xd4, 0xaa},
1593 {0x00, 0x7b, 0xea, 0xaa},
1594 {0x00, 0x7c, 0x00, 0xaa},
1595 {0x00, 0x7d, 0x10, 0xaa},
1596 {0x00, 0x7e, 0x20, 0xaa},
1597 {0x00, 0x7f, 0x2b, 0xaa},
1598 {0x00, 0x80, 0x36, 0xaa},
1599 {0x00, 0x81, 0x49, 0xaa},
1600 {0x00, 0x82, 0x5a, 0xaa},
1601 {0x00, 0x83, 0x7f, 0xaa},
1602 {0x00, 0x84, 0x9b, 0xaa},
1603 {0x00, 0x85, 0xba, 0xaa},
1604 {0x00, 0x86, 0xd4, 0xaa},
1605 {0x00, 0x87, 0xea, 0xaa},
1606 {0x00, 0x57, 0x2a, 0xaa},
1607 {0x00, 0x03, 0x01, 0xaa},
1608 {0x00, 0x04, 0x10, 0xaa},
1609 {0x00, 0x05, 0x10, 0xaa},
1610 {0x00, 0x06, 0x10, 0xaa},
1611 {0x00, 0x07, 0x10, 0xaa},
1612 {0x00, 0x08, 0x13, 0xaa},
1613 {0x00, 0x0a, 0x00, 0xaa},
1614 {0x00, 0x0b, 0x10, 0xaa},
1615 {0x00, 0x0c, 0x20, 0xaa},
1616 {0x00, 0x0d, 0x18, 0xaa},
1617 {0x00, 0x22, 0x01, 0xaa},
1618 {0x00, 0x23, 0x60, 0xaa},
1619 {0x00, 0x25, 0x08, 0xaa},
1620 {0x00, 0x26, 0x82, 0xaa},
1621 {0x00, 0x2e, 0x0f, 0xaa},
1622 {0x00, 0x2f, 0x1e, 0xaa},
1623 {0x00, 0x30, 0x2d, 0xaa},
1624 {0x00, 0x31, 0x3c, 0xaa},
1625 {0x00, 0x32, 0x4b, 0xaa},
1626 {0x00, 0x33, 0x5a, 0xaa},
1627 {0x00, 0x34, 0x69, 0xaa},
1628 {0x00, 0x35, 0x78, 0xaa},
1629 {0x00, 0x36, 0x87, 0xaa},
1630 {0x00, 0x37, 0x96, 0xaa},
1631 {0x00, 0x38, 0xa5, 0xaa},
1632 {0x00, 0x39, 0xb4, 0xaa},
1633 {0x00, 0x3a, 0xc3, 0xaa},
1634 {0x00, 0x3b, 0xd2, 0xaa},
1635 {0x00, 0x3c, 0xe1, 0xaa},
1636 {0x00, 0x3e, 0xff, 0xaa},
1637 {0x00, 0x3f, 0xff, 0xaa},
1638 {0x00, 0x40, 0xff, 0xaa},
1639 {0x00, 0x41, 0xff, 0xaa},
1640 {0x00, 0x42, 0xff, 0xaa},
1641 {0x00, 0x43, 0xff, 0xaa},
1642 {0x00, 0x03, 0x00, 0xaa},
1643 {0x00, 0x03, 0x00, 0xaa},
1644 {0x00, 0x20, 0xc4, 0xaa},
1645 {0x00, 0x13, 0x03, 0xaa},
1646 {0x00, 0x3c, 0x50, 0xaa},
1647 {0x00, 0x61, 0x6a, 0xaa}, /* sharpness? */
1648 {0x00, 0x51, 0x5b, 0xaa},
1649 {0x00, 0x52, 0x91, 0xaa},
1650 {0x00, 0x53, 0x4c, 0xaa},
1651 {0x00, 0x54, 0x50, 0xaa},
1652 {0x00, 0x56, 0x02, 0xaa},
1653 {0xb6, 0x00, 0x00, 0xcc},
1654 {0xb6, 0x03, 0x03, 0xcc},
1655 {0xb6, 0x02, 0x20, 0xcc},
1656 {0xb6, 0x05, 0x02, 0xcc},
1657 {0xb6, 0x04, 0x58, 0xcc},
1658 {0xb6, 0x12, 0xf8, 0xcc},
1659 {0xb6, 0x13, 0x21, 0xcc},
1660 {0xb6, 0x18, 0x03, 0xcc},
1661 {0xb6, 0x17, 0xa9, 0xcc},
1662 {0xb6, 0x16, 0x80, 0xcc},
1663 {0xb6, 0x22, 0x12, 0xcc},
1664 {0xb6, 0x23, 0x0b, 0xcc},
1665 {0xbf, 0xc0, 0x39, 0xcc},
1666 {0xbf, 0xc1, 0x04, 0xcc},
1667 {0xbf, 0xcc, 0x00, 0xcc},
1668 {0xb8, 0x06, 0x20, 0xcc},
1669 {0xb8, 0x07, 0x03, 0xcc},
1670 {0xb8, 0x08, 0x58, 0xcc},
1671 {0xb8, 0x09, 0x02, 0xcc},
1672 {0xb3, 0x01, 0x41, 0xcc},
1673 {0x00, 0x03, 0x00, 0xaa},
1674 {0x00, 0xd9, 0x0f, 0xaa},
1675 {0x00, 0xda, 0xaa, 0xaa},
1676 {0x00, 0xd9, 0x10, 0xaa},
1677 {0x00, 0xda, 0xaa, 0xaa},
1678 {0x00, 0xd9, 0x11, 0xaa},
1679 {0x00, 0xda, 0x00, 0xaa},
1680 {0x00, 0xd9, 0x12, 0xaa},
1681 {0x00, 0xda, 0xff, 0xaa},
1682 {0x00, 0xd9, 0x13, 0xaa},
1683 {0x00, 0xda, 0xff, 0xaa},
1684 {0x00, 0xe8, 0x11, 0xaa},
1685 {0x00, 0xe9, 0x12, 0xaa},
1686 {0x00, 0xea, 0x5c, 0xaa},
1687 {0x00, 0xeb, 0xff, 0xaa},
1688 {0x00, 0xd8, 0x80, 0xaa},
1689 {0x00, 0xe6, 0x02, 0xaa},
1690 {0x00, 0xd6, 0x40, 0xaa},
1691 {0x00, 0xe3, 0x05, 0xaa},
1692 {0x00, 0xe0, 0x40, 0xaa},
1693 {0x00, 0xde, 0x03, 0xaa},
1694 {0x00, 0xdf, 0x03, 0xaa},
1695 {0x00, 0xdb, 0x02, 0xaa},
1696 {0x00, 0xdc, 0x00, 0xaa},
1697 {0x00, 0xdd, 0x03, 0xaa},
1698 {0x00, 0xe1, 0x08, 0xaa},
1699 {0x00, 0xe2, 0x01, 0xaa},
1700 {0x00, 0xd6, 0x40, 0xaa},
1701 {0x00, 0xe4, 0x40, 0xaa},
1702 {0x00, 0xa8, 0x8f, 0xaa},
1703 {0x00, 0xb4, 0x16, 0xaa},
1704 {0xb0, 0x02, 0x06, 0xcc},
1705 {0xb0, 0x18, 0x06, 0xcc},
1706 {0xb0, 0x19, 0x06, 0xcc},
1707 {0xb3, 0x5d, 0x18, 0xcc},
1708 {0xb3, 0x05, 0x00, 0xcc},
1709 {0xb3, 0x06, 0x00, 0xcc},
1710 {0x00, 0xb4, 0x0e, 0xaa},
1711 {0x00, 0xb5, 0x49, 0xaa},
1712 {0x00, 0xb6, 0x1c, 0xaa},
1713 {0x00, 0xb7, 0x96, 0xaa},
1714/* end of usbvm326.inf - start of ms-win trace */
1715 {0xb6, 0x12, 0xf8, 0xcc},
1716 {0xb6, 0x13, 0x3d, 0xcc},
1717/*read b306*/
1718 {0x00, 0x03, 0x00, 0xaa},
1719 {0x00, 0x1a, 0x09, 0xaa},
1720 {0x00, 0x1b, 0x8a, 0xaa},
1721/*read b827*/
1722 {0xb8, 0x27, 0x00, 0xcc},
1723 {0xb8, 0x26, 0x60, 0xcc},
1724 {0xb8, 0x26, 0x60, 0xcc},
1725/*gamma - to do?*/
1726 {0x00, 0x03, 0x00, 0xaa},
1727 {0x00, 0xae, 0x84, 0xaa},
1728/*gamma again*/
1729 {0x00, 0x03, 0x00, 0xaa},
1730 {0x00, 0x96, 0xa0, 0xaa},
1731/*matrix*/
1732 {0x00, 0x03, 0x00, 0xaa},
1733 {0x00, 0x91, 0x35, 0xaa},
1734 {0x00, 0x92, 0x22, 0xaa},
1735/*gamma*/
1736 {0x00, 0x03, 0x00, 0xaa},
1737 {0x00, 0x95, 0x85, 0xaa},
1738/*matrix*/
1739 {0x00, 0x03, 0x00, 0xaa},
1740 {0x00, 0x4d, 0x20, 0xaa},
1741 {0xb8, 0x22, 0x40, 0xcc},
1742 {0xb8, 0x23, 0x40, 0xcc},
1743 {0xb8, 0x24, 0x40, 0xcc},
1744 {0xb8, 0x81, 0x09, 0xcc},
1745 {0x00, 0x00, 0x64, 0xdd},
1746 {0x00, 0x03, 0x01, 0xaa},
1747/*read 46*/
1748 {0x00, 0x46, 0x3c, 0xaa},
1749 {0x00, 0x03, 0x00, 0xaa},
1750 {0x00, 0x16, 0x40, 0xaa},
1751 {0x00, 0x17, 0x40, 0xaa},
1752 {0x00, 0x18, 0x40, 0xaa},
1753 {0x00, 0x19, 0x41, 0xaa},
1754 {0x00, 0x03, 0x01, 0xaa},
1755 {0x00, 0x46, 0x3c, 0xaa},
1756 {0x00, 0x00, 0x18, 0xdd},
1757/*read bfff*/
1758 {0x00, 0x03, 0x00, 0xaa},
1759 {0x00, 0xb4, 0x1c, 0xaa},
1760 {0x00, 0xb5, 0x92, 0xaa},
1761 {0x00, 0xb6, 0x39, 0xaa},
1762 {0x00, 0xb7, 0x24, 0xaa},
1763/*write 89 0400 1415*/
1764};
1765
1207struct sensor_info { 1766struct sensor_info {
1208 int sensorId; 1767 int sensorId;
1209 __u8 I2cAdd; 1768 __u8 I2cAdd;
@@ -1222,6 +1781,9 @@ static const struct sensor_info sensor_info_data[] = {
1222 {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01}, 1781 {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01},
1223 {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, 1782 {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
1224 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, 1783 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
1784/* (tested in vc032x_probe_sensor) */
1785/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
1786 {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
1225}; 1787};
1226 1788
1227/* read 'len' bytes in gspca_dev->usb_buf */ 1789/* read 'len' bytes in gspca_dev->usb_buf */
@@ -1278,18 +1840,18 @@ static void read_sensor_register(struct gspca_dev *gspca_dev,
1278 msleep(1); 1840 msleep(1);
1279 } 1841 }
1280 reg_r(gspca_dev, 0xa1, 0xb33e, 1); 1842 reg_r(gspca_dev, 0xa1, 0xb33e, 1);
1281 hdata = gspca_dev->usb_buf[0]; 1843 ldata = gspca_dev->usb_buf[0];
1282 reg_r(gspca_dev, 0xa1, 0xb33d, 1); 1844 reg_r(gspca_dev, 0xa1, 0xb33d, 1);
1283 mdata = gspca_dev->usb_buf[0]; 1845 mdata = gspca_dev->usb_buf[0];
1284 reg_r(gspca_dev, 0xa1, 0xb33c, 1); 1846 reg_r(gspca_dev, 0xa1, 0xb33c, 1);
1285 ldata = gspca_dev->usb_buf[0]; 1847 hdata = gspca_dev->usb_buf[0];
1286 PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)", 1848 PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
1287 hdata, mdata, ldata); 1849 hdata, mdata, ldata);
1288 reg_r(gspca_dev, 0xa1, 0xb334, 1); 1850 reg_r(gspca_dev, 0xa1, 0xb334, 1);
1289 if (gspca_dev->usb_buf[0] == 0x02) 1851 if (gspca_dev->usb_buf[0] == 0x02)
1290 *value = (ldata << 8) + mdata; 1852 *value = (hdata << 8) + mdata;
1291 else 1853 else
1292 *value = ldata; 1854 *value = hdata;
1293} 1855}
1294 1856
1295static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) 1857static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
@@ -1300,7 +1862,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
1300 const struct sensor_info *ptsensor_info; 1862 const struct sensor_info *ptsensor_info;
1301 1863
1302 reg_r(gspca_dev, 0xa1, 0xbfcf, 1); 1864 reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
1303 PDEBUG(D_PROBE, "check sensor header %d", gspca_dev->usb_buf[0]); 1865 PDEBUG(D_PROBE, "check sensor header %02x", gspca_dev->usb_buf[0]);
1304 for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { 1866 for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) {
1305 ptsensor_info = &sensor_info_data[i]; 1867 ptsensor_info = &sensor_info_data[i];
1306 reg_w(dev, 0xa0, 0x02, 0xb334); 1868 reg_w(dev, 0xa0, 0x02, 0xb334);
@@ -1309,16 +1871,15 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
1309 reg_w(dev, 0xa0, 0x01, 0xb308); 1871 reg_w(dev, 0xa0, 0x01, 0xb308);
1310 reg_w(dev, 0xa0, 0x0c, 0xb309); 1872 reg_w(dev, 0xa0, 0x0c, 0xb309);
1311 reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335); 1873 reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
1312/* PDEBUG(D_PROBE,
1313 "check sensor VC032X -> %d Add -> ox%02X!",
1314 i, ptsensor_info->I2cAdd); */
1315 reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); 1874 reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
1316 read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value); 1875 read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value);
1317 if (value == ptsensor_info->VpId) { 1876 if (value == ptsensor_info->VpId)
1318/* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!",
1319 ptsensor_info->VpId); */
1320 return ptsensor_info->sensorId; 1877 return ptsensor_info->sensorId;
1321 } 1878
1879 /* special case for MI0360 */
1880 if (ptsensor_info->sensorId == SENSOR_MI1310_SOC
1881 && value == 0x8243)
1882 return SENSOR_MI0360;
1322 } 1883 }
1323 return -1; 1884 return -1;
1324} 1885}
@@ -1420,13 +1981,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1420 cam = &gspca_dev->cam; 1981 cam = &gspca_dev->cam;
1421 cam->epaddr = 0x02; 1982 cam->epaddr = 0x02;
1422 sd->bridge = id->driver_info; 1983 sd->bridge = id->driver_info;
1423 if (sd->bridge == BRIDGE_VC0321) {
1424 cam->cam_mode = vc0321_mode;
1425 cam->nmodes = ARRAY_SIZE(vc0321_mode);
1426 } else {
1427 cam->cam_mode = vc0323_mode;
1428 cam->nmodes = ARRAY_SIZE(vc0323_mode);
1429 }
1430 1984
1431 vc0321_reset(gspca_dev); 1985 vc0321_reset(gspca_dev);
1432 sensor = vc032x_probe_sensor(gspca_dev); 1986 sensor = vc032x_probe_sensor(gspca_dev);
@@ -1436,35 +1990,66 @@ static int sd_config(struct gspca_dev *gspca_dev,
1436 return -EINVAL; 1990 return -EINVAL;
1437 case SENSOR_HV7131R: 1991 case SENSOR_HV7131R:
1438 PDEBUG(D_PROBE, "Find Sensor HV7131R"); 1992 PDEBUG(D_PROBE, "Find Sensor HV7131R");
1439 sd->sensor = SENSOR_HV7131R; 1993 break;
1994 case SENSOR_MI0360:
1995 PDEBUG(D_PROBE, "Find Sensor MI0360");
1996 sd->bridge = BRIDGE_VC0323;
1440 break; 1997 break;
1441 case SENSOR_MI1310_SOC: 1998 case SENSOR_MI1310_SOC:
1442 PDEBUG(D_PROBE, "Find Sensor MI1310_SOC"); 1999 PDEBUG(D_PROBE, "Find Sensor MI1310_SOC");
1443 sd->sensor = SENSOR_MI1310_SOC;
1444 break; 2000 break;
1445 case SENSOR_MI1320: 2001 case SENSOR_MI1320:
1446 PDEBUG(D_PROBE, "Find Sensor MI1320"); 2002 PDEBUG(D_PROBE, "Find Sensor MI1320");
1447 sd->sensor = SENSOR_MI1320;
1448 break; 2003 break;
1449 case SENSOR_OV7660: 2004 case SENSOR_OV7660:
1450 PDEBUG(D_PROBE, "Find Sensor OV7660"); 2005 PDEBUG(D_PROBE, "Find Sensor OV7660");
1451 sd->sensor = SENSOR_OV7660;
1452 break; 2006 break;
1453 case SENSOR_OV7670: 2007 case SENSOR_OV7670:
1454 PDEBUG(D_PROBE, "Find Sensor OV7670"); 2008 PDEBUG(D_PROBE, "Find Sensor OV7670");
1455 sd->sensor = SENSOR_OV7670; 2009 break;
2010 case SENSOR_PO1200:
2011 PDEBUG(D_PROBE, "Find Sensor PO1200");
1456 break; 2012 break;
1457 case SENSOR_PO3130NC: 2013 case SENSOR_PO3130NC:
1458 PDEBUG(D_PROBE, "Find Sensor PO3130NC"); 2014 PDEBUG(D_PROBE, "Find Sensor PO3130NC");
1459 sd->sensor = SENSOR_PO3130NC;
1460 break; 2015 break;
1461 } 2016 }
2017 sd->sensor = sensor;
1462 2018
1463 sd->qindex = 7; 2019 if (sd->bridge == BRIDGE_VC0321) {
1464 sd->autogain = AUTOGAIN_DEF; 2020 cam->cam_mode = vc0321_mode;
2021 cam->nmodes = ARRAY_SIZE(vc0321_mode);
2022 } else {
2023 if (sensor != SENSOR_PO1200) {
2024 cam->cam_mode = vc0323_mode;
2025 cam->nmodes = ARRAY_SIZE(vc0323_mode);
2026 } else {
2027 cam->cam_mode = svga_mode;
2028 cam->nmodes = ARRAY_SIZE(svga_mode);
2029 }
2030 }
2031
2032 sd->hflip = HFLIP_DEF;
2033 sd->vflip = VFLIP_DEF;
2034 if (sd->sensor == SENSOR_OV7670) {
2035 sd->hflip = 1;
2036 sd->vflip = 1;
2037 }
1465 sd->lightfreq = FREQ_DEF; 2038 sd->lightfreq = FREQ_DEF;
1466 if (sd->sensor != SENSOR_OV7670) 2039 if (sd->sensor != SENSOR_OV7670)
1467 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX); 2040 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
2041 switch (sd->sensor) {
2042 case SENSOR_OV7660:
2043 case SENSOR_OV7670:
2044 case SENSOR_PO1200:
2045 break;
2046 default:
2047 gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
2048 | (1 << VFLIP_IDX);
2049 break;
2050 }
2051
2052 sd->sharpness = SHARPNESS_DEF;
1468 2053
1469 if (sd->bridge == BRIDGE_VC0321) { 2054 if (sd->bridge == BRIDGE_VC0321) {
1470 reg_r(gspca_dev, 0x8a, 0, 3); 2055 reg_r(gspca_dev, 0x8a, 0, 3);
@@ -1482,12 +2067,33 @@ static int sd_init(struct gspca_dev *gspca_dev)
1482 return 0; 2067 return 0;
1483} 2068}
1484 2069
1485static void setquality(struct gspca_dev *gspca_dev) 2070/* for OV7660 and OV7670 only */
2071static void sethvflip(struct gspca_dev *gspca_dev)
1486{ 2072{
1487} 2073 struct sd *sd = (struct sd *) gspca_dev;
2074 __u8 data;
1488 2075
1489static void setautogain(struct gspca_dev *gspca_dev) 2076 switch (sd->sensor) {
1490{ 2077 case SENSOR_OV7660:
2078 data = 1;
2079 break;
2080 case SENSOR_OV7670:
2081 data = 7;
2082 break;
2083 case SENSOR_PO1200:
2084 data = 0;
2085 i2c_write(gspca_dev, 0x03, &data, 1);
2086 data = 0x80 * sd->hflip
2087 | 0x40 * sd->vflip
2088 | 0x06;
2089 i2c_write(gspca_dev, 0x1e, &data, 1);
2090 return;
2091 default:
2092 return;
2093 }
2094 data |= OV7660_MVFP_MIRROR * sd->hflip
2095 | OV7660_MVFP_VFLIP * sd->vflip;
2096 i2c_write(gspca_dev, OV7660_REG_MVFP, &data, 1);
1491} 2097}
1492 2098
1493static void setlightfreq(struct gspca_dev *gspca_dev) 2099static void setlightfreq(struct gspca_dev *gspca_dev)
@@ -1501,6 +2107,20 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
1501 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); 2107 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]);
1502} 2108}
1503 2109
2110/* po1200 only */
2111static void setsharpness(struct gspca_dev *gspca_dev)
2112{
2113 struct sd *sd = (struct sd *) gspca_dev;
2114 __u8 data;
2115
2116 if (sd->sensor != SENSOR_PO1200)
2117 return;
2118 data = 0;
2119 i2c_write(gspca_dev, 0x03, &data, 1);
2120 data = 0xb5 + sd->sharpness * 3;
2121 i2c_write(gspca_dev, 0x61, &data, 1);
2122}
2123
1504static int sd_start(struct gspca_dev *gspca_dev) 2124static int sd_start(struct gspca_dev *gspca_dev)
1505{ 2125{
1506 struct sd *sd = (struct sd *) gspca_dev; 2126 struct sd *sd = (struct sd *) gspca_dev;
@@ -1551,6 +2171,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
1551 usb_exchange(gspca_dev, ov7670_initVGA_JPG); 2171 usb_exchange(gspca_dev, ov7670_initVGA_JPG);
1552 } 2172 }
1553 break; 2173 break;
2174 case SENSOR_MI0360:
2175 GammaT = mi1320_gamma;
2176 MatrixT = mi0360_matrix;
2177 if (mode) {
2178 /* 320x240 */
2179 usb_exchange(gspca_dev, mi0360_initQVGA_JPG);
2180 } else {
2181 /* 640x480 */
2182 usb_exchange(gspca_dev, mi0360_initVGA_JPG);
2183 }
2184 break;
1554 case SENSOR_MI1310_SOC: 2185 case SENSOR_MI1310_SOC:
1555 if (mode) { 2186 if (mode) {
1556 /* 320x240 */ 2187 /* 320x240 */
@@ -1583,6 +2214,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
1583 } 2214 }
1584 usb_exchange(gspca_dev, po3130_rundata); 2215 usb_exchange(gspca_dev, po3130_rundata);
1585 break; 2216 break;
2217 case SENSOR_PO1200:
2218 GammaT = po1200_gamma;
2219 MatrixT = po1200_matrix;
2220 usb_exchange(gspca_dev, po1200_initVGA_data);
2221 break;
1586 default: 2222 default:
1587 PDEBUG(D_PROBE, "Damned !! no sensor found Bye"); 2223 PDEBUG(D_PROBE, "Damned !! no sensor found Bye");
1588 return -EMEDIUMTYPE; 2224 return -EMEDIUMTYPE;
@@ -1615,11 +2251,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
1615 reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS 2251 reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS
1616 */ 2252 */
1617 /* set the led on 0x0892 0x0896 */ 2253 /* set the led on 0x0892 0x0896 */
1618 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); 2254 if (sd->sensor != SENSOR_PO1200) {
1619 msleep(100); 2255 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
1620 setquality(gspca_dev); 2256 msleep(100);
1621 setautogain(gspca_dev); 2257 sethvflip(gspca_dev);
1622 setlightfreq(gspca_dev); 2258 setlightfreq(gspca_dev);
2259 } else {
2260 setsharpness(gspca_dev);
2261 sethvflip(gspca_dev);
2262 reg_w(gspca_dev->dev, 0x89, 0x0400, 0x1415);
2263 }
1623 } 2264 }
1624 return 0; 2265 return 0;
1625} 2266}
@@ -1665,24 +2306,48 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1665 data, len); 2306 data, len);
1666 return; 2307 return;
1667 } 2308 }
2309
2310 /* The vc0321 sends some additional data after sending the complete
2311 * frame, we ignore this. */
2312 if (sd->bridge == BRIDGE_VC0321
2313 && len > frame->v4l2_buf.length - (frame->data_end - frame->data))
2314 len = frame->v4l2_buf.length - (frame->data_end - frame->data);
1668 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 2315 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1669} 2316}
1670 2317
1671static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 2318static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2319{
2320 struct sd *sd = (struct sd *) gspca_dev;
2321
2322 sd->hflip = val;
2323 if (gspca_dev->streaming)
2324 sethvflip(gspca_dev);
2325 return 0;
2326}
2327
2328static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
2329{
2330 struct sd *sd = (struct sd *) gspca_dev;
2331
2332 *val = sd->hflip;
2333 return 0;
2334}
2335
2336static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1672{ 2337{
1673 struct sd *sd = (struct sd *) gspca_dev; 2338 struct sd *sd = (struct sd *) gspca_dev;
1674 2339
1675 sd->autogain = val; 2340 sd->vflip = val;
1676 if (gspca_dev->streaming) 2341 if (gspca_dev->streaming)
1677 setautogain(gspca_dev); 2342 sethvflip(gspca_dev);
1678 return 0; 2343 return 0;
1679} 2344}
1680 2345
1681static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 2346static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1682{ 2347{
1683 struct sd *sd = (struct sd *) gspca_dev; 2348 struct sd *sd = (struct sd *) gspca_dev;
1684 2349
1685 *val = sd->autogain; 2350 *val = sd->vflip;
1686 return 0; 2351 return 0;
1687} 2352}
1688 2353
@@ -1704,6 +2369,24 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1704 return 0; 2369 return 0;
1705} 2370}
1706 2371
2372static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2373{
2374 struct sd *sd = (struct sd *) gspca_dev;
2375
2376 sd->sharpness = val;
2377 if (gspca_dev->streaming)
2378 setsharpness(gspca_dev);
2379 return 0;
2380}
2381
2382static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2383{
2384 struct sd *sd = (struct sd *) gspca_dev;
2385
2386 *val = sd->sharpness;
2387 return 0;
2388}
2389
1707static int sd_querymenu(struct gspca_dev *gspca_dev, 2390static int sd_querymenu(struct gspca_dev *gspca_dev,
1708 struct v4l2_querymenu *menu) 2391 struct v4l2_querymenu *menu)
1709{ 2392{
@@ -1743,11 +2426,13 @@ static const struct sd_desc sd_desc = {
1743static const __devinitdata struct usb_device_id device_table[] = { 2426static const __devinitdata struct usb_device_id device_table[] = {
1744 {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321}, 2427 {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
1745 {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321}, 2428 {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
2429 {USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321},
1746 {USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321}, 2430 {USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321},
1747 {USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323}, 2431 {USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323},
1748 {USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321}, 2432 {USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321},
1749 {USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321}, 2433 {USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321},
1750 {USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321}, 2434 {USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321},
2435 {USB_DEVICE(0x15b8, 0x6002), .driver_info = BRIDGE_VC0323},
1751 {USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323}, 2436 {USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323},
1752 {} 2437 {}
1753}; 2438};
diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/video/gspca/zc3xx-reg.h
index f52e09c2cc19..bfb559c3b713 100644
--- a/drivers/media/video/gspca/zc3xx-reg.h
+++ b/drivers/media/video/gspca/zc3xx-reg.h
@@ -244,14 +244,6 @@
244#define ZC3XX_R1CA_SHARPNESS04 0x01ca 244#define ZC3XX_R1CA_SHARPNESS04 0x01ca
245#define ZC3XX_R1CB_SHARPNESS05 0x01cb 245#define ZC3XX_R1CB_SHARPNESS05 0x01cb
246 246
247/* Synchronization */
248#define ZC3XX_R190_SYNC00LOW 0x0190
249#define ZC3XX_R191_SYNC00MID 0x0191
250#define ZC3XX_R192_SYNC00HIGH 0x0192
251#define ZC3XX_R195_SYNC01LOW 0x0195
252#define ZC3XX_R196_SYNC01MID 0x0196
253#define ZC3XX_R197_SYNC01HIGH 0x0197
254
255/* Dead pixels */ 247/* Dead pixels */
256#define ZC3XX_R250_DEADPIXELSMODE 0x0250 248#define ZC3XX_R250_DEADPIXELSMODE 0x0250
257 249
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 0befacf49855..ec2a53d53fe2 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -51,16 +51,16 @@ struct sd {
51#define SENSOR_CS2102 0 51#define SENSOR_CS2102 0
52#define SENSOR_CS2102K 1 52#define SENSOR_CS2102K 1
53#define SENSOR_GC0305 2 53#define SENSOR_GC0305 2
54#define SENSOR_HDCS2020 3 54#define SENSOR_HDCS2020b 3
55#define SENSOR_HDCS2020b 4 55#define SENSOR_HV7131B 4
56#define SENSOR_HV7131B 5 56#define SENSOR_HV7131C 5
57#define SENSOR_HV7131C 6 57#define SENSOR_ICM105A 6
58#define SENSOR_ICM105A 7 58#define SENSOR_MC501CB 7
59#define SENSOR_MC501CB 8 59#define SENSOR_OV7620 8
60#define SENSOR_OV7620 9 60/*#define SENSOR_OV7648 8 - same values */
61/*#define SENSOR_OV7648 9 - same values */ 61#define SENSOR_OV7630C 9
62#define SENSOR_OV7630C 10 62#define SENSOR_PAS106 10
63#define SENSOR_PAS106 11 63#define SENSOR_PAS202B 11
64#define SENSOR_PB0330 12 64#define SENSOR_PB0330 12
65#define SENSOR_PO2030 13 65#define SENSOR_PO2030 13
66#define SENSOR_TAS5130CK 14 66#define SENSOR_TAS5130CK 14
@@ -173,7 +173,7 @@ static struct ctrl sd_ctrls[] = {
173 }, 173 },
174}; 174};
175 175
176static struct v4l2_pix_format vga_mode[] = { 176static const struct v4l2_pix_format vga_mode[] = {
177 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 177 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
178 .bytesperline = 320, 178 .bytesperline = 320,
179 .sizeimage = 320 * 240 * 3 / 8 + 590, 179 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -186,7 +186,7 @@ static struct v4l2_pix_format vga_mode[] = {
186 .priv = 0}, 186 .priv = 0},
187}; 187};
188 188
189static struct v4l2_pix_format sif_mode[] = { 189static const struct v4l2_pix_format sif_mode[] = {
190 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 190 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
191 .bytesperline = 176, 191 .bytesperline = 176,
192 .sizeimage = 176 * 144 * 3 / 8 + 590, 192 .sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -1653,295 +1653,6 @@ static const struct usb_action gc0305_NoFliker[] = {
1653 {} 1653 {}
1654}; 1654};
1655 1655
1656/* play poker with registers at your own risk !! */
1657static const struct usb_action hdcs2020xx_Initial[] = {
1658 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1659 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
1660 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT},
1661 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
1662 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
1663 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
1664 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
1665 {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW},
1666 /* D0 ?? E0 did not start */
1667 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
1668 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
1669 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
1670 {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
1671 {0xa0, 0x08, ZC3XX_R098_WINYSTARTLOW},
1672 {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW},
1673 {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW},
1674 {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW},
1675 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
1676 {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW},
1677 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
1678 {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
1679 {0xaa, 0x02, 0x0002},
1680 {0xaa, 0x07, 0x0006},
1681 {0xaa, 0x08, 0x0002},
1682 {0xaa, 0x09, 0x0006},
1683 {0xaa, 0x0a, 0x0001},
1684 {0xaa, 0x0b, 0x0001},
1685 {0xaa, 0x0c, 0x0008},
1686 {0xaa, 0x0d, 0x0000},
1687 {0xaa, 0x10, 0x0000},
1688 {0xaa, 0x12, 0x0005},
1689 {0xaa, 0x13, 0x0063},
1690 {0xaa, 0x15, 0x0070},
1691 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
1692 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
1693 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
1694 {0xa0, 0x00, 0x01ad},
1695 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
1696 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
1697 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
1698 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
1699 {0xa0, 0x70, ZC3XX_R18D_YTARGET},
1700 {0xa1, 0x01, 0x0002},
1701 {0xa1, 0x01, 0x0008},
1702 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
1703 {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
1704 {0xa1, 0x01, 0x01c8},
1705 {0xa1, 0x01, 0x01c9},
1706 {0xa1, 0x01, 0x01ca},
1707 {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
1708 {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4 */
1709 {0xa0, 0x37, ZC3XX_R121_GAMMA01},
1710 {0xa0, 0x58, ZC3XX_R122_GAMMA02},
1711 {0xa0, 0x79, ZC3XX_R123_GAMMA03},
1712 {0xa0, 0x91, ZC3XX_R124_GAMMA04},
1713 {0xa0, 0xa6, ZC3XX_R125_GAMMA05},
1714 {0xa0, 0xb8, ZC3XX_R126_GAMMA06},
1715 {0xa0, 0xc7, ZC3XX_R127_GAMMA07},
1716 {0xa0, 0xd3, ZC3XX_R128_GAMMA08},
1717 {0xa0, 0xde, ZC3XX_R129_GAMMA09},
1718 {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A},
1719 {0xa0, 0xed, ZC3XX_R12B_GAMMA0B},
1720 {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C},
1721 {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D},
1722 {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E},
1723 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
1724 {0xa0, 0x26, ZC3XX_R130_GAMMA10},
1725 {0xa0, 0x23, ZC3XX_R131_GAMMA11},
1726 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
1727 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
1728 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
1729 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
1730 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
1731 {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
1732 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
1733 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
1734 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
1735 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
1736 {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
1737 {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
1738 {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
1739 {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
1740
1741 {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */
1742 {0xa0, 0xf5, ZC3XX_R10B_RGB01},
1743 {0xa0, 0xff, ZC3XX_R10C_RGB02},
1744 {0xa0, 0xf9, ZC3XX_R10D_RGB10},
1745 {0xa0, 0x51, ZC3XX_R10E_RGB11},
1746 {0xa0, 0xf5, ZC3XX_R10F_RGB12},
1747 {0xa0, 0xfb, ZC3XX_R110_RGB20},
1748 {0xa0, 0xed, ZC3XX_R111_RGB21},
1749 {0xa0, 0x5f, ZC3XX_R112_RGB22},
1750
1751 {0xa1, 0x01, 0x0180},
1752 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
1753 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
1754 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
1755 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
1756 {0xaa, 0x20, 0x0004},
1757 {0xaa, 0x21, 0x003d},
1758 {0xaa, 0x03, 0x0041},
1759 {0xaa, 0x04, 0x0010},
1760 {0xaa, 0x05, 0x003d},
1761 {0xaa, 0x0e, 0x0001},
1762 {0xaa, 0x0f, 0x0000},
1763 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
1764 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
1765 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
1766 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
1767 {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
1768 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
1769 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
1770 {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW},
1771 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
1772 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
1773 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0},
1774 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1},
1775 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2},
1776 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
1777 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID},
1778 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW},
1779 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
1780 {0xa1, 0x01, 0x0195},
1781 {0xa1, 0x01, 0x0196},
1782 {0xa1, 0x01, 0x0197},
1783 {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
1784 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
1785 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
1786 {0xa0, 0x1d, ZC3XX_R116_RGAIN},
1787 {0xa0, 0x40, ZC3XX_R117_GGAIN},
1788 {0xa0, 0x85, ZC3XX_R118_BGAIN},
1789 {0xa1, 0x01, 0x0116},
1790 {0xa1, 0x01, 0x0118},
1791 {0xa1, 0x01, 0x0180},
1792 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
1793 {0xa0, 0x1d, ZC3XX_R116_RGAIN},
1794 {0xa0, 0x40, ZC3XX_R117_GGAIN},
1795 {0xa0, 0x85, ZC3XX_R118_BGAIN},
1796 {0xa1, 0x01, 0x0116},
1797 {0xa1, 0x01, 0x0118},
1798/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
1799 {0xa0, 0x00, 0x0007},
1800 {}
1801};
1802
1803static const struct usb_action hdcs2020xx_InitialScale[] = {
1804 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1805 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
1806 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT},
1807 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
1808 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
1809 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
1810 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
1811 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
1812 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
1813 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
1814 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
1815 {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
1816 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
1817 {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},
1818 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
1819 {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},
1820 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
1821 {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
1822 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
1823 {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
1824 {0xaa, 0x02, 0x0002},
1825 {0xaa, 0x07, 0x0006},
1826 {0xaa, 0x08, 0x0002},
1827 {0xaa, 0x09, 0x0006},
1828 {0xaa, 0x0a, 0x0001},
1829 {0xaa, 0x0b, 0x0001},
1830 {0xaa, 0x0c, 0x0008},
1831 {0xaa, 0x0d, 0x0000},
1832 {0xaa, 0x10, 0x0000},
1833 {0xaa, 0x12, 0x0005},
1834 {0xaa, 0x13, 0x0063},
1835 {0xaa, 0x15, 0x0070},
1836 {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
1837 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
1838 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
1839 {0xa0, 0x00, 0x01ad},
1840 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
1841 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
1842 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
1843 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
1844 {0xa0, 0x70, ZC3XX_R18D_YTARGET},
1845 {0xa1, 0x01, 0x0002},
1846 {0xa1, 0x01, 0x0008},
1847 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
1848 {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
1849 {0xa1, 0x01, 0x01c8},
1850 {0xa1, 0x01, 0x01c9},
1851 {0xa1, 0x01, 0x01ca},
1852 {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
1853 {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4*/
1854 {0xa0, 0x37, ZC3XX_R121_GAMMA01},
1855 {0xa0, 0x58, ZC3XX_R122_GAMMA02},
1856 {0xa0, 0x79, ZC3XX_R123_GAMMA03},
1857 {0xa0, 0x91, ZC3XX_R124_GAMMA04},
1858 {0xa0, 0xa6, ZC3XX_R125_GAMMA05},
1859 {0xa0, 0xb8, ZC3XX_R126_GAMMA06},
1860 {0xa0, 0xc7, ZC3XX_R127_GAMMA07},
1861 {0xa0, 0xd3, ZC3XX_R128_GAMMA08},
1862 {0xa0, 0xde, ZC3XX_R129_GAMMA09},
1863 {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A},
1864 {0xa0, 0xed, ZC3XX_R12B_GAMMA0B},
1865 {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C},
1866 {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D},
1867 {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E},
1868 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
1869 {0xa0, 0x26, ZC3XX_R130_GAMMA10},
1870 {0xa0, 0x23, ZC3XX_R131_GAMMA11},
1871 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
1872 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
1873 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
1874 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
1875 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
1876 {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
1877 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
1878 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
1879 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
1880 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
1881 {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
1882 {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
1883 {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
1884 {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
1885 {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */
1886 {0xa0, 0xff, ZC3XX_R10B_RGB01},
1887 {0xa0, 0xff, ZC3XX_R10C_RGB02},
1888 {0xa0, 0xff, ZC3XX_R10D_RGB10},
1889 {0xa0, 0x60, ZC3XX_R10E_RGB11},
1890 {0xa0, 0xff, ZC3XX_R10F_RGB12},
1891 {0xa0, 0xff, ZC3XX_R110_RGB20},
1892 {0xa0, 0xff, ZC3XX_R111_RGB21},
1893 {0xa0, 0x60, ZC3XX_R112_RGB22},
1894
1895 {0xa1, 0x01, 0x0180},
1896 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
1897 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
1898 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
1899 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
1900 {0xaa, 0x20, 0x0002},
1901 {0xaa, 0x21, 0x001b},
1902 {0xaa, 0x03, 0x0044},
1903 {0xaa, 0x04, 0x0008},
1904 {0xaa, 0x05, 0x001b},
1905 {0xaa, 0x0e, 0x0001},
1906 {0xaa, 0x0f, 0x0000},
1907 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
1908 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
1909 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
1910 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
1911 {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
1912 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
1913 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
1914 {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW},
1915 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
1916 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
1917 {0xa0, 0x44, ZC3XX_R01D_HSYNC_0},
1918 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1},
1919 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2},
1920 {0xa0, 0xeb, ZC3XX_R020_HSYNC_3},
1921 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID},
1922 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW},
1923 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
1924 {0xa1, 0x01, 0x0195},
1925 {0xa1, 0x01, 0x0196},
1926 {0xa1, 0x01, 0x0197},
1927 {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
1928 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
1929 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
1930 {0xa0, 0x1d, ZC3XX_R116_RGAIN},
1931 {0xa0, 0x40, ZC3XX_R117_GGAIN},
1932 {0xa0, 0x99, ZC3XX_R118_BGAIN},
1933 {0xa1, 0x01, 0x0116},
1934 {0xa1, 0x01, 0x0118},
1935 {0xa1, 0x01, 0x0180},
1936 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
1937 {0xa0, 0x1d, ZC3XX_R116_RGAIN},
1938 {0xa0, 0x40, ZC3XX_R117_GGAIN},
1939 {0xa0, 0x99, ZC3XX_R118_BGAIN},
1940/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
1941 {0xa0, 0x00, 0x0007},
1942/* {0xa0, 0x18, 0x00fe}, */
1943 {}
1944};
1945static const struct usb_action hdcs2020xb_Initial[] = { 1656static const struct usb_action hdcs2020xb_Initial[] = {
1946 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1657 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1947 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, 1658 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
@@ -2310,67 +2021,6 @@ static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */
2310 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 2021 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
2311 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 2022 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
2312 {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */ 2023 {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */
2313 {0xa1, 0x01, 0x0002},
2314 {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
2315 {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
2316 {0xa1, 0x01, 0x0091},
2317 {0xa1, 0x01, 0x0095},
2318 {0xa1, 0x01, 0x0096},
2319
2320 {0xa1, 0x01, 0x0008},
2321 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
2322 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
2323 {0xa1, 0x01, 0x01c8},
2324 {0xa1, 0x01, 0x01c9},
2325 {0xa1, 0x01, 0x01ca},
2326 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
2327
2328 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
2329 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
2330 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
2331 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
2332 {0xa0, 0x50, ZC3XX_R10E_RGB11},
2333 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
2334 {0xa0, 0xf8, ZC3XX_R110_RGB20},
2335 {0xa0, 0xf8, ZC3XX_R111_RGB21},
2336 {0xa0, 0x50, ZC3XX_R112_RGB22},
2337 {0xa1, 0x01, 0x0180},
2338 {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
2339 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
2340 {0xaa, 0x25, 0x0007},
2341 {0xaa, 0x26, 0x00a1},
2342 {0xaa, 0x27, 0x0020},
2343 {0xaa, 0x20, 0x0000},
2344 {0xaa, 0x21, 0x00a0},
2345 {0xaa, 0x22, 0x0016},
2346 {0xaa, 0x23, 0x0040},
2347
2348 {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2F */
2349 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */
2350 {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW},
2351 {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH},
2352 {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID},
2353 {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW},
2354 {0xa0, 0x07, ZC3XX_R18C_AEFREEZE},
2355 {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE},
2356 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF},
2357 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
2358 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
2359 {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1},
2360 {0xa0, 0x16, ZC3XX_R01F_HSYNC_2},
2361 {0xa0, 0x40, ZC3XX_R020_HSYNC_3},
2362 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
2363 {0xa1, 0x01, 0x001d},
2364 {0xa1, 0x01, 0x001e},
2365 {0xa1, 0x01, 0x001f},
2366 {0xa1, 0x01, 0x0020},
2367 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
2368 {0xa1, 0x01, 0x0180},
2369 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
2370 {0xa0, 0x40, ZC3XX_R116_RGAIN},
2371 {0xa0, 0x40, ZC3XX_R117_GGAIN},
2372 {0xa0, 0x40, ZC3XX_R118_BGAIN},
2373/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
2374 {} 2024 {}
2375}; 2025};
2376 2026
@@ -2418,65 +2068,156 @@ static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/
2418 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 2068 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
2419 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 2069 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
2420 {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */ 2070 {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */
2421 {0xa1, 0x01, 0x0002}, 2071 {}
2422 {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, 2072};
2423 {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, 2073static const struct usb_action hv7131b_50HZ[] = { /* 640x480*/
2424 {0xa1, 0x01, 0x0091}, 2074 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2425 {0xa1, 0x01, 0x0095}, 2075 {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
2426 {0xa1, 0x01, 0x0096}, 2076 {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
2427 {0xa1, 0x01, 0x0008}, 2077 {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
2428 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ 2078 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2429 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ 2079 {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
2430 {0xa1, 0x01, 0x01c8}, 2080 {0xaa, 0x22, 0x001b}, /* 00,22,1b,aa */
2431 {0xa1, 0x01, 0x01c9}, 2081 {0xaa, 0x23, 0x00fc}, /* 00,23,fc,aa */
2432 {0xa1, 0x01, 0x01ca}, 2082 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2433 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ 2083 {0xa0, 0x9b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,9b,cc */
2434 2084 {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */
2435 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ 2085 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
2436 {0xa0, 0xf8, ZC3XX_R10B_RGB01}, 2086 {0xa0, 0xea, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,ea,cc */
2437 {0xa0, 0xf8, ZC3XX_R10C_RGB02}, 2087 {0xa0, 0x60, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,60,cc */
2438 {0xa0, 0xf8, ZC3XX_R10D_RGB10}, 2088 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
2439 {0xa0, 0x50, ZC3XX_R10E_RGB11}, 2089 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
2440 {0xa0, 0xf8, ZC3XX_R10F_RGB12}, 2090 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
2441 {0xa0, 0xf8, ZC3XX_R110_RGB20}, 2091 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
2442 {0xa0, 0xf8, ZC3XX_R111_RGB21}, 2092 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2443 {0xa0, 0x50, ZC3XX_R112_RGB22}, 2093 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
2444 {0xa1, 0x01, 0x0180}, 2094 {0xa0, 0x1b, ZC3XX_R01F_HSYNC_2}, /* 00,1f,1b,cc */
2445 {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, 2095 {0xa0, 0xfc, ZC3XX_R020_HSYNC_3}, /* 00,20,fc,cc */
2446 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 2096 {}
2447 {0xaa, 0x25, 0x0007}, 2097};
2448 {0xaa, 0x26, 0x00a1}, 2098static const struct usb_action hv7131b_50HZScale[] = { /* 320x240 */
2449 {0xaa, 0x27, 0x0020}, 2099 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2450 {0xaa, 0x20, 0x0000}, 2100 {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
2451 {0xaa, 0x21, 0x0040}, 2101 {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
2452 {0xaa, 0x22, 0x0013}, 2102 {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
2453 {0xaa, 0x23, 0x004c}, 2103 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2454 {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */ 2104 {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
2455 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */ 2105 {0xaa, 0x22, 0x0012}, /* 00,22,12,aa */
2456 {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 60 */ 2106 {0xaa, 0x23, 0x0080}, /* 00,23,80,aa */
2457 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, 2107 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2458 {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID}, 2108 {0xa0, 0x9b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,9b,cc */
2459 {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW}, 2109 {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */
2460 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, 2110 {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,01,cc */
2461 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, 2111 {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,d4,cc */
2462 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, 2112 {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,c0,cc */
2463 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, 2113 {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
2464 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, 2114 {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
2465 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, 2115 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
2466 {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, 2116 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
2467 {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, 2117 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2468 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, 2118 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
2469 {0xa1, 0x01, 0x001d}, 2119 {0xa0, 0x12, ZC3XX_R01F_HSYNC_2}, /* 00,1f,12,cc */
2470 {0xa1, 0x01, 0x001e}, 2120 {0xa0, 0x80, ZC3XX_R020_HSYNC_3}, /* 00,20,80,cc */
2471 {0xa1, 0x01, 0x001f}, 2121 {}
2472 {0xa1, 0x01, 0x0020}, 2122};
2473 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, 2123static const struct usb_action hv7131b_60HZ[] = { /* 640x480*/
2474 {0xa1, 0x01, 0x0180}, 2124 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2475 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, 2125 {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
2476 {0xa0, 0x40, ZC3XX_R116_RGAIN}, 2126 {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
2477 {0xa0, 0x40, ZC3XX_R117_GGAIN}, 2127 {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
2478 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 2128 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2479/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ 2129 {0xaa, 0x21, 0x0040}, /* 00,21,40,aa */
2130 {0xaa, 0x22, 0x0013}, /* 00,22,13,aa */
2131 {0xaa, 0x23, 0x004c}, /* 00,23,4c,aa */
2132 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2133 {0xa0, 0x4d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,4d,cc */
2134 {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,60,cc */
2135 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
2136 {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,c3,cc */
2137 {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,50,cc */
2138 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
2139 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
2140 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
2141 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
2142 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2143 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */
2144 {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, /* 00,1f,13,cc */
2145 {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, /* 00,20,4c,cc */
2146 {}
2147};
2148static const struct usb_action hv7131b_60HZScale[] = { /* 320x240 */
2149 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2150 {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
2151 {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
2152 {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
2153 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2154 {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
2155 {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
2156 {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
2157 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2158 {0xa0, 0x4d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,4d,cc */
2159 {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,60,cc */
2160 {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,01,cc */
2161 {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,86,cc */
2162 {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,a0,cc */
2163 {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
2164 {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
2165 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
2166 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
2167 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2168 {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
2169 {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
2170 {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
2171 {}
2172};
2173static const struct usb_action hv7131b_NoFliker[] = { /* 640x480*/
2174 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2175 {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
2176 {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
2177 {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
2178 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2179 {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */
2180 {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */
2181 {0xaa, 0x23, 0x0003}, /* 00,23,03,aa */
2182 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2183 {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,f8,cc */
2184 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,00,cc */
2185 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
2186 {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,02,cc */
2187 {0xa0, 0x00, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,00,cc */
2188 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
2189 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
2190 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
2191 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
2192 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2193 {0xa0, 0x10, ZC3XX_R01E_HSYNC_1}, /* 00,1e,10,cc */
2194 {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, /* 00,1f,00,cc */
2195 {0xa0, 0x03, ZC3XX_R020_HSYNC_3}, /* 00,20,03,cc */
2196 {}
2197};
2198static const struct usb_action hv7131b_NoFlikerScale[] = { /* 320x240 */
2199 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2200 {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
2201 {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
2202 {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
2203 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2204 {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
2205 {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
2206 {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
2207 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2208 {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,f8,cc */
2209 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,00,cc */
2210 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
2211 {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,02,cc */
2212 {0xa0, 0x00, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,00,cc */
2213 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
2214 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
2215 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
2216 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
2217 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2218 {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
2219 {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
2220 {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
2480 {} 2221 {}
2481}; 2222};
2482 2223
@@ -4389,6 +4130,270 @@ static const struct usb_action pas106b_NoFliker[] = {
4389 {} 4130 {}
4390}; 4131};
4391 4132
4133/* from usbvm31b.inf */
4134static const struct usb_action pas202b_Initial[] = { /* 640x480 */
4135 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4136 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
4137 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
4138 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
4139 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
4140 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
4141 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
4142 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
4143 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
4144 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
4145 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
4146 {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
4147 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
4148 {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,03,cc */
4149 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
4150 {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,03,cc */
4151 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
4152 {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */
4153 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
4154 {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
4155 {0xaa, 0x02, 0x0002}, /* 00,02,04,aa --> 02 */
4156 {0xaa, 0x07, 0x0006}, /* 00,07,06,aa */
4157 {0xaa, 0x08, 0x0002}, /* 00,08,02,aa */
4158 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
4159 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
4160 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
4161 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */
4162 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
4163 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
4164 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
4165 {0xaa, 0x13, 0x0063}, /* 00,13,63,aa */
4166 {0xaa, 0x15, 0x0070}, /* 00,15,70,aa */
4167 {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */
4168 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
4169 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
4170 {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
4171 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
4172 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
4173 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
4174 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
4175 {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */
4176 {}
4177};
4178static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4179 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4180 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
4181 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
4182 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
4183 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
4184 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
4185 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
4186 {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
4187 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
4188 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
4189 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
4190 {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
4191 {0xa0, 0x08, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,08,cc */
4192 {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,02,cc */
4193 {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,08,cc */
4194 {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,02,cc */
4195 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
4196 {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */
4197 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
4198 {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
4199 {0xaa, 0x02, 0x0002}, /* 00,02,02,aa */
4200 {0xaa, 0x07, 0x0006}, /* 00,07,06,aa */
4201 {0xaa, 0x08, 0x0002}, /* 00,08,02,aa */
4202 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
4203 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
4204 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
4205 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */
4206 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
4207 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
4208 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
4209 {0xaa, 0x13, 0x0063}, /* 00,13,63,aa */
4210 {0xaa, 0x15, 0x0070}, /* 00,15,70,aa */
4211 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
4212 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
4213 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
4214 {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
4215 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
4216 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
4217 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
4218 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
4219 {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */
4220 {}
4221};
4222static const struct usb_action pas202b_50HZ[] = {
4223 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4224 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4225 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4226 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4227 {0xaa, 0x21, 0x0068}, /* 00,21,68,aa */
4228 {0xaa, 0x03, 0x0044}, /* 00,03,44,aa */
4229 {0xaa, 0x04, 0x0009}, /* 00,04,09,aa */
4230 {0xaa, 0x05, 0x0028}, /* 00,05,28,aa */
4231 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4232 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4233 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */
4234 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4235 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4236 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4237 {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,d2,cc */
4238 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4239 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4240 {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4d,cc */
4241 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4242 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4243 {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, /* 00,1d,44,cc */
4244 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4245 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
4246 {0xa0, 0xeb, ZC3XX_R020_HSYNC_3}, /* 00,20,eb,cc */
4247 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4248 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4249 {}
4250};
4251static const struct usb_action pas202b_50HZScale[] = {
4252 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4253 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4254 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4255 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4256 {0xaa, 0x21, 0x006c}, /* 00,21,6c,aa */
4257 {0xaa, 0x03, 0x0041}, /* 00,03,41,aa */
4258 {0xaa, 0x04, 0x0009}, /* 00,04,09,aa */
4259 {0xaa, 0x05, 0x002c}, /* 00,05,2c,aa */
4260 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4261 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4262 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */
4263 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4264 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4265 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */
4266 {0xa0, 0xbe, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,be,cc */
4267 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4268 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4269 {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,9b,cc */
4270 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4271 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4272 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */
4273 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4274 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
4275 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
4276 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4277 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4278 {}
4279};
4280static const struct usb_action pas202b_60HZ[] = {
4281 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4282 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4283 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4284 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4285 {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
4286 {0xaa, 0x03, 0x0045}, /* 00,03,45,aa */
4287 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4288 {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
4289 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4290 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4291 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */
4292 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4293 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4294 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4295 {0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,c0,cc */
4296 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4297 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4298 {0xa0, 0x40, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,40,cc */
4299 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4300 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4301 {0xa0, 0x45, ZC3XX_R01D_HSYNC_0}, /* 00,1d,45,cc */
4302 {0xa0, 0x8e, ZC3XX_R01E_HSYNC_1}, /* 00,1e,8e,cc */
4303 {0xa0, 0xc1, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c1,cc */
4304 {0xa0, 0xf5, ZC3XX_R020_HSYNC_3}, /* 00,20,f5,cc */
4305 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4306 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4307 {}
4308};
4309static const struct usb_action pas202b_60HZScale[] = {
4310 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4311 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4312 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4313 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4314 {0xaa, 0x21, 0x0004}, /* 00,21,04,aa */
4315 {0xaa, 0x03, 0x0042}, /* 00,03,42,aa */
4316 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4317 {0xaa, 0x05, 0x0004}, /* 00,05,04,aa */
4318 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4319 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4320 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */
4321 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4322 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4323 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */
4324 {0xa0, 0x9f, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,9f,cc */
4325 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4326 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4327 {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */
4328 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4329 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4330 {0xa0, 0x42, ZC3XX_R01D_HSYNC_0}, /* 00,1d,42,cc */
4331 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4332 {0xa0, 0xaf, ZC3XX_R01F_HSYNC_2}, /* 00,1f,af,cc */
4333 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
4334 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4335 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4336 {}
4337};
4338static const struct usb_action pas202b_NoFliker[] = {
4339 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4340 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4341 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4342 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4343 {0xaa, 0x21, 0x0020}, /* 00,21,20,aa */
4344 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
4345 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4346 {0xaa, 0x05, 0x0020}, /* 00,05,20,aa */
4347 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4348 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4349 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4350 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4351 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
4352 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4353 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4354 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */
4355 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4356 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4357 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
4358 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
4359 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
4360 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
4361 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
4362 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
4363 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4364 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4365 {}
4366};
4367static const struct usb_action pas202b_NoFlikerScale[] = {
4368 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4369 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4370 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4371 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4372 {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */
4373 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
4374 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4375 {0xaa, 0x05, 0x0010}, /* 00,05,10,aa */
4376 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4377 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4378 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4379 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */
4380 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
4381 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4382 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4383 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */
4384 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4385 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4386 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
4387 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
4388 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
4389 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
4390 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
4391 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
4392 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4393 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4394 {}
4395};
4396
4392static const struct usb_action pb03303x_Initial[] = { 4397static const struct usb_action pb03303x_Initial[] = {
4393 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4398 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4394 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 4399 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -5725,7 +5730,7 @@ static const struct usb_action tas5130cxx_Initial[] = {
5725 {} 5730 {}
5726}; 5731};
5727static const struct usb_action tas5130cxx_InitialScale[] = { 5732static const struct usb_action tas5130cxx_InitialScale[] = {
5728 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5733/*?? {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, */
5729 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5734 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
5730 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, 5735 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT},
5731 5736
@@ -6049,7 +6054,7 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = {
6049 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ 6054 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */
6050 {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ 6055 {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */
6051 {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ 6056 {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */
6052 {0xaa, 0x01, 0x0000}, 6057/*?? {0xaa, 0x01, 0x0000}, */
6053 {0xaa, 0x01, 0x0000}, 6058 {0xaa, 0x01, 0x0000},
6054 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ 6059 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */
6055 {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ 6060 {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */
@@ -6065,8 +6070,8 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = {
6065 {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ 6070 {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */
6066 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ 6071 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */
6067 {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ 6072 {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */
6068 {0xa0, 0x00, 0x0039}, 6073/*?? {0xa0, 0x00, 0x0039},
6069 {0xa1, 0x01, 0x0037}, 6074 {0xa1, 0x01, 0x0037}, */
6070 {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ 6075 {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */
6071 {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */ 6076 {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */
6072 {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ 6077 {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */
@@ -6303,7 +6308,7 @@ static __u8 i2c_write(struct gspca_dev *gspca_dev,
6303 reg_w_i(gspca_dev->dev, valL, 0x93); 6308 reg_w_i(gspca_dev->dev, valL, 0x93);
6304 reg_w_i(gspca_dev->dev, valH, 0x94); 6309 reg_w_i(gspca_dev->dev, valH, 0x94);
6305 reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */ 6310 reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */
6306 msleep(5); 6311 msleep(15);
6307 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 6312 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
6308 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)", 6313 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
6309 reg, valH, valL, retbyte); 6314 reg, valH, valL, retbyte);
@@ -6346,30 +6351,35 @@ static void setmatrix(struct gspca_dev *gspca_dev)
6346 {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; 6351 {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
6347 static const __u8 ov7620_matrix[9] = 6352 static const __u8 ov7620_matrix[9] =
6348 {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58}; 6353 {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58};
6354 static const __u8 pas202b_matrix[9] =
6355 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
6349 static const __u8 po2030_matrix[9] = 6356 static const __u8 po2030_matrix[9] =
6350 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; 6357 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
6351 static const __u8 vf0250_matrix[9] = 6358 static const __u8 vf0250_matrix[9] =
6352 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; 6359 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
6360 static const __u8 *matrix_tb[SENSOR_MAX] = {
6361 NULL, /* SENSOR_CS2102 0 */
6362 NULL, /* SENSOR_CS2102K 1 */
6363 gc0305_matrix, /* SENSOR_GC0305 2 */
6364 NULL, /* SENSOR_HDCS2020b 3 */
6365 NULL, /* SENSOR_HV7131B 4 */
6366 NULL, /* SENSOR_HV7131C 5 */
6367 NULL, /* SENSOR_ICM105A 6 */
6368 NULL, /* SENSOR_MC501CB 7 */
6369 ov7620_matrix, /* SENSOR_OV7620 8 */
6370 NULL, /* SENSOR_OV7630C 9 */
6371 NULL, /* SENSOR_PAS106 10 */
6372 pas202b_matrix, /* SENSOR_PAS202B 11 */
6373 NULL, /* SENSOR_PB0330 12 */
6374 po2030_matrix, /* SENSOR_PO2030 13 */
6375 NULL, /* SENSOR_TAS5130CK 14 */
6376 NULL, /* SENSOR_TAS5130CXX 15 */
6377 vf0250_matrix, /* SENSOR_TAS5130C_VF0250 16 */
6378 };
6353 6379
6354 switch (sd->sensor) { 6380 matrix = matrix_tb[sd->sensor];
6355 case SENSOR_GC0305: 6381 if (matrix == NULL)
6356 matrix = gc0305_matrix; 6382 return; /* matrix already loaded */
6357 break;
6358 case SENSOR_MC501CB:
6359 return; /* no matrix? */
6360 case SENSOR_OV7620:
6361/* case SENSOR_OV7648: */
6362 matrix = ov7620_matrix;
6363 break;
6364 case SENSOR_PO2030:
6365 matrix = po2030_matrix;
6366 break;
6367 case SENSOR_TAS5130C_VF0250:
6368 matrix = vf0250_matrix;
6369 break;
6370 default: /* matrix already loaded */
6371 return;
6372 }
6373 for (i = 0; i < ARRAY_SIZE(ov7620_matrix); i++) 6383 for (i = 0; i < ARRAY_SIZE(ov7620_matrix); i++)
6374 reg_w(gspca_dev->dev, matrix[i], 0x010a + i); 6384 reg_w(gspca_dev->dev, matrix[i], 0x010a + i);
6375} 6385}
@@ -6585,42 +6595,42 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6585 {gc0305_NoFliker, gc0305_NoFliker, 6595 {gc0305_NoFliker, gc0305_NoFliker,
6586 gc0305_50HZ, gc0305_50HZ, 6596 gc0305_50HZ, gc0305_50HZ,
6587 gc0305_60HZ, gc0305_60HZ}, 6597 gc0305_60HZ, gc0305_60HZ},
6588/* SENSOR_HDCS2020 3 */ 6598/* SENSOR_HDCS2020b 3 */
6589 {NULL, NULL,
6590 NULL, NULL,
6591 NULL, NULL},
6592/* SENSOR_HDCS2020b 4 */
6593 {hdcs2020b_NoFliker, hdcs2020b_NoFliker, 6599 {hdcs2020b_NoFliker, hdcs2020b_NoFliker,
6594 hdcs2020b_50HZ, hdcs2020b_50HZ, 6600 hdcs2020b_50HZ, hdcs2020b_50HZ,
6595 hdcs2020b_60HZ, hdcs2020b_60HZ}, 6601 hdcs2020b_60HZ, hdcs2020b_60HZ},
6596/* SENSOR_HV7131B 5 */ 6602/* SENSOR_HV7131B 4 */
6603 {hv7131b_NoFlikerScale, hv7131b_NoFliker,
6604 hv7131b_50HZScale, hv7131b_50HZ,
6605 hv7131b_60HZScale, hv7131b_60HZ},
6606/* SENSOR_HV7131C 5 */
6597 {NULL, NULL, 6607 {NULL, NULL,
6598 NULL, NULL, 6608 NULL, NULL,
6599 NULL, NULL}, 6609 NULL, NULL},
6600/* SENSOR_HV7131C 6 */ 6610/* SENSOR_ICM105A 6 */
6601 {NULL, NULL,
6602 NULL, NULL,
6603 NULL, NULL},
6604/* SENSOR_ICM105A 7 */
6605 {icm105a_NoFliker, icm105a_NoFlikerScale, 6611 {icm105a_NoFliker, icm105a_NoFlikerScale,
6606 icm105a_50HZ, icm105a_50HZScale, 6612 icm105a_50HZ, icm105a_50HZScale,
6607 icm105a_60HZ, icm105a_60HZScale}, 6613 icm105a_60HZ, icm105a_60HZScale},
6608/* SENSOR_MC501CB 8 */ 6614/* SENSOR_MC501CB 7 */
6609 {MC501CB_NoFliker, MC501CB_NoFlikerScale, 6615 {MC501CB_NoFliker, MC501CB_NoFlikerScale,
6610 MC501CB_50HZ, MC501CB_50HZScale, 6616 MC501CB_50HZ, MC501CB_50HZScale,
6611 MC501CB_60HZ, MC501CB_60HZScale}, 6617 MC501CB_60HZ, MC501CB_60HZScale},
6612/* SENSOR_OV7620 9 */ 6618/* SENSOR_OV7620 8 */
6613 {OV7620_NoFliker, OV7620_NoFliker, 6619 {OV7620_NoFliker, OV7620_NoFliker,
6614 OV7620_50HZ, OV7620_50HZ, 6620 OV7620_50HZ, OV7620_50HZ,
6615 OV7620_60HZ, OV7620_60HZ}, 6621 OV7620_60HZ, OV7620_60HZ},
6616/* SENSOR_OV7630C 10 */ 6622/* SENSOR_OV7630C 9 */
6617 {NULL, NULL, 6623 {NULL, NULL,
6618 NULL, NULL, 6624 NULL, NULL,
6619 NULL, NULL}, 6625 NULL, NULL},
6620/* SENSOR_PAS106 11 */ 6626/* SENSOR_PAS106 10 */
6621 {pas106b_NoFliker, pas106b_NoFliker, 6627 {pas106b_NoFliker, pas106b_NoFliker,
6622 pas106b_50HZ, pas106b_50HZ, 6628 pas106b_50HZ, pas106b_50HZ,
6623 pas106b_60HZ, pas106b_60HZ}, 6629 pas106b_60HZ, pas106b_60HZ},
6630/* SENSOR_PAS202B 11 */
6631 {pas202b_NoFlikerScale, pas202b_NoFliker,
6632 pas202b_50HZScale, pas202b_50HZ,
6633 pas202b_60HZScale, pas202b_60HZ},
6624/* SENSOR_PB0330 12 */ 6634/* SENSOR_PB0330 12 */
6625 {pb0330_NoFliker, pb0330_NoFlikerScale, 6635 {pb0330_NoFliker, pb0330_NoFlikerScale,
6626 pb0330_50HZ, pb0330_50HZScale, 6636 pb0330_50HZ, pb0330_50HZScale,
@@ -7002,15 +7012,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
7002 5, /* SENSOR_CS2102 0 */ 7012 5, /* SENSOR_CS2102 0 */
7003 5, /* SENSOR_CS2102K 1 */ 7013 5, /* SENSOR_CS2102K 1 */
7004 4, /* SENSOR_GC0305 2 */ 7014 4, /* SENSOR_GC0305 2 */
7005 4, /* SENSOR_HDCS2020 3 */ 7015 4, /* SENSOR_HDCS2020b 3 */
7006 4, /* SENSOR_HDCS2020b 4 */ 7016 4, /* SENSOR_HV7131B 4 */
7007 4, /* SENSOR_HV7131B 5 */ 7017 4, /* SENSOR_HV7131C 5 */
7008 4, /* SENSOR_HV7131C 6 */ 7018 4, /* SENSOR_ICM105A 6 */
7009 4, /* SENSOR_ICM105A 7 */ 7019 4, /* SENSOR_MC501CB 7 */
7010 4, /* SENSOR_MC501CB 8 */ 7020 3, /* SENSOR_OV7620 8 */
7011 3, /* SENSOR_OV7620 9 */ 7021 4, /* SENSOR_OV7630C 9 */
7012 4, /* SENSOR_OV7630C 10 */ 7022 4, /* SENSOR_PAS106 10 */
7013 4, /* SENSOR_PAS106 11 */ 7023 4, /* SENSOR_PAS202B 11 */
7014 4, /* SENSOR_PB0330 12 */ 7024 4, /* SENSOR_PB0330 12 */
7015 4, /* SENSOR_PO2030 13 */ 7025 4, /* SENSOR_PO2030 13 */
7016 4, /* SENSOR_TAS5130CK 14 */ 7026 4, /* SENSOR_TAS5130CK 14 */
@@ -7066,8 +7076,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
7066 sd->sensor = SENSOR_ICM105A; 7076 sd->sensor = SENSOR_ICM105A;
7067 break; 7077 break;
7068 case 0x0e: 7078 case 0x0e:
7069 PDEBUG(D_PROBE, "Find Sensor HDCS2020"); 7079 PDEBUG(D_PROBE, "Find Sensor PAS202B");
7070 sd->sensor = SENSOR_HDCS2020; 7080 sd->sensor = SENSOR_PAS202B;
7071 sd->sharpness = 1; 7081 sd->sharpness = 1;
7072 break; 7082 break;
7073 case 0x0f: 7083 case 0x0f:
@@ -7153,7 +7163,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
7153 sd->gamma = gamma[(int) sd->sensor]; 7163 sd->gamma = gamma[(int) sd->sensor];
7154 sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; 7164 sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
7155 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; 7165 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
7156 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
7157 7166
7158 switch (sd->sensor) { 7167 switch (sd->sensor) {
7159 case SENSOR_GC0305: 7168 case SENSOR_GC0305:
@@ -7161,7 +7170,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
7161 case SENSOR_PO2030: 7170 case SENSOR_PO2030:
7162 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); 7171 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
7163 break; 7172 break;
7164 case SENSOR_HDCS2020:
7165 case SENSOR_HV7131B: 7173 case SENSOR_HV7131B:
7166 case SENSOR_HV7131C: 7174 case SENSOR_HV7131C:
7167 case SENSOR_OV7630C: 7175 case SENSOR_OV7630C:
@@ -7191,15 +7199,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
7191 {cs2102_InitialScale, cs2102_Initial}, /* 0 */ 7199 {cs2102_InitialScale, cs2102_Initial}, /* 0 */
7192 {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */ 7200 {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */
7193 {gc0305_Initial, gc0305_InitialScale}, /* 2 */ 7201 {gc0305_Initial, gc0305_InitialScale}, /* 2 */
7194 {hdcs2020xx_InitialScale, hdcs2020xx_Initial}, /* 3 */ 7202 {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 3 */
7195 {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */ 7203 {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 4 */
7196 {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */ 7204 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 5 */
7197 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ 7205 {icm105axx_InitialScale, icm105axx_Initial}, /* 6 */
7198 {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ 7206 {MC501CB_InitialScale, MC501CB_Initial}, /* 7 */
7199 {MC501CB_InitialScale, MC501CB_Initial}, /* 9 */ 7207 {OV7620_mode0, OV7620_mode1}, /* 8 */
7200 {OV7620_mode0, OV7620_mode1}, /* 9 */ 7208 {ov7630c_InitialScale, ov7630c_Initial}, /* 9 */
7201 {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ 7209 {pas106b_InitialScale, pas106b_Initial}, /* 10 */
7202 {pas106b_InitialScale, pas106b_Initial}, /* 11 */ 7210 {pas202b_Initial, pas202b_InitialScale}, /* 11 */
7203 {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */ 7211 {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */
7204/* or {pb03303x_InitialScale, pb03303x_Initial}, */ 7212/* or {pb03303x_InitialScale, pb03303x_Initial}, */
7205 {PO2030_mode0, PO2030_mode1}, /* 13 */ 7213 {PO2030_mode0, PO2030_mode1}, /* 13 */
@@ -7256,6 +7264,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
7256 reg_r(gspca_dev, 0x0008); 7264 reg_r(gspca_dev, 0x0008);
7257 reg_w(dev, 0x00, 0x0008); 7265 reg_w(dev, 0x00, 0x0008);
7258 break; 7266 break;
7267 case SENSOR_PAS202B:
7259 case SENSOR_GC0305: 7268 case SENSOR_GC0305:
7260 reg_r(gspca_dev, 0x0008); 7269 reg_r(gspca_dev, 0x0008);
7261 /* fall thru */ 7270 /* fall thru */
@@ -7269,7 +7278,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
7269 switch (sd->sensor) { 7278 switch (sd->sensor) {
7270 case SENSOR_CS2102: /* gamma set in xxx_Initial */ 7279 case SENSOR_CS2102: /* gamma set in xxx_Initial */
7271 case SENSOR_CS2102K: 7280 case SENSOR_CS2102K:
7272 case SENSOR_HDCS2020:
7273 case SENSOR_HDCS2020b: 7281 case SENSOR_HDCS2020b:
7274 case SENSOR_PB0330: /* pb with chip_revision - see above */ 7282 case SENSOR_PB0330: /* pb with chip_revision - see above */
7275 case SENSOR_OV7630C: 7283 case SENSOR_OV7630C:
@@ -7282,6 +7290,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
7282 setmatrix(gspca_dev); /* one more time? */ 7290 setmatrix(gspca_dev); /* one more time? */
7283 switch (sd->sensor) { 7291 switch (sd->sensor) {
7284 case SENSOR_OV7620: 7292 case SENSOR_OV7620:
7293 case SENSOR_PAS202B:
7285 reg_r(gspca_dev, 0x0180); /* from win */ 7294 reg_r(gspca_dev, 0x0180); /* from win */
7286 reg_w(dev, 0x00, 0x0180); 7295 reg_w(dev, 0x00, 0x0180);
7287 break; 7296 break;
@@ -7293,37 +7302,29 @@ static int sd_start(struct gspca_dev *gspca_dev)
7293 7302
7294 switch (sd->sensor) { 7303 switch (sd->sensor) {
7295 case SENSOR_GC0305: 7304 case SENSOR_GC0305:
7296 case SENSOR_OV7620:
7297 reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ 7305 reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
7298 reg_w(dev, 0x15, 0x01ae); 7306 reg_w(dev, 0x15, 0x01ae);
7299 sd->autogain = 0; 7307 /* fall thru */
7300 break; 7308 case SENSOR_PAS202B:
7301 case SENSOR_PO2030: 7309 case SENSOR_PO2030:
7302 reg_w(dev, 0x40, 0x0117); /* (from win traces) */ 7310/* reg_w(dev, 0x40, ZC3XX_R117_GGAIN); * (from win traces) */
7303 reg_r(gspca_dev, 0x0180); 7311 reg_r(gspca_dev, 0x0180);
7304 break; 7312 break;
7305 }
7306
7307 setautogain(gspca_dev);
7308 switch (sd->sensor) {
7309 case SENSOR_GC0305:
7310/* setlightfreq(gspca_dev); ?? (end: 80 -> [18d]) */
7311 reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
7312 reg_w(dev, 0x15, 0x01ae);
7313 reg_w(dev, 0x40, 0x0180);
7314 reg_w(dev, 0x40, 0x0117);
7315 reg_r(gspca_dev, 0x0180);
7316 sd->autogain = 1;
7317 setautogain(gspca_dev);
7318 break;
7319 case SENSOR_OV7620: 7313 case SENSOR_OV7620:
7314 reg_w(dev, 0x09, 0x01ad);
7315 reg_w(dev, 0x15, 0x01ae);
7320 i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */ 7316 i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */
7321 i2c_write(gspca_dev, 0x13, 0xa3, 0x00); 7317 i2c_write(gspca_dev, 0x13, 0xa3, 0x00);
7322 /*fixme: returned value to send? */ 7318 /*fixme: returned value to send? */
7323 reg_w(dev, 0x40, 0x0117); /* (from win traces) */ 7319 reg_w(dev, 0x40, 0x0117);
7324 reg_r(gspca_dev, 0x0180); 7320 reg_r(gspca_dev, 0x0180);
7325 setautogain(gspca_dev); 7321 break;
7326 msleep(500); 7322 }
7323
7324 setautogain(gspca_dev);
7325 switch (sd->sensor) {
7326 case SENSOR_PAS202B:
7327 reg_w(dev, 0x00, 0x0007); /* (from win traces) */
7327 break; 7328 break;
7328 case SENSOR_PO2030: 7329 case SENSOR_PO2030:
7329 msleep(500); 7330 msleep(500);
@@ -7333,6 +7334,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
7333 reg_w(dev, 0x02, 0x0008); 7334 reg_w(dev, 0x02, 0x0008);
7334 break; 7335 break;
7335 } 7336 }
7337 if (sd->sensor == SENSOR_PAS202B)
7338 reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
7336 return 0; 7339 return 0;
7337} 7340}
7338 7341
@@ -7530,6 +7533,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
7530 {USB_DEVICE(0x0458, 0x700c)}, 7533 {USB_DEVICE(0x0458, 0x700c)},
7531 {USB_DEVICE(0x0458, 0x700f)}, 7534 {USB_DEVICE(0x0458, 0x700f)},
7532 {USB_DEVICE(0x0461, 0x0a00)}, 7535 {USB_DEVICE(0x0461, 0x0a00)},
7536 {USB_DEVICE(0x046d, 0x089d), .driver_info = SENSOR_MC501CB},
7533 {USB_DEVICE(0x046d, 0x08a0)}, 7537 {USB_DEVICE(0x046d, 0x08a0)},
7534 {USB_DEVICE(0x046d, 0x08a1)}, 7538 {USB_DEVICE(0x046d, 0x08a1)},
7535 {USB_DEVICE(0x046d, 0x08a2)}, 7539 {USB_DEVICE(0x046d, 0x08a2)},