diff options
Diffstat (limited to 'drivers/media/video/gspca')
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 | ||
18 | if USB_GSPCA && VIDEO_V4L2 | 18 | if USB_GSPCA && VIDEO_V4L2 |
19 | 19 | ||
20 | source "drivers/media/video/gspca/m5602/Kconfig" | 20 | source "drivers/media/video/gspca/m5602/Kconfig" |
21 | source "drivers/media/video/gspca/stv06xx/Kconfig" | ||
21 | 22 | ||
22 | config USB_GSPCA_CONEX | 23 | config 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 | ||
68 | config 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 | |||
67 | config USB_GSPCA_PAC207 | 78 | config 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 | ||
85 | config USB_GSPCA_SONIXB | 96 | config 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 | ||
176 | config USB_GSPCA_T613 | 189 | config 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 | |||
4 | obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o | 4 | obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o |
5 | obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o | 5 | obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o |
6 | obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o | 6 | obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o |
7 | obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o | ||
7 | obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o | 8 | obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o |
8 | obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o | 9 | obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o |
9 | obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o | 10 | obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o |
@@ -27,6 +28,7 @@ gspca_etoms-objs := etoms.o | |||
27 | gspca_finepix-objs := finepix.o | 28 | gspca_finepix-objs := finepix.o |
28 | gspca_mars-objs := mars.o | 29 | gspca_mars-objs := mars.o |
29 | gspca_ov519-objs := ov519.o | 30 | gspca_ov519-objs := ov519.o |
31 | gspca_ov534-objs := ov534.o | ||
30 | gspca_pac207-objs := pac207.o | 32 | gspca_pac207-objs := pac207.o |
31 | gspca_pac7311-objs := pac7311.o | 33 | gspca_pac7311-objs := pac7311.o |
32 | gspca_sonixb-objs := sonixb.o | 34 | gspca_sonixb-objs := sonixb.o |
@@ -45,4 +47,4 @@ gspca_vc032x-objs := vc032x.o | |||
45 | gspca_zc3xx-objs := zc3xx.o | 47 | gspca_zc3xx-objs := zc3xx.o |
46 | 48 | ||
47 | obj-$(CONFIG_USB_M5602) += m5602/ | 49 | obj-$(CONFIG_USB_M5602) += m5602/ |
48 | 50 | obj-$(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 | ||
96 | static struct v4l2_pix_format vga_mode[] = { | 96 | static 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 | ||
115 | static struct v4l2_pix_format vga_mode[] = { | 115 | static 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 | ||
128 | static struct v4l2_pix_format sif_mode[] = { | 128 | static 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. */ |
75 | static struct v4l2_pix_format fpix_mode[1] = { | 75 | static 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>"); | |||
45 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 44 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
46 | MODULE_LICENSE("GPL"); | 45 | MODULE_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 | ||
50 | static int video_nr = -1; | 49 | static 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) | |||
645 | static void gspca_stream_off(struct gspca_dev *gspca_dev) | 669 | static 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 | ||
849 | static void gspca_delete(struct kref *kref) | 868 | static 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?*/ | ||
1071 | static 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 | |||
1079 | static 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 | |||
1087 | static 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 | |||
1056 | static int vidioc_querymenu(struct file *file, void *priv, | 1099 | static 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; |
1241 | out: | 1281 | out: |
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 | } |
1469 | ok: | 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 */ |
57 | struct cam { | 57 | struct 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 *); | |||
70 | typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); | 74 | typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); |
71 | typedef int (*cam_jpg_op) (struct gspca_dev *, | 75 | typedef int (*cam_jpg_op) (struct gspca_dev *, |
72 | struct v4l2_jpegcompression *); | 76 | struct v4l2_jpegcompression *); |
77 | typedef int (*cam_streamparm_op) (struct gspca_dev *, | ||
78 | struct v4l2_streamparm *); | ||
73 | typedef int (*cam_qmnu_op) (struct gspca_dev *, | 79 | typedef int (*cam_qmnu_op) (struct gspca_dev *, |
74 | struct v4l2_querymenu *); | 80 | struct v4l2_querymenu *); |
75 | typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, | 81 | typedef 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 | ||
122 | struct gspca_dev { | 130 | struct 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 */ | ||
119 | struct sd { | 112 | struct sd { |
120 | struct gspca_dev gspca_dev; | 113 | struct gspca_dev gspca_dev; |
121 | 114 | ||
@@ -140,4 +133,10 @@ int m5602_read_bridge( | |||
140 | int m5602_write_bridge( | 133 | int m5602_write_bridge( |
141 | struct sd *sd, u8 address, u8 i2c_data); | 134 | struct sd *sd, u8 address, u8 i2c_data); |
142 | 135 | ||
136 | int m5602_write_sensor(struct sd *sd, const u8 address, | ||
137 | u8 *i2c_data, const u8 len); | ||
138 | |||
139 | int 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 */ |
26 | int force_sensor; | 26 | int force_sensor; |
27 | int dump_bridge; | 27 | static int dump_bridge; |
28 | int dump_sensor; | 28 | int dump_sensor; |
29 | 29 | ||
30 | static const __devinitdata struct usb_device_id m5602_table[] = { | 30 | static 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 | ||
83 | int 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 | } | ||
126 | out: | ||
127 | return err; | ||
128 | } | ||
129 | |||
130 | int 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 */ |
85 | static void m5602_dump_bridge(struct sd *sd) | 176 | static 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 | |||
287 | static void __exit mod_m5602_exit(void) | 383 | static 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 | ||
21 | static void mt9m111_dump_registers(struct sd *sd); | ||
22 | |||
21 | int mt9m111_probe(struct sd *sd) | 23 | int 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 | ||
115 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 117 | int 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); |
135 | out: | 137 | out: |
136 | return (err < 0) ? err : 0; | 138 | return err; |
137 | } | 139 | } |
138 | 140 | ||
139 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 141 | int 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 | ||
153 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 155 | int 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); |
173 | out: | 175 | out: |
174 | return (err < 0) ? err : 0; | 176 | return err; |
175 | } | 177 | } |
176 | 178 | ||
177 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 179 | int 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 | ||
196 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 198 | int 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); |
230 | out: | 232 | out: |
231 | return (err < 0) ? err : 0; | 233 | return err; |
232 | } | ||
233 | |||
234 | int 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 | } | ||
263 | out: | ||
264 | return (err < 0) ? err : 0; | ||
265 | } | ||
266 | |||
267 | int 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 | ||
311 | void mt9m111_dump_registers(struct sd *sd) | 236 | static 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); | |||
87 | int mt9m111_init(struct sd *sd); | 87 | int mt9m111_init(struct sd *sd); |
88 | int mt9m111_power_down(struct sd *sd); | 88 | int mt9m111_power_down(struct sd *sd); |
89 | 89 | ||
90 | int mt9m111_read_sensor(struct sd *sd, const u8 address, | ||
91 | u8 *i2c_data, const u8 len); | ||
92 | |||
93 | int mt9m111_write_sensor(struct sd *sd, const u8 address, | ||
94 | u8 *i2c_data, const u8 len); | ||
95 | |||
96 | void mt9m111_dump_registers(struct sd *sd); | ||
97 | |||
98 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 90 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); |
99 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | 91 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); |
100 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | 92 | int 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 | ||
21 | int 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 | { | 23 | static |
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", | |
49 | int 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; | 71 | static void ov9650_dump_registers(struct sd *sd); |
91 | } | ||
92 | 72 | ||
93 | int ov9650_probe(struct sd *sd) | 73 | int 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 | |||
145 | int 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 | ||
166 | int ov9650_power_down(struct sd *sd) | 201 | int 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 | ||
181 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 217 | int 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); |
203 | out: | 239 | out: |
204 | return (err < 0) ? err : 0; | 240 | return err; |
205 | } | 241 | } |
206 | 242 | ||
207 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 243 | int 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 | ||
234 | out: | 270 | out: |
235 | return (err < 0) ? err : 0; | 271 | return err; |
236 | } | 272 | } |
237 | 273 | ||
238 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 274 | int 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 | ||
253 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 289 | int 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 | ||
274 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 310 | int 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 | ||
288 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 324 | int 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 | ||
303 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 339 | int 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 | ||
317 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 353 | int 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 | ||
332 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 368 | int 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 | ||
348 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 384 | int 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); |
367 | out: | 403 | out: |
368 | return (err < 0) ? err : 0; | 404 | return err; |
369 | } | 405 | } |
370 | 406 | ||
371 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 407 | int 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 | ||
387 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 423 | int 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); |
406 | out: | 442 | out: |
407 | return (err < 0) ? err : 0; | 443 | return err; |
408 | } | 444 | } |
409 | 445 | ||
410 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 446 | int 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); |
424 | out: | 460 | out: |
425 | return (err < 0) ? err : 0; | 461 | return err; |
426 | } | 462 | } |
427 | 463 | ||
428 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 464 | int 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 | ||
452 | out: | 488 | out: |
453 | return (err < 0) ? err : 0; | 489 | return err; |
454 | } | 490 | } |
455 | 491 | ||
456 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | 492 | int 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 | ||
469 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | 505 | int 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); |
482 | out: | 518 | out: |
483 | return (err < 0) ? err : 0; | 519 | return err; |
484 | } | 520 | } |
485 | 521 | ||
486 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | 522 | int 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 | ||
499 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | 535 | int 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); |
512 | out: | 548 | out: |
513 | return (err < 0) ? err : 0; | 549 | return err; |
514 | } | 550 | } |
515 | 551 | ||
516 | void ov9650_dump_registers(struct sd *sd) | 552 | static 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 | ||
125 | int ov9650_probe(struct sd *sd); | 129 | int ov9650_probe(struct sd *sd); |
126 | int ov9650_init(struct sd *sd); | 130 | int ov9650_init(struct sd *sd); |
131 | int ov9650_start(struct sd *sd); | ||
127 | int ov9650_power_down(struct sd *sd); | 132 | int ov9650_power_down(struct sd *sd); |
128 | 133 | ||
129 | int ov9650_read_sensor(struct sd *sd, const u8 address, | ||
130 | u8 *i2c_data, const u8 len); | ||
131 | int ov9650_write_sensor(struct sd *sd, const u8 address, | ||
132 | u8 *i2c_data, const u8 len); | ||
133 | |||
134 | void ov9650_dump_registers(struct sd *sd); | ||
135 | |||
136 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 134 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); |
137 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | 135 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); |
138 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | 136 | int 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); | |||
155 | static struct m5602_sensor ov9650 = { | 153 | static 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 | ||
446 | static const unsigned char power_down_ov9650[][3] = | 444 | static 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 | 464 | static const unsigned char res_init_ov9650[][2] = |
467 | where the sensor is mounted upside down */ | 465 | { |
468 | static | 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") | 473 | static 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."), | 493 | static 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 | |||
513 | static 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 | ||
21 | static void po1030_dump_registers(struct sd *sd); | ||
22 | |||
21 | int po1030_probe(struct sd *sd) | 23 | int 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 | ||
67 | int 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 | |||
91 | int 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 | |||
133 | int po1030_init(struct sd *sd) | 69 | int 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 | ||
172 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 102 | int 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); |
189 | out: | 119 | out: |
190 | return (err < 0) ? err : 0; | 120 | return err; |
191 | } | 121 | } |
192 | 122 | ||
193 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 123 | int 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 | ||
216 | out: | 146 | out: |
217 | return (err < 0) ? err : 0; | 147 | return err; |
218 | } | 148 | } |
219 | 149 | ||
220 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 150 | int 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 | ||
234 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 164 | int 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 | ||
250 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 180 | int 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; | 196 | out: |
197 | return err; | ||
264 | } | 198 | } |
265 | 199 | ||
266 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 200 | int 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 | ||
282 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 216 | int 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; | 232 | out: |
233 | return err; | ||
296 | } | 234 | } |
297 | 235 | ||
298 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 236 | int 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 | ||
311 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 249 | int 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 | ||
324 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 262 | int 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 | ||
337 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 275 | int 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 | ||
351 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 289 | int 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 | ||
364 | int po1030_power_down(struct sd *sd) | 302 | int 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 | ||
369 | void po1030_dump_registers(struct sd *sd) | 307 | static 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); | |||
128 | int po1030_init(struct sd *sd); | 128 | int po1030_init(struct sd *sd); |
129 | int po1030_power_down(struct sd *sd); | 129 | int po1030_power_down(struct sd *sd); |
130 | 130 | ||
131 | void po1030_dump_registers(struct sd *sd); | ||
132 | |||
133 | int po1030_read_sensor(struct sd *sd, const u8 address, | ||
134 | u8 *i2c_data, const u8 len); | ||
135 | int po1030_write_sensor(struct sd *sd, const u8 address, | ||
136 | u8 *i2c_data, const u8 len); | ||
137 | |||
138 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | 131 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); |
139 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 132 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); |
140 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | 133 | int 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 | ||
21 | static | ||
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 | |||
53 | static void s5k4aa_dump_registers(struct sd *sd); | ||
54 | |||
21 | int s5k4aa_probe(struct sd *sd) | 55 | int 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 | |||
78 | sensor_found: | 113 | sensor_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 | ||
87 | int 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 | } | ||
123 | out: | ||
124 | return (err < 0) ? err : 0; | ||
125 | } | ||
126 | |||
127 | int 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 | |||
171 | int s5k4aa_init(struct sd *sd) | 122 | int 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); |
252 | out: | 203 | out: |
253 | return (err < 0) ? err : 0; | 204 | return err; |
254 | } | 205 | } |
255 | 206 | ||
256 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 207 | int 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); |
272 | out: | 223 | out: |
273 | return (err < 0) ? err : 0; | 224 | return err; |
274 | } | 225 | } |
275 | 226 | ||
276 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 227 | int 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 | ||
290 | out: | 241 | out: |
291 | return (err < 0) ? err : 0; | 242 | return err; |
292 | } | 243 | } |
293 | 244 | ||
294 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 245 | int 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 | } |
328 | out: | 279 | out: |
329 | return (err < 0) ? err : 0; | 280 | return err; |
330 | } | 281 | } |
331 | 282 | ||
332 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 283 | int 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); |
345 | out: | 296 | out: |
346 | return (err < 0) ? err : 0; | 297 | return err; |
347 | } | 298 | } |
348 | 299 | ||
349 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 300 | int 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 | } |
384 | out: | 335 | out: |
385 | return (err < 0) ? err : 0; | 336 | return err; |
386 | } | 337 | } |
387 | 338 | ||
388 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 339 | int 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 | ||
402 | out: | 353 | out: |
403 | return (err < 0) ? err : 0; | 354 | return err; |
404 | } | 355 | } |
405 | 356 | ||
406 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 357 | int 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 | ||
420 | out: | 371 | out: |
421 | return (err < 0) ? err : 0; | 372 | return err; |
422 | } | 373 | } |
423 | 374 | ||
424 | void s5k4aa_dump_registers(struct sd *sd) | 375 | static 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); | |||
68 | int s5k4aa_init(struct sd *sd); | 67 | int s5k4aa_init(struct sd *sd); |
69 | int s5k4aa_power_down(struct sd *sd); | 68 | int s5k4aa_power_down(struct sd *sd); |
70 | 69 | ||
71 | void s5k4aa_dump_registers(struct sd *sd); | ||
72 | |||
73 | int s5k4aa_read_sensor(struct sd *sd, const u8 address, | ||
74 | u8 *i2c_data, const u8 len); | ||
75 | int s5k4aa_write_sensor(struct sd *sd, const u8 address, | ||
76 | u8 *i2c_data, const u8 len); | ||
77 | |||
78 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | 70 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); |
79 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 71 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); |
80 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | 72 | int 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 | ||
341 | static | ||
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 | ||
21 | static void s5k83a_dump_registers(struct sd *sd); | ||
22 | |||
21 | int s5k83a_probe(struct sd *sd) | 23 | int 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 | ||
71 | int 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 | |||
108 | out: | ||
109 | return (err < 0) ? err : 0; | ||
110 | } | ||
111 | |||
112 | int 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 | |||
156 | int s5k83a_init(struct sd *sd) | 73 | int 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 | ||
241 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 158 | int 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; | 171 | out: |
172 | return err; | ||
252 | } | 173 | } |
253 | 174 | ||
254 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 175 | int 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; | 199 | out: |
200 | return err; | ||
279 | } | 201 | } |
280 | 202 | ||
281 | int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) | 203 | int 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 | |
215 | out: | ||
216 | return err; | ||
291 | } | 217 | } |
292 | 218 | ||
293 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) | 219 | int 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 | ||
305 | int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 231 | int 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; | 247 | out: |
248 | return err; | ||
320 | } | 249 | } |
321 | 250 | ||
322 | int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 251 | int 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 | ||
335 | int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 263 | int 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; | 277 | out: |
278 | return err; | ||
350 | } | 279 | } |
351 | 280 | ||
352 | int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 281 | int 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; | 306 | out: |
307 | return err; | ||
378 | } | 308 | } |
379 | 309 | ||
380 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 310 | int 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; | 324 | out: |
325 | return err; | ||
395 | } | 326 | } |
396 | 327 | ||
397 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 328 | int 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 | 352 | out: | |
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); | |||
46 | int s5k83a_init(struct sd *sd); | 46 | int s5k83a_init(struct sd *sd); |
47 | int s5k83a_power_down(struct sd *sd); | 47 | int s5k83a_power_down(struct sd *sd); |
48 | 48 | ||
49 | void s5k83a_dump_registers(struct sd *sd); | ||
50 | |||
51 | int s5k83a_read_sensor(struct sd *sd, const u8 address, | ||
52 | u8 *i2c_data, const u8 len); | ||
53 | int s5k83a_write_sensor(struct sd *sd, const u8 address, | ||
54 | u8 *i2c_data, const u8 len); | ||
55 | |||
56 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | 49 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); |
57 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | 50 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); |
58 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val); | 51 | int 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); | |||
64 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | 57 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); |
65 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | 58 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); |
66 | 59 | ||
67 | |||
68 | static struct m5602_sensor s5k83a = { | 60 | static 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 { | |||
39 | static struct ctrl sd_ctrls[] = { | 39 | static struct ctrl sd_ctrls[] = { |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static struct v4l2_pix_format vga_mode[] = { | 42 | static 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 | ||
161 | static struct v4l2_pix_format vga_mode[] = { | 167 | static 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 | }; |
173 | static struct v4l2_pix_format sif_mode[] = { | 179 | static 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 | */ |
1030 | static int init_ov_sensor(struct sd *sd) | 1036 | static 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 */ |
1286 | static void ov51x_led_control(struct sd *sd, int on) | 1288 | static 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; |
1875 | out: | 1873 | out: |
@@ -1879,8 +1877,10 @@ out: | |||
1879 | 1877 | ||
1880 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1878 | static 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 | ||
1886 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1886 | static 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 | ||
1966 | static void setcontrast(struct gspca_dev *gspca_dev) | 1961 | static 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 | ||
2014 | static void setcolors(struct gspca_dev *gspca_dev) | 2004 | static 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 | ||
2051 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 2036 | static 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 | |
2166 | MODULE_DEVICE_TABLE(usb, device_table); | 2156 | MODULE_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 | |||
42 | MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); | ||
43 | MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); | ||
44 | MODULE_LICENSE("GPL"); | ||
45 | |||
46 | /* specific webcam descriptor */ | ||
47 | struct 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 */ | ||
55 | static struct ctrl sd_ctrls[] = { | ||
56 | }; | ||
57 | |||
58 | static 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 | |||
66 | static 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 | |||
82 | static 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)? */ | ||
100 | static 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 | |||
119 | static 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 | |||
142 | static 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 | ||
154 | static 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 | |||
169 | static 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 | |||
231 | static 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 */ | ||
315 | static 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 */ | ||
350 | static 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 */ | ||
375 | static 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 */ | ||
393 | static 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 | |||
401 | static 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 | |||
410 | static 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 | |||
427 | static 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 | |||
436 | scan_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 | |||
497 | discard: | ||
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) */ | ||
504 | static 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) */ | ||
522 | static 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 */ | ||
544 | static 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 -- */ | ||
558 | static 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 | |||
565 | MODULE_DEVICE_TABLE(usb, device_table); | ||
566 | |||
567 | /* -- device connect -- */ | ||
568 | static 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 | |||
574 | static 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 -- */ | ||
586 | static 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 | |||
594 | static void __exit sd_mod_exit(void) | ||
595 | { | ||
596 | usb_deregister(&sd_driver); | ||
597 | PDEBUG(D_PROBE, "deregistered"); | ||
598 | } | ||
599 | |||
600 | module_init(sd_mod_init); | ||
601 | module_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 | ||
30 | MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); | 30 | MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>"); |
31 | MODULE_DESCRIPTION("Pixart PAC207"); | 31 | MODULE_DESCRIPTION("Pixart PAC207"); |
32 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
33 | 33 | ||
@@ -149,7 +149,7 @@ static struct ctrl sd_ctrls[] = { | |||
149 | }, | 149 | }, |
150 | }; | 150 | }; |
151 | 151 | ||
152 | static struct v4l2_pix_format sif_mode[] = { | 152 | static 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 = { | |||
529 | static const __devinitdata struct usb_device_id device_table[] = { | 529 | static 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 | ||
229 | static struct v4l2_pix_format vga_mode[] = { | 229 | static 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 | }; |
1073 | MODULE_DEVICE_TABLE(usb, device_table); | 1076 | MODULE_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 */ |
139 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 137 | static 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 | ||
232 | static struct v4l2_pix_format vga_mode[] = { | 230 | static 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 | }; |
254 | static struct v4l2_pix_format sif_mode[] = { | 252 | static 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 | ||
828 | static void do_autogain(struct gspca_dev *gspca_dev) | 826 | static 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 | |||
27 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | 29 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); |
28 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); | 30 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); |
29 | MODULE_LICENSE("GPL"); | 31 | MODULE_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); | |||
69 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 74 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
70 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 75 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); |
71 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 76 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); |
77 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
78 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
79 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
80 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
72 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 81 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); |
73 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 82 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); |
74 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | 83 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); |
75 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | 84 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); |
85 | static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val); | ||
86 | static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val); | ||
76 | 87 | ||
77 | static struct ctrl sd_ctrls[] = { | 88 | static 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 */ | ||
211 | static __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 | ||
155 | static struct v4l2_pix_format vga_mode[] = { | 228 | static 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 | ||
232 | static const __u8 sn_ov7648[] = { | 305 | static 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 | ||
243 | static const __u8 sn_ov7660[] = { | 316 | static 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 | |||
546 | static 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 | |||
472 | static const __u8 ov7660_sensor_init[][8] = { | 592 | static 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 | |||
563 | static 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 | ||
619 | static const __u8 qtable4[] = { | 681 | static 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 | ||
758 | static int probesensor(struct gspca_dev *gspca_dev) | 820 | static 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, | |||
981 | static int sd_init(struct gspca_dev *gspca_dev) | 1045 | static 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 */ | ||
1104 | static 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 */ | ||
1122 | static void setbrightness(struct gspca_dev *gspca_dev) | 1166 | static 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 */ | ||
1154 | static void setcontrast(struct gspca_dev *gspca_dev) | 1197 | static 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 | ||
1167 | static void setcolors(struct gspca_dev *gspca_dev) | 1213 | static 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 | |||
1230 | static 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 | ||
1184 | static void setautogain(struct gspca_dev *gspca_dev) | 1239 | static void setautogain(struct gspca_dev *gspca_dev) |
@@ -1195,12 +1250,18 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
1195 | 1250 | ||
1196 | static void setvflip(struct sd *sd) | 1251 | static 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 | ||
1257 | static 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 -- */ |
1205 | static int sd_start(struct gspca_dev *gspca_dev) | 1266 | static 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 | ||
1612 | static 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 | |||
1622 | static 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 | |||
1630 | static 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 | |||
1640 | static 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 | |||
1565 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | 1648 | static 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 | ||
1684 | static 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 | |||
1694 | static 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 */ |
1602 | static const struct sd_desc sd_desc = { | 1703 | static 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 | ||
114 | static struct v4l2_pix_format vga_mode[] = { | 114 | static 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 | ||
127 | static struct v4l2_pix_format sif_mode[] = { | 127 | static 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); | |||
52 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 54 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
53 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 55 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); |
54 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 56 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); |
57 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
60 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | 61 | ||
56 | static struct ctrl sd_ctrls[] = { | 62 | static 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 | ||
101 | static struct v4l2_pix_format vga_mode[] = { | 135 | static 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 */ | ||
1826 | static 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 | ||
1849 | static int write_vector(struct gspca_dev *gspca_dev, | 1860 | static 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 | ||
1877 | static void getbrightness(struct gspca_dev *gspca_dev) | 1886 | static 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 | ||
1886 | static void setcontrast(struct gspca_dev *gspca_dev) | 1890 | static void setcontrast(struct gspca_dev *gspca_dev) |
@@ -1895,7 +1899,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
1895 | 1899 | ||
1896 | static void getcontrast(struct gspca_dev *gspca_dev) | 1900 | static void getcontrast(struct gspca_dev *gspca_dev) |
1897 | { | 1901 | { |
1898 | /* spca50x->contrast = 0xaa01; */ | ||
1899 | } | 1902 | } |
1900 | 1903 | ||
1901 | static void setcolors(struct gspca_dev *gspca_dev) | 1904 | static void setcolors(struct gspca_dev *gspca_dev) |
@@ -1907,11 +1910,20 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
1907 | 1910 | ||
1908 | static void getcolors(struct gspca_dev *gspca_dev) | 1911 | static void getcolors(struct gspca_dev *gspca_dev) |
1909 | { | 1912 | { |
1913 | } | ||
1914 | |||
1915 | static 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 | |||
1922 | static 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 */ | ||
1949 | static 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; |
1952 | error: | 1973 | error: |
1953 | return -EINVAL; | 1974 | return -EINVAL; |
1954 | } | 1975 | } |
1955 | 1976 | ||
1956 | /* this function is called at probe and resume time */ | 1977 | static int sd_start(struct gspca_dev *gspca_dev) |
1957 | static 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 | |||
1983 | static 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 | ||
2130 | static 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 | |||
2140 | static 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 | |||
2148 | static 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 | |||
2158 | static 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 */ |
2117 | static const struct sd_desc sd_desc = { | 2167 | static 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 | ||
62 | static struct v4l2_pix_format vga_mode[] = { | 62 | static 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 | ||
113 | static struct v4l2_pix_format vga_mode[] = { | 113 | static 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 | ||
65 | static struct v4l2_pix_format sif_mode[] = { | 65 | static 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"); | |||
32 | struct sd { | 32 | struct 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 | ||
76 | static struct v4l2_pix_format sif_012a_mode[] = { | 76 | static 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 | ||
99 | static struct v4l2_pix_format sif_072a_mode[] = { | 99 | static 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 | ||
149 | static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value) | 149 | static 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 | |||
162 | static 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 */ | ||
176 | static 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 | |||
187 | static 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 | |||
199 | static 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 | |||
217 | static 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 | |||
240 | static 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}, | 162 | static 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 */ | 178 | static 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}, | 221 | static 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 */ | 232 | static 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 ********************/ |
439 | static const __u16 Pb100_1map8300[][2] = { | 323 | static 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 | ||
518 | static void sensor_mapwrite(struct gspca_dev *gspca_dev, | 402 | static 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 | |||
415 | static 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 */ | ||
429 | static 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 */ | ||
441 | static 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 | |||
452 | static 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 | |||
466 | static 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 | |||
486 | static 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 | |||
497 | static 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 | |||
531 | static void init_161rev12A(struct gspca_dev *gspca_dev) | 506 | static 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) | |||
598 | static int sd_init_72a(struct gspca_dev *gspca_dev) | 572 | static 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 | ||
605 | static void setcontrast(struct gspca_dev *gspca_dev) | 583 | /* rev 72a only */ |
584 | static 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 */ | ||
632 | static void setwhite(struct gspca_dev *gspca_dev) | 599 | static 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 | |||
621 | static 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 */ |
682 | static void setgain(struct gspca_dev *gspca_dev) | 674 | static 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 | ||
692 | static void setautogain(struct gspca_dev *gspca_dev) | 683 | static void setautogain(struct gspca_dev *gspca_dev) |
@@ -702,9 +693,9 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
702 | static int sd_start_12a(struct gspca_dev *gspca_dev) | 693 | static 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 */ |
903 | static 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 | |||
915 | static 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 */ | ||
933 | static 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 */ | ||
952 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 902 | static 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 */ | ||
1010 | static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val) | 957 | static 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 | ||
1122 | static struct ctrl sd_ctrls_72a[] = { | 1069 | static 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 | ||
112 | static struct v4l2_pix_format vga_mode[] = { | 112 | static 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 @@ | |||
1 | config 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 @@ | |||
1 | obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o | ||
2 | |||
3 | gspca_stv06xx-objs := stv06xx.o \ | ||
4 | stv06xx_vv6410.o \ | ||
5 | stv06xx_hdcs.o \ | ||
6 | stv06xx_pb0100.o | ||
7 | |||
8 | EXTRA_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 | |||
32 | MODULE_AUTHOR("Erik Andrén"); | ||
33 | MODULE_DESCRIPTION("STV06XX USB Camera Driver"); | ||
34 | MODULE_LICENSE("GPL"); | ||
35 | |||
36 | static int dump_bridge; | ||
37 | static int dump_sensor; | ||
38 | |||
39 | int 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 | |||
60 | int 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 */ | ||
80 | int 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 | |||
91 | static 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 | |||
109 | int 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 | |||
138 | int 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 | |||
169 | int 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 */ | ||
212 | static 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 */ | ||
243 | static 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 */ | ||
263 | static 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 | |||
276 | out: | ||
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 | |||
285 | static 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 | |||
299 | out: | ||
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 | */ | ||
318 | static 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 | |||
409 | static int stv06xx_config(struct gspca_dev *gspca_dev, | ||
410 | const struct usb_device_id *id); | ||
411 | |||
412 | /* sub-driver description */ | ||
413 | static 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 */ | ||
423 | static 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 -- */ | ||
462 | static 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 | }; | ||
468 | MODULE_DEVICE_TABLE(usb, device_table); | ||
469 | |||
470 | /* -- device connect -- */ | ||
471 | static 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 | |||
479 | static 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 | |||
490 | static 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 -- */ | ||
502 | static 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 | } | ||
509 | static void __exit sd_mod_exit(void) | ||
510 | { | ||
511 | usb_deregister(&sd_driver); | ||
512 | PDEBUG(D_PROBE, "deregistered"); | ||
513 | } | ||
514 | |||
515 | module_init(sd_mod_init); | ||
516 | module_exit(sd_mod_exit); | ||
517 | |||
518 | module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); | ||
519 | MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); | ||
520 | |||
521 | module_param(dump_sensor, bool, S_IRUGO | S_IWUSR); | ||
522 | MODULE_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 */ | ||
85 | struct 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 | |||
98 | int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data); | ||
99 | int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data); | ||
100 | |||
101 | int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len); | ||
102 | int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len); | ||
103 | |||
104 | int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value); | ||
105 | int 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 | |||
33 | enum hdcs_power_state { | ||
34 | HDCS_STATE_SLEEP, | ||
35 | HDCS_STATE_IDLE, | ||
36 | HDCS_STATE_RUN | ||
37 | }; | ||
38 | |||
39 | /* no lock? */ | ||
40 | struct 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 | |||
65 | static 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 | |||
82 | static 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 | |||
123 | static 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 | |||
139 | static 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 | |||
175 | static 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 | |||
251 | static 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 | |||
271 | static 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 | |||
289 | static 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 | |||
296 | static 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 | |||
344 | static 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 | |||
403 | static 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 | |||
447 | static 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 | |||
454 | static 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 | |||
461 | static void hdcs_disconnect(struct sd *sd) | ||
462 | { | ||
463 | PDEBUG(D_PROBE, "Disconnecting the sensor"); | ||
464 | kfree(sd->sensor_priv); | ||
465 | } | ||
466 | |||
467 | static 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 | |||
524 | static 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 | |||
130 | static int hdcs_probe_1x00(struct sd *sd); | ||
131 | static int hdcs_probe_1020(struct sd *sd); | ||
132 | static int hdcs_start(struct sd *sd); | ||
133 | static int hdcs_init(struct sd *sd); | ||
134 | static int hdcs_stop(struct sd *sd); | ||
135 | static int hdcs_dump(struct sd *sd); | ||
136 | static void hdcs_disconnect(struct sd *sd); | ||
137 | |||
138 | static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
139 | static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
140 | static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
141 | static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
142 | |||
143 | const 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 | |||
204 | const 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 | |||
235 | static 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 | |||
250 | static 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 | |||
49 | static 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 | |||
84 | static 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 | |||
129 | static 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"); | ||
142 | out: | ||
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 */ | ||
150 | static 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 | |||
215 | static int pb0100_dump(struct sd *sd) | ||
216 | { | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static 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 | |||
230 | static 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 | |||
255 | static 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 | |||
265 | static 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 | |||
287 | static 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 | |||
297 | static 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 | |||
319 | static 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 | |||
329 | static 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 | |||
345 | static 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 | |||
355 | static 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 | |||
378 | static 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 | |||
388 | static 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 | |||
412 | static 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 | |||
422 | static 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 | |||
112 | static int pb0100_probe(struct sd *sd); | ||
113 | static int pb0100_start(struct sd *sd); | ||
114 | static int pb0100_init(struct sd *sd); | ||
115 | static int pb0100_stop(struct sd *sd); | ||
116 | static int pb0100_dump(struct sd *sd); | ||
117 | |||
118 | /* V4L2 controls supported by the driver */ | ||
119 | static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
120 | static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
121 | static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
122 | static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
123 | static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
124 | static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
125 | static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
126 | static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
127 | static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
128 | static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val); | ||
129 | static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val); | ||
130 | static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val); | ||
131 | static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val); | ||
132 | static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val); | ||
133 | |||
134 | const 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 | |||
39 | extern const struct stv06xx_sensor stv06xx_sensor_vv6410; | ||
40 | extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00; | ||
41 | extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020; | ||
42 | extern const struct stv06xx_sensor stv06xx_sensor_pb0100; | ||
43 | |||
44 | #define STV06XX_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10) | ||
45 | |||
46 | struct 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 | |||
32 | static 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 | |||
55 | static 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 | |||
83 | static 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 | |||
125 | static 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 | |||
143 | static 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 | |||
157 | static 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 | |||
172 | static 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 | |||
192 | static 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 | |||
207 | static 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 | |||
227 | static 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 | |||
242 | static 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 | |||
176 | static int vv6410_probe(struct sd *sd); | ||
177 | static int vv6410_start(struct sd *sd); | ||
178 | static int vv6410_init(struct sd *sd); | ||
179 | static int vv6410_stop(struct sd *sd); | ||
180 | static int vv6410_dump(struct sd *sd); | ||
181 | |||
182 | /* V4L2 controls supported by the driver */ | ||
183 | static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
184 | static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
185 | static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
186 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
187 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
188 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
189 | |||
190 | const 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 */ | ||
259 | struct stv_init { | ||
260 | const u8 *data; | ||
261 | u16 start; | ||
262 | u8 len; | ||
263 | }; | ||
264 | |||
265 | static const u8 x1500[] = { /* 0x1500 - 0x150f */ | ||
266 | 0x0b, 0xa7, 0xb7, 0x00, 0x00 | ||
267 | }; | ||
268 | |||
269 | static const u8 x1536[] = { /* 0x1536 - 0x153b */ | ||
270 | 0x02, 0x00, 0x60, 0x01, 0x20, 0x01 | ||
271 | }; | ||
272 | |||
273 | static const u8 x15c1[] = { /* 0x15c1 - 0x15c2 */ | ||
274 | 0xff, 0x03 /* Output word 0x03ff = 1023 (ISO size) */ | ||
275 | }; | ||
276 | |||
277 | static 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 | |||
287 | static 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 | ||
126 | static struct v4l2_pix_format vga_mode[] = { | 126 | static 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 | ||
139 | static struct v4l2_pix_format custom_mode[] = { | 139 | static 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 | ||
152 | static struct v4l2_pix_format vga_mode2[] = { | 152 | static 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 | ||
236 | static struct v4l2_pix_format vga_mode_t16[] = { | 236 | static 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"); | |||
30 | struct sd { | 30 | struct 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 | ||
81 | static struct v4l2_pix_format sif_mode[] = { | 76 | static 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 -- */ |
393 | static int sd_start(struct gspca_dev *gspca_dev) | 388 | static 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 | ||
454 | static 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 | |||
486 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 455 | static 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 | ||
561 | static void setcontrast(struct gspca_dev *gspca_dev) | 487 | static 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"); | |||
32 | struct sd { | 32 | struct 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 */ |
52 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 55 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); |
53 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 56 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); |
57 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | 59 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); |
55 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | 60 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); |
61 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
62 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
56 | 63 | ||
57 | static struct ctrl sd_ctrls[] = { | 64 | static 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 | ||
89 | static struct v4l2_pix_format vc0321_mode[] = { | 129 | static 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 | }; |
101 | static struct v4l2_pix_format vc0323_mode[] = { | 141 | static 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 | ||
154 | static 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 | |||
167 | static const __u8 mi0360_matrix[9] = { | ||
168 | 0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50 | ||
169 | }; | ||
170 | |||
171 | static 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 | }; | ||
280 | static 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 | |||
114 | static const __u8 mi1310_socinitVGA_JPG[][4] = { | 400 | static 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 */ | ||
1498 | static 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 | }; | ||
1502 | static const __u8 po1200_matrix[9] = { | ||
1503 | 0x60, 0xf9, 0xe5, 0xe7, 0x50, 0x05, 0xf3, 0xe6, 0x5e | ||
1504 | }; | ||
1505 | static 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 | |||
1207 | struct sensor_info { | 1766 | struct 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 | ||
1295 | static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) | 1857 | static 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 | ||
1485 | static void setquality(struct gspca_dev *gspca_dev) | 2070 | /* for OV7660 and OV7670 only */ |
2071 | static void sethvflip(struct gspca_dev *gspca_dev) | ||
1486 | { | 2072 | { |
1487 | } | 2073 | struct sd *sd = (struct sd *) gspca_dev; |
2074 | __u8 data; | ||
1488 | 2075 | ||
1489 | static 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 | ||
1493 | static void setlightfreq(struct gspca_dev *gspca_dev) | 2099 | static 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 */ | ||
2111 | static 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 | |||
1504 | static int sd_start(struct gspca_dev *gspca_dev) | 2124 | static 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 | ||
1671 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | 2318 | static 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 | |||
2328 | static 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 | |||
2336 | static 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 | ||
1681 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | 2346 | static 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 | ||
2372 | static 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 | |||
2382 | static 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 | |||
1707 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 2390 | static 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 = { | |||
1743 | static const __devinitdata struct usb_device_id device_table[] = { | 2426 | static 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 | ||
176 | static struct v4l2_pix_format vga_mode[] = { | 176 | static 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 | ||
189 | static struct v4l2_pix_format sif_mode[] = { | 189 | static 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 !! */ | ||
1657 | static 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 | |||
1803 | static 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 | }; | ||
1945 | static const struct usb_action hdcs2020xb_Initial[] = { | 1656 | static 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}, | 2073 | static 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}, | 2098 | static 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}, | 2123 | static 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 | }; | ||
2148 | static 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 | }; | ||
2173 | static 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 | }; | ||
2198 | static 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 */ | ||
4134 | static 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 | }; | ||
4178 | static 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 | }; | ||
4222 | static 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 | }; | ||
4251 | static 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 | }; | ||
4280 | static 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 | }; | ||
4309 | static 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 | }; | ||
4338 | static 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 | }; | ||
4367 | static 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 | |||
4392 | static const struct usb_action pb03303x_Initial[] = { | 4397 | static 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 | }; |
5727 | static const struct usb_action tas5130cxx_InitialScale[] = { | 5732 | static 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)}, |