aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 17:03:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 17:03:59 -0400
commitcf2fa66055d718ae13e62451bb546505f63906a2 (patch)
treee206d3f04e74a34e9aa88d21af6c26eea21d4121 /drivers/media/video/gspca
parent4501a466f28788485604ee42641d7a5fe7258d16 (diff)
parent57f51dbc45f65f7ee1e8c8f77200bb8000e3e271 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (313 commits) V4L/DVB (9186): Added support for Prof 7300 DVB-S/S2 cards V4L/DVB (9185): S2API: Ensure we have a reasonable ROLLOFF default V4L/DVB (9184): cx24116: Change the default SNR units back to percentage by default. V4L/DVB (9183): S2API: Return error of the caller provides 0 commands. V4L/DVB (9182): S2API: Added support for DTV_HIERARCHY V4L/DVB (9181): S2API: Add support fot DTV_GUARD_INTERVAL and DTV_TRANSMISSION_MODE V4L/DVB (9180): S2API: Added support for DTV_CODE_RATE_HP/LP V4L/DVB (9179): S2API: frontend.h cleanup V4L/DVB (9178): cx24116: Add module parameter to return SNR as ESNO. V4L/DVB (9177): S2API: Change _8PSK / _16APSK to PSK_8 and APSK_16 V4L/DVB (9176): Add support for DvbWorld USB cards with STV0288 demodulator. V4L/DVB (9175): Remove NULL pointer in stb6000 driver. V4L/DVB (9174): Allow custom inittab for ST STV0288 demodulator. V4L/DVB (9173): S2API: Remove the hardcoded command limit during validation V4L/DVB (9172): S2API: Bugfix related to DVB-S / DVB-S2 tuning for the legacy API. V4L/DVB (9171): S2API: Stop an OOPS if illegal commands are dumped in S2API. V4L/DVB (9170): cx24116: Sanity checking to data input via S2API to the cx24116 demod. V4L/DVB (9169): uvcvideo: Support two new Bison Electronics webcams. V4L/DVB (9168): Add support for MSI TV@nywhere Plus remote V4L/DVB: v4l2-dev: remove duplicated #include ...
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/Kconfig215
-rw-r--r--drivers/media/video/gspca/Makefile75
-rw-r--r--drivers/media/video/gspca/conex.c3
-rw-r--r--drivers/media/video/gspca/etoms.c3
-rw-r--r--drivers/media/video/gspca/finepix.c466
-rw-r--r--drivers/media/video/gspca/gspca.c245
-rw-r--r--drivers/media/video/gspca/gspca.h21
-rw-r--r--drivers/media/video/gspca/m5602/Kconfig11
-rw-r--r--drivers/media/video/gspca/m5602/Makefile11
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h170
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c313
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c345
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h1020
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c546
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h503
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c336
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h478
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c463
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h370
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c423
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h484
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h76
-rw-r--r--drivers/media/video/gspca/mars.c20
-rw-r--r--drivers/media/video/gspca/ov519.c5
-rw-r--r--drivers/media/video/gspca/pac207.c4
-rw-r--r--drivers/media/video/gspca/pac7311.c3
-rw-r--r--drivers/media/video/gspca/sonixb.c5
-rw-r--r--drivers/media/video/gspca/sonixj.c89
-rw-r--r--drivers/media/video/gspca/spca500.c3
-rw-r--r--drivers/media/video/gspca/spca501.c3
-rw-r--r--drivers/media/video/gspca/spca505.c3
-rw-r--r--drivers/media/video/gspca/spca506.c3
-rw-r--r--drivers/media/video/gspca/spca508.c3
-rw-r--r--drivers/media/video/gspca/spca561.c10
-rw-r--r--drivers/media/video/gspca/stk014.c5
-rw-r--r--drivers/media/video/gspca/sunplus.c3
-rw-r--r--drivers/media/video/gspca/t613.c591
-rw-r--r--drivers/media/video/gspca/tv8532.c3
-rw-r--r--drivers/media/video/gspca/vc032x.c6
-rw-r--r--drivers/media/video/gspca/zc3xx.c3
40 files changed, 6904 insertions, 435 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 42b90742b40b..4d0817471c9f 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -1,13 +1,212 @@
1config USB_GSPCA 1menuconfig USB_GSPCA
2 tristate "USB GSPCA driver" 2 tristate "GSPCA based webcams"
3 depends on VIDEO_V4L2 3 depends on VIDEO_V4L2
4 default m
4 ---help--- 5 ---help---
5 Say Y here if you want support for various USB webcams. 6 Say Y here if you want to enable selecting webcams based
7 on the GSPCA framework.
6 8
7 See <file:Documentation/video4linux/gspca.txt> for more info. 9 See <file:Documentation/video4linux/gspca.txt> for more info.
8 10
9 This driver uses the Video For Linux API. You must say Y or M to 11 This driver uses the Video For Linux API. You must say Y or M to
10 "Video For Linux" to use this driver. 12 "Video For Linux" to use this driver.
11 13
12 To compile this driver as modules, choose M here: the 14 To compile this driver as modules, choose M here: the
13 modules will be called gspca_xxxx. 15 modules will be called gspca_main.
16
17
18if USB_GSPCA && VIDEO_V4L2
19
20source "drivers/media/video/gspca/m5602/Kconfig"
21
22config USB_GSPCA_CONEX
23 tristate "Conexant Camera Driver"
24 depends on VIDEO_V4L2 && USB_GSPCA
25 help
26 Say Y here if you want support for cameras based on the Conexant chip.
27
28 To compile this driver as a module, choose M here: the
29 module will be called gspca_conex.
30
31config USB_GSPCA_ETOMS
32 tristate "Etoms USB Camera Driver"
33 depends on VIDEO_V4L2 && USB_GSPCA
34 help
35 Say Y here if you want support for cameras based on the Etoms chip.
36
37 To compile this driver as a module, choose M here: the
38 module will be called gspca_etoms.
39
40config USB_GSPCA_FINEPIX
41 tristate "Fujifilm FinePix USB V4L2 driver"
42 depends on VIDEO_V4L2 && USB_GSPCA
43 help
44 Say Y here if you want support for cameras based on the FinePix chip.
45
46 To compile this driver as a module, choose M here: the
47 module will be called gspca_finepix.
48
49config USB_GSPCA_MARS
50 tristate "Mars USB Camera Driver"
51 depends on VIDEO_V4L2 && USB_GSPCA
52 help
53 Say Y here if you want support for cameras based on the Mars chip.
54
55 To compile this driver as a module, choose M here: the
56 module will be called gspca_mars.
57
58config USB_GSPCA_OV519
59 tristate "OV519 USB Camera Driver"
60 depends on VIDEO_V4L2 && USB_GSPCA
61 help
62 Say Y here if you want support for cameras based on the OV519 chip.
63
64 To compile this driver as a module, choose M here: the
65 module will be called gspca_ov519.
66
67config USB_GSPCA_PAC207
68 tristate "Pixart PAC207 USB Camera Driver"
69 depends on VIDEO_V4L2 && USB_GSPCA
70 help
71 Say Y here if you want support for cameras based on the PAC207 chip.
72
73 To compile this driver as a module, choose M here: the
74 module will be called gspca_pac207.
75
76config USB_GSPCA_PAC7311
77 tristate "Pixart PAC7311 USB Camera Driver"
78 depends on VIDEO_V4L2 && USB_GSPCA
79 help
80 Say Y here if you want support for cameras based on the PAC7311 chip.
81
82 To compile this driver as a module, choose M here: the
83 module will be called gspca_pac7311.
84
85config USB_GSPCA_SONIXB
86 tristate "SN9C102 USB Camera Driver"
87 depends on VIDEO_V4L2 && USB_GSPCA
88 help
89 Say Y here if you want support for cameras based on the SONIXB chip.
90
91 To compile this driver as a module, choose M here: the
92 module will be called gspca_sonixb.
93
94config USB_GSPCA_SONIXJ
95 tristate "SONIX JPEG USB Camera Driver"
96 depends on VIDEO_V4L2 && USB_GSPCA
97 help
98 Say Y here if you want support for cameras based on the SONIXJ chip.
99
100 To compile this driver as a module, choose M here: the
101 module will be called gspca_sonixj
102
103config USB_GSPCA_SPCA500
104 tristate "SPCA500 USB Camera Driver"
105 depends on VIDEO_V4L2 && USB_GSPCA
106 help
107 Say Y here if you want support for cameras based on the SPCA500 chip.
108
109 To compile this driver as a module, choose M here: the
110 module will be called gspca_spca500.
111
112config USB_GSPCA_SPCA501
113 tristate "SPCA501 USB Camera Driver"
114 depends on VIDEO_V4L2 && USB_GSPCA
115 help
116 Say Y here if you want support for cameras based on the SPCA501 chip.
117
118 To compile this driver as a module, choose M here: the
119 module will be called gspca_spca501.
120
121config USB_GSPCA_SPCA505
122 tristate "SPCA505 USB Camera Driver"
123 depends on VIDEO_V4L2 && USB_GSPCA
124 help
125 Say Y here if you want support for cameras based on the SPCA505 chip.
126
127 To compile this driver as a module, choose M here: the
128 module will be called gspca_spca505.
129
130config USB_GSPCA_SPCA506
131 tristate "SPCA506 USB Camera Driver"
132 depends on VIDEO_V4L2 && USB_GSPCA
133 help
134 Say Y here if you want support for cameras based on the SPCA506 chip.
135
136 To compile this driver as a module, choose M here: the
137 module will be called gspca_spca506.
138
139config USB_GSPCA_SPCA508
140 tristate "SPCA508 USB Camera Driver"
141 depends on VIDEO_V4L2 && USB_GSPCA
142 help
143 Say Y here if you want support for cameras based on the SPCA508 chip.
144
145 To compile this driver as a module, choose M here: the
146 module will be called gspca_spca508.
147
148config USB_GSPCA_SPCA561
149 tristate "SPCA561 USB Camera Driver"
150 depends on VIDEO_V4L2 && USB_GSPCA
151 help
152 Say Y here if you want support for cameras based on the SPCA561 chip.
153
154 To compile this driver as a module, choose M here: the
155 module will be called gspca_spca561.
156
157config USB_GSPCA_STK014
158 tristate "Syntek DV4000 (STK014) USB Camera Driver"
159 depends on VIDEO_V4L2 && USB_GSPCA
160 help
161 Say Y here if you want support for cameras based on the STK014 chip.
162
163 To compile this driver as a module, choose M here: the
164 module will be called gspca_stk014.
165
166config USB_GSPCA_SUNPLUS
167 tristate "SUNPLUS USB Camera Driver"
168 depends on VIDEO_V4L2 && USB_GSPCA
169 help
170 Say Y here if you want support for cameras based on the Sunplus
171 SPCA504(abc) SPCA533 SPCA536 chips.
172
173 To compile this driver as a module, choose M here: the
174 module will be called gspca_spca5xx.
175
176config USB_GSPCA_T613
177 tristate "T613 (JPEG Compliance) USB Camera Driver"
178 depends on VIDEO_V4L2 && USB_GSPCA
179 help
180 Say Y here if you want support for cameras based on the T613 chip.
181
182 To compile this driver as a module, choose M here: the
183 module will be called gspca_t613.
184
185config USB_GSPCA_TV8532
186 tristate "TV8532 USB Camera Driver"
187 depends on VIDEO_V4L2 && USB_GSPCA
188 help
189 Say Y here if you want support for cameras based on the TV8531 chip.
190
191 To compile this driver as a module, choose M here: the
192 module will be called gspca_tv8532.
193
194config USB_GSPCA_VC032X
195 tristate "VC032X USB Camera Driver"
196 depends on VIDEO_V4L2 && USB_GSPCA
197 help
198 Say Y here if you want support for cameras based on the VC032X chip.
199
200 To compile this driver as a module, choose M here: the
201 module will be called gspca_vc032x.
202
203config USB_GSPCA_ZC3XX
204 tristate "VC3xx USB Camera Driver"
205 depends on VIDEO_V4L2 && USB_GSPCA
206 help
207 Say Y here if you want support for cameras based on the ZC3XX chip.
208
209 To compile this driver as a module, choose M here: the
210 module will be called gspca_zc3xx.
211
212endif
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index e68a8965297a..22734f5a6c32 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -1,29 +1,48 @@
1obj-$(CONFIG_USB_GSPCA) += gspca_main.o \ 1obj-$(CONFIG_USB_GSPCA) += gspca_main.o
2 gspca_conex.o gspca_etoms.o gspca_mars.o \ 2obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
3 gspca_ov519.o gspca_pac207.o gspca_pac7311.o \ 3obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
4 gspca_sonixb.o gspca_sonixj.o gspca_spca500.o gspca_spca501.o \ 4obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
5 gspca_spca505.o gspca_spca506.o gspca_spca508.o gspca_spca561.o \ 5obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
6 gspca_sunplus.o gspca_stk014.o gspca_t613.o gspca_tv8532.o \ 6obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
7 gspca_vc032x.o gspca_zc3xx.o 7obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
8obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
9obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
10obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
11obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
12obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
13obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
14obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
15obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
16obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
17obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
18obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
19obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
20obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
21obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
22obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
23
24gspca_main-objs := gspca.o
25gspca_conex-objs := conex.o
26gspca_etoms-objs := etoms.o
27gspca_finepix-objs := finepix.o
28gspca_mars-objs := mars.o
29gspca_ov519-objs := ov519.o
30gspca_pac207-objs := pac207.o
31gspca_pac7311-objs := pac7311.o
32gspca_sonixb-objs := sonixb.o
33gspca_sonixj-objs := sonixj.o
34gspca_spca500-objs := spca500.o
35gspca_spca501-objs := spca501.o
36gspca_spca505-objs := spca505.o
37gspca_spca506-objs := spca506.o
38gspca_spca508-objs := spca508.o
39gspca_spca561-objs := spca561.o
40gspca_stk014-objs := stk014.o
41gspca_sunplus-objs := sunplus.o
42gspca_t613-objs := t613.o
43gspca_tv8532-objs := tv8532.o
44gspca_vc032x-objs := vc032x.o
45gspca_zc3xx-objs := zc3xx.o
46
47obj-$(CONFIG_USB_M5602) += m5602/
8 48
9gspca_main-objs := gspca.o
10gspca_conex-objs := conex.o
11gspca_etoms-objs := etoms.o
12gspca_mars-objs := mars.o
13gspca_ov519-objs := ov519.o
14gspca_pac207-objs := pac207.o
15gspca_pac7311-objs := pac7311.o
16gspca_sonixb-objs := sonixb.o
17gspca_sonixj-objs := sonixj.o
18gspca_spca500-objs := spca500.o
19gspca_spca501-objs := spca501.o
20gspca_spca505-objs := spca505.o
21gspca_spca506-objs := spca506.o
22gspca_spca508-objs := spca508.o
23gspca_spca561-objs := spca561.o
24gspca_stk014-objs := stk014.o
25gspca_sunplus-objs := sunplus.o
26gspca_t613-objs := t613.o
27gspca_tv8532-objs := tv8532.o
28gspca_vc032x-objs := vc032x.o
29gspca_zc3xx-objs := zc3xx.o
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 4d9f4cc255a9..a9d51ba7c57c 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -837,12 +837,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
837 return 0; 837 return 0;
838} 838}
839 839
840static void sd_start(struct gspca_dev *gspca_dev) 840static int sd_start(struct gspca_dev *gspca_dev)
841{ 841{
842 cx11646_initsize(gspca_dev); 842 cx11646_initsize(gspca_dev);
843 cx11646_fw(gspca_dev); 843 cx11646_fw(gspca_dev);
844 cx_sensor(gspca_dev); 844 cx_sensor(gspca_dev);
845 cx11646_jpeg(gspca_dev); 845 cx11646_jpeg(gspca_dev);
846 return 0;
846} 847}
847 848
848static void sd_stop0(struct gspca_dev *gspca_dev) 849static void sd_stop0(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 4ff0e386914b..3be30b420a26 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -691,7 +691,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
691} 691}
692 692
693/* -- start the camera -- */ 693/* -- start the camera -- */
694static void sd_start(struct gspca_dev *gspca_dev) 694static int sd_start(struct gspca_dev *gspca_dev)
695{ 695{
696 struct sd *sd = (struct sd *) gspca_dev; 696 struct sd *sd = (struct sd *) gspca_dev;
697 697
@@ -704,6 +704,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
704 704
705 reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); 705 reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
706 et_video(gspca_dev, 1); /* video on */ 706 et_video(gspca_dev, 1); /* video on */
707 return 0;
707} 708}
708 709
709static void sd_stopN(struct gspca_dev *gspca_dev) 710static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
new file mode 100644
index 000000000000..65d3cbfe6b27
--- /dev/null
+++ b/drivers/media/video/gspca/finepix.c
@@ -0,0 +1,466 @@
1/*
2 * Fujifilm Finepix subdriver
3 *
4 * Copyright (C) 2008 Frank Zago
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#define MODULE_NAME "finepix"
22
23#include "gspca.h"
24
25MODULE_AUTHOR("Frank Zago <frank@zago.net>");
26MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");
27MODULE_LICENSE("GPL");
28
29/* Default timeout, in ms */
30#define FPIX_TIMEOUT (HZ / 10)
31
32/* Maximum transfer size to use. The windows driver reads by chunks of
33 * 0x2000 bytes, so do the same. Note: reading more seems to work
34 * too. */
35#define FPIX_MAX_TRANSFER 0x2000
36
37/* Structure to hold all of our device specific stuff */
38struct usb_fpix {
39 struct gspca_dev gspca_dev; /* !! must be the first item */
40
41 /*
42 * USB stuff
43 */
44 struct usb_ctrlrequest ctrlreq;
45 struct urb *control_urb;
46 struct timer_list bulk_timer;
47
48 enum {
49 FPIX_NOP, /* inactive, else streaming */
50 FPIX_RESET, /* must reset */
51 FPIX_REQ_FRAME, /* requesting a frame */
52 FPIX_READ_FRAME, /* reading frame */
53 } state;
54
55 /*
56 * Driver stuff
57 */
58 struct delayed_work wqe;
59 struct completion can_close;
60 int streaming;
61};
62
63/* Delay after which claim the next frame. If the delay is too small,
64 * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms
65 * will fail every 4 or 5 frames, but 30ms is perfect. */
66#define NEXT_FRAME_DELAY (((HZ * 30) + 999) / 1000)
67
68#define dev_new_state(new_state) { \
69 PDEBUG(D_STREAM, "new state from %d to %d at %s:%d", \
70 dev->state, new_state, __func__, __LINE__); \
71 dev->state = new_state; \
72}
73
74/* These cameras only support 320x200. */
75static struct v4l2_pix_format fpix_mode[1] = {
76 { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
77 .bytesperline = 320,
78 .sizeimage = 320 * 240 * 3 / 8 + 590,
79 .colorspace = V4L2_COLORSPACE_SRGB,
80 .priv = 0}
81};
82
83/* Reads part of a frame */
84static void read_frame_part(struct usb_fpix *dev)
85{
86 int ret;
87
88 PDEBUG(D_STREAM, "read_frame_part");
89
90 /* Reads part of a frame */
91 ret = usb_submit_urb(dev->gspca_dev.urb[0], GFP_ATOMIC);
92 if (ret) {
93 dev_new_state(FPIX_RESET);
94 schedule_delayed_work(&dev->wqe, 1);
95 PDEBUG(D_STREAM, "usb_submit_urb failed with %d",
96 ret);
97 } else {
98 /* Sometimes we never get a callback, so use a timer.
99 * Is this masking a bug somewhere else? */
100 dev->bulk_timer.expires = jiffies + msecs_to_jiffies(150);
101 add_timer(&dev->bulk_timer);
102 }
103}
104
105/* Callback for URBs. */
106static void urb_callback(struct urb *urb)
107{
108 struct gspca_dev *gspca_dev = urb->context;
109 struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
110
111 PDEBUG(D_PACK,
112 "enter urb_callback - status=%d, length=%d",
113 urb->status, urb->actual_length);
114
115 if (dev->state == FPIX_READ_FRAME)
116 del_timer(&dev->bulk_timer);
117
118 if (urb->status != 0) {
119 /* We kill a stuck urb every 50 frames on average, so don't
120 * display a log message for that. */
121 if (urb->status != -ECONNRESET)
122 PDEBUG(D_STREAM, "bad URB status %d", urb->status);
123 dev_new_state(FPIX_RESET);
124 schedule_delayed_work(&dev->wqe, 1);
125 }
126
127 switch (dev->state) {
128 case FPIX_REQ_FRAME:
129 dev_new_state(FPIX_READ_FRAME);
130 read_frame_part(dev);
131 break;
132
133 case FPIX_READ_FRAME: {
134 unsigned char *data = urb->transfer_buffer;
135 struct gspca_frame *frame;
136
137 frame = gspca_get_i_frame(&dev->gspca_dev);
138 if (frame == NULL)
139 gspca_dev->last_packet_type = DISCARD_PACKET;
140 if (urb->actual_length < FPIX_MAX_TRANSFER ||
141 (data[urb->actual_length-2] == 0xff &&
142 data[urb->actual_length-1] == 0xd9)) {
143
144 /* If the result is less than what was asked
145 * for, then it's the end of the
146 * frame. Sometime the jpeg is not complete,
147 * but there's nothing we can do. We also end
148 * here if the the jpeg ends right at the end
149 * of the frame. */
150 if (frame)
151 gspca_frame_add(gspca_dev, LAST_PACKET,
152 frame,
153 data, urb->actual_length);
154 dev_new_state(FPIX_REQ_FRAME);
155 schedule_delayed_work(&dev->wqe, NEXT_FRAME_DELAY);
156 } else {
157
158 /* got a partial image */
159 if (frame)
160 gspca_frame_add(gspca_dev,
161 gspca_dev->last_packet_type
162 == LAST_PACKET
163 ? FIRST_PACKET : INTER_PACKET,
164 frame,
165 data, urb->actual_length);
166 read_frame_part(dev);
167 }
168 break;
169 }
170
171 case FPIX_NOP:
172 case FPIX_RESET:
173 PDEBUG(D_STREAM, "invalid state %d", dev->state);
174 break;
175 }
176}
177
178/* Request a new frame */
179static void request_frame(struct usb_fpix *dev)
180{
181 int ret;
182 struct gspca_dev *gspca_dev = &dev->gspca_dev;
183
184 /* Setup command packet */
185 memset(gspca_dev->usb_buf, 0, 12);
186 gspca_dev->usb_buf[0] = 0xd3;
187 gspca_dev->usb_buf[7] = 0x01;
188
189 /* Request a frame */
190 dev->ctrlreq.bRequestType =
191 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
192 dev->ctrlreq.bRequest = USB_REQ_GET_STATUS;
193 dev->ctrlreq.wValue = 0;
194 dev->ctrlreq.wIndex = 0;
195 dev->ctrlreq.wLength = cpu_to_le16(12);
196
197 usb_fill_control_urb(dev->control_urb,
198 gspca_dev->dev,
199 usb_sndctrlpipe(gspca_dev->dev, 0),
200 (unsigned char *) &dev->ctrlreq,
201 gspca_dev->usb_buf,
202 12, urb_callback, gspca_dev);
203
204 ret = usb_submit_urb(dev->control_urb, GFP_ATOMIC);
205 if (ret) {
206 dev_new_state(FPIX_RESET);
207 schedule_delayed_work(&dev->wqe, 1);
208 PDEBUG(D_STREAM, "usb_submit_urb failed with %d", ret);
209 }
210}
211
212/*--------------------------------------------------------------------------*/
213
214/* State machine. */
215static void fpix_sm(struct work_struct *work)
216{
217 struct usb_fpix *dev = container_of(work, struct usb_fpix, wqe.work);
218
219 PDEBUG(D_STREAM, "fpix_sm state %d", dev->state);
220
221 /* verify that the device wasn't unplugged */
222 if (!dev->gspca_dev.present) {
223 PDEBUG(D_STREAM, "device is gone");
224 dev_new_state(FPIX_NOP);
225 complete(&dev->can_close);
226 return;
227 }
228
229 if (!dev->streaming) {
230 PDEBUG(D_STREAM, "stopping state machine");
231 dev_new_state(FPIX_NOP);
232 complete(&dev->can_close);
233 return;
234 }
235
236 switch (dev->state) {
237 case FPIX_RESET:
238 dev_new_state(FPIX_REQ_FRAME);
239 schedule_delayed_work(&dev->wqe, HZ / 10);
240 break;
241
242 case FPIX_REQ_FRAME:
243 /* get an image */
244 request_frame(dev);
245 break;
246
247 case FPIX_NOP:
248 case FPIX_READ_FRAME:
249 PDEBUG(D_STREAM, "invalid state %d", dev->state);
250 break;
251 }
252}
253
254/* this function is called at probe time */
255static int sd_config(struct gspca_dev *gspca_dev,
256 const struct usb_device_id *id)
257{
258 struct cam *cam = &gspca_dev->cam;
259
260 cam->cam_mode = fpix_mode;
261 cam->nmodes = 1;
262 cam->epaddr = 0x01; /* todo: correct for all cams? */
263 cam->bulk_size = FPIX_MAX_TRANSFER;
264
265/* gspca_dev->nbalt = 1; * use bulk transfer */
266 return 0;
267}
268
269/* Stop streaming and free the ressources allocated by sd_start. */
270static void sd_stopN(struct gspca_dev *gspca_dev)
271{
272 struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
273
274 dev->streaming = 0;
275
276 /* Stop the state machine */
277 if (dev->state != FPIX_NOP)
278 wait_for_completion(&dev->can_close);
279
280 usb_free_urb(dev->control_urb);
281 dev->control_urb = NULL;
282}
283
284/* Kill an URB that hasn't completed. */
285static void timeout_kill(unsigned long data)
286{
287 struct urb *urb = (struct urb *) data;
288
289 usb_unlink_urb(urb);
290}
291
292/* this function is called at probe and resume time */
293static int sd_init(struct gspca_dev *gspca_dev)
294{
295 struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
296
297 INIT_DELAYED_WORK(&dev->wqe, fpix_sm);
298
299 init_timer(&dev->bulk_timer);
300 dev->bulk_timer.function = timeout_kill;
301
302 return 0;
303}
304
305static int sd_start(struct gspca_dev *gspca_dev)
306{
307 struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
308 int ret;
309 int size_ret;
310
311 /* Reset bulk in endpoint */
312 usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
313
314 /* Init the device */
315 memset(gspca_dev->usb_buf, 0, 12);
316 gspca_dev->usb_buf[0] = 0xc6;
317 gspca_dev->usb_buf[8] = 0x20;
318
319 ret = usb_control_msg(gspca_dev->dev,
320 usb_sndctrlpipe(gspca_dev->dev, 0),
321 USB_REQ_GET_STATUS,
322 USB_DIR_OUT | USB_TYPE_CLASS |
323 USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
324 12, FPIX_TIMEOUT);
325
326 if (ret != 12) {
327 PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
328 ret = -EIO;
329 goto error;
330 }
331
332 /* Read the result of the command. Ignore the result, for it
333 * varies with the device. */
334 ret = usb_bulk_msg(gspca_dev->dev,
335 usb_rcvbulkpipe(gspca_dev->dev,
336 gspca_dev->cam.epaddr),
337 gspca_dev->usb_buf, FPIX_MAX_TRANSFER, &size_ret,
338 FPIX_TIMEOUT);
339 if (ret != 0) {
340 PDEBUG(D_STREAM, "usb_bulk_msg failed (%d)", ret);
341 ret = -EIO;
342 goto error;
343 }
344
345 /* Request a frame, but don't read it */
346 memset(gspca_dev->usb_buf, 0, 12);
347 gspca_dev->usb_buf[0] = 0xd3;
348 gspca_dev->usb_buf[7] = 0x01;
349
350 ret = usb_control_msg(gspca_dev->dev,
351 usb_sndctrlpipe(gspca_dev->dev, 0),
352 USB_REQ_GET_STATUS,
353 USB_DIR_OUT | USB_TYPE_CLASS |
354 USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
355 12, FPIX_TIMEOUT);
356 if (ret != 12) {
357 PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
358 ret = -EIO;
359 goto error;
360 }
361
362 /* Again, reset bulk in endpoint */
363 usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
364
365 /* Allocate a control URB */
366 dev->control_urb = usb_alloc_urb(0, GFP_KERNEL);
367 if (!dev->control_urb) {
368 PDEBUG(D_STREAM, "No free urbs available");
369 ret = -EIO;
370 goto error;
371 }
372
373 /* Various initializations. */
374 init_completion(&dev->can_close);
375 dev->bulk_timer.data = (unsigned long)dev->gspca_dev.urb[0];
376 dev->gspca_dev.urb[0]->complete = urb_callback;
377 dev->streaming = 1;
378
379 /* Schedule a frame request. */
380 dev_new_state(FPIX_REQ_FRAME);
381 schedule_delayed_work(&dev->wqe, 1);
382
383 return 0;
384
385error:
386 /* Free the ressources */
387 sd_stopN(gspca_dev);
388 return ret;
389}
390
391/* Table of supported USB devices */
392static const __devinitdata struct usb_device_id device_table[] = {
393 {USB_DEVICE(0x04cb, 0x0104)},
394 {USB_DEVICE(0x04cb, 0x0109)},
395 {USB_DEVICE(0x04cb, 0x010b)},
396 {USB_DEVICE(0x04cb, 0x010f)},
397 {USB_DEVICE(0x04cb, 0x0111)},
398 {USB_DEVICE(0x04cb, 0x0113)},
399 {USB_DEVICE(0x04cb, 0x0115)},
400 {USB_DEVICE(0x04cb, 0x0117)},
401 {USB_DEVICE(0x04cb, 0x0119)},
402 {USB_DEVICE(0x04cb, 0x011b)},
403 {USB_DEVICE(0x04cb, 0x011d)},
404 {USB_DEVICE(0x04cb, 0x0121)},
405 {USB_DEVICE(0x04cb, 0x0123)},
406 {USB_DEVICE(0x04cb, 0x0125)},
407 {USB_DEVICE(0x04cb, 0x0127)},
408 {USB_DEVICE(0x04cb, 0x0129)},
409 {USB_DEVICE(0x04cb, 0x012b)},
410 {USB_DEVICE(0x04cb, 0x012d)},
411 {USB_DEVICE(0x04cb, 0x012f)},
412 {USB_DEVICE(0x04cb, 0x0131)},
413 {USB_DEVICE(0x04cb, 0x013b)},
414 {USB_DEVICE(0x04cb, 0x013d)},
415 {USB_DEVICE(0x04cb, 0x013f)},
416 {}
417};
418
419MODULE_DEVICE_TABLE(usb, device_table);
420
421/* sub-driver description */
422static const struct sd_desc sd_desc = {
423 .name = MODULE_NAME,
424 .config = sd_config,
425 .init = sd_init,
426 .start = sd_start,
427 .stopN = sd_stopN,
428};
429
430/* -- device connect -- */
431static int sd_probe(struct usb_interface *intf,
432 const struct usb_device_id *id)
433{
434 return gspca_dev_probe(intf, id,
435 &sd_desc,
436 sizeof(struct usb_fpix),
437 THIS_MODULE);
438}
439
440static struct usb_driver sd_driver = {
441 .name = MODULE_NAME,
442 .id_table = device_table,
443 .probe = sd_probe,
444 .disconnect = gspca_disconnect,
445#ifdef CONFIG_PM
446 .suspend = gspca_suspend,
447 .resume = gspca_resume,
448#endif
449};
450
451/* -- module insert / remove -- */
452static int __init sd_mod_init(void)
453{
454 if (usb_register(&sd_driver) < 0)
455 return -1;
456 PDEBUG(D_PROBE, "registered");
457 return 0;
458}
459static void __exit sd_mod_exit(void)
460{
461 usb_deregister(&sd_driver);
462 PDEBUG(D_PROBE, "deregistered");
463}
464
465module_init(sd_mod_init);
466module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index ac95c55887df..c21af312ee7c 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -29,6 +29,7 @@
29#include <linux/string.h> 29#include <linux/string.h>
30#include <linux/pagemap.h> 30#include <linux/pagemap.h>
31#include <linux/io.h> 31#include <linux/io.h>
32#include <linux/kref.h>
32#include <asm/page.h> 33#include <asm/page.h>
33#include <linux/uaccess.h> 34#include <linux/uaccess.h>
34#include <linux/jiffies.h> 35#include <linux/jiffies.h>
@@ -43,7 +44,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
43MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 44MODULE_DESCRIPTION("GSPCA USB Camera Driver");
44MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
45 46
46#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 2, 0) 47#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 3, 0)
47 48
48static int video_nr = -1; 49static int video_nr = -1;
49 50
@@ -102,6 +103,22 @@ static struct vm_operations_struct gspca_vm_ops = {
102 .close = gspca_vm_close, 103 .close = gspca_vm_close,
103}; 104};
104 105
106/* get the current input frame buffer */
107struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev)
108{
109 struct gspca_frame *frame;
110 int i;
111
112 i = gspca_dev->fr_i;
113 i = gspca_dev->fr_queue[i];
114 frame = &gspca_dev->frame[i];
115 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
116 != V4L2_BUF_FLAG_QUEUED)
117 return NULL;
118 return frame;
119}
120EXPORT_SYMBOL(gspca_get_i_frame);
121
105/* 122/*
106 * fill a video frame from an URB and resubmit 123 * fill a video frame from an URB and resubmit
107 */ 124 */
@@ -110,7 +127,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
110{ 127{
111 struct gspca_frame *frame; 128 struct gspca_frame *frame;
112 __u8 *data; /* address of data in the iso message */ 129 __u8 *data; /* address of data in the iso message */
113 int i, j, len, st; 130 int i, len, st;
114 cam_pkt_op pkt_scan; 131 cam_pkt_op pkt_scan;
115 132
116 if (urb->status != 0) { 133 if (urb->status != 0) {
@@ -124,11 +141,8 @@ static void fill_frame(struct gspca_dev *gspca_dev,
124 for (i = 0; i < urb->number_of_packets; i++) { 141 for (i = 0; i < urb->number_of_packets; i++) {
125 142
126 /* check the availability of the frame buffer */ 143 /* check the availability of the frame buffer */
127 j = gspca_dev->fr_i; 144 frame = gspca_get_i_frame(gspca_dev);
128 j = gspca_dev->fr_queue[j]; 145 if (!frame) {
129 frame = &gspca_dev->frame[j];
130 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
131 != V4L2_BUF_FLAG_QUEUED) {
132 gspca_dev->last_packet_type = DISCARD_PACKET; 146 gspca_dev->last_packet_type = DISCARD_PACKET;
133 break; 147 break;
134 } 148 }
@@ -178,6 +192,39 @@ static void isoc_irq(struct urb *urb
178} 192}
179 193
180/* 194/*
195 * bulk message interrupt from the USB device
196 */
197static void bulk_irq(struct urb *urb
198)
199{
200 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
201 struct gspca_frame *frame;
202
203 PDEBUG(D_PACK, "bulk irq");
204 if (!gspca_dev->streaming)
205 return;
206 if (urb->status != 0 && urb->status != -ECONNRESET) {
207#ifdef CONFIG_PM
208 if (!gspca_dev->frozen)
209#endif
210 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
211 return; /* disconnection ? */
212 }
213
214 /* check the availability of the frame buffer */
215 frame = gspca_get_i_frame(gspca_dev);
216 if (!frame) {
217 gspca_dev->last_packet_type = DISCARD_PACKET;
218 } else {
219 PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
220 gspca_dev->sd_desc->pkt_scan(gspca_dev,
221 frame,
222 urb->transfer_buffer,
223 urb->actual_length);
224 }
225}
226
227/*
181 * add data to the current frame 228 * add data to the current frame
182 * 229 *
183 * This function is called by the subdrivers at interrupt level. 230 * This function is called by the subdrivers at interrupt level.
@@ -190,7 +237,7 @@ static void isoc_irq(struct urb *urb
190 * On LAST_PACKET, a new frame is returned. 237 * On LAST_PACKET, a new frame is returned.
191 */ 238 */
192struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 239struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
193 int packet_type, 240 enum gspca_packet_type packet_type,
194 struct gspca_frame *frame, 241 struct gspca_frame *frame,
195 const __u8 *data, 242 const __u8 *data,
196 int len) 243 int len)
@@ -232,7 +279,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
232 } 279 }
233 gspca_dev->last_packet_type = packet_type; 280 gspca_dev->last_packet_type = packet_type;
234 281
235 /* if last packet, wake the application and advance in the queue */ 282 /* if last packet, wake up the application and advance in the queue */
236 if (packet_type == LAST_PACKET) { 283 if (packet_type == LAST_PACKET) {
237 frame->v4l2_buf.bytesused = frame->data_end - frame->data; 284 frame->v4l2_buf.bytesused = frame->data_end - frame->data;
238 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; 285 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
@@ -270,7 +317,6 @@ static void *rvmalloc(unsigned long size)
270 void *mem; 317 void *mem;
271 unsigned long adr; 318 unsigned long adr;
272 319
273/* size = PAGE_ALIGN(size); (already done) */
274 mem = vmalloc_32(size); 320 mem = vmalloc_32(size);
275 if (mem != NULL) { 321 if (mem != NULL) {
276 adr = (unsigned long) mem; 322 adr = (unsigned long) mem;
@@ -374,10 +420,11 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
374} 420}
375 421
376/* 422/*
377 * search an input isochronous endpoint in an alternate setting 423 * look for an input transfer endpoint in an alternate setting
378 */ 424 */
379static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt, 425static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
380 __u8 epaddr) 426 __u8 epaddr,
427 __u8 xfer)
381{ 428{
382 struct usb_host_endpoint *ep; 429 struct usb_host_endpoint *ep;
383 int i, attr; 430 int i, attr;
@@ -388,7 +435,7 @@ static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt,
388 if (ep->desc.bEndpointAddress == epaddr) { 435 if (ep->desc.bEndpointAddress == epaddr) {
389 attr = ep->desc.bmAttributes 436 attr = ep->desc.bmAttributes
390 & USB_ENDPOINT_XFERTYPE_MASK; 437 & USB_ENDPOINT_XFERTYPE_MASK;
391 if (attr == USB_ENDPOINT_XFER_ISOC) 438 if (attr == xfer)
392 return ep; 439 return ep;
393 break; 440 break;
394 } 441 }
@@ -397,14 +444,14 @@ static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt,
397} 444}
398 445
399/* 446/*
400 * search an input isochronous endpoint 447 * look for an input (isoc or bulk) endpoint
401 * 448 *
402 * The endpoint is defined by the subdriver. 449 * The endpoint is defined by the subdriver.
403 * Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep). 450 * Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep).
404 * This routine may be called many times when the bandwidth is too small 451 * This routine may be called many times when the bandwidth is too small
405 * (the bandwidth is checked on urb submit). 452 * (the bandwidth is checked on urb submit).
406 */ 453 */
407static struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) 454static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
408{ 455{
409 struct usb_interface *intf; 456 struct usb_interface *intf;
410 struct usb_host_endpoint *ep; 457 struct usb_host_endpoint *ep;
@@ -413,28 +460,41 @@ static struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev)
413 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); 460 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
414 ep = NULL; 461 ep = NULL;
415 i = gspca_dev->alt; /* previous alt setting */ 462 i = gspca_dev->alt; /* previous alt setting */
463
464 /* try isoc */
416 while (--i > 0) { /* alt 0 is unusable */ 465 while (--i > 0) { /* alt 0 is unusable */
417 ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); 466 ep = alt_xfer(&intf->altsetting[i],
467 gspca_dev->cam.epaddr,
468 USB_ENDPOINT_XFER_ISOC);
418 if (ep) 469 if (ep)
419 break; 470 break;
420 } 471 }
472
473 /* if no isoc, try bulk */
421 if (ep == NULL) { 474 if (ep == NULL) {
422 err("no ISOC endpoint found"); 475 ep = alt_xfer(&intf->altsetting[0],
423 return NULL; 476 gspca_dev->cam.epaddr,
477 USB_ENDPOINT_XFER_BULK);
478 if (ep == NULL) {
479 err("no transfer endpoint found");
480 return NULL;
481 }
424 } 482 }
425 PDEBUG(D_STREAM, "use ISOC alt %d ep 0x%02x", 483 PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
426 i, ep->desc.bEndpointAddress); 484 i, ep->desc.bEndpointAddress);
427 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); 485 if (i > 0) {
428 if (ret < 0) { 486 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
429 err("set interface err %d", ret); 487 if (ret < 0) {
430 return NULL; 488 err("set interface err %d", ret);
489 return NULL;
490 }
431 } 491 }
432 gspca_dev->alt = i; /* memorize the current alt setting */ 492 gspca_dev->alt = i; /* memorize the current alt setting */
433 return ep; 493 return ep;
434} 494}
435 495
436/* 496/*
437 * create the isochronous URBs 497 * create the URBs for image transfer
438 */ 498 */
439static int create_urbs(struct gspca_dev *gspca_dev, 499static int create_urbs(struct gspca_dev *gspca_dev,
440 struct usb_host_endpoint *ep) 500 struct usb_host_endpoint *ep)
@@ -445,15 +505,27 @@ static int create_urbs(struct gspca_dev *gspca_dev,
445 /* calculate the packet size and the number of packets */ 505 /* calculate the packet size and the number of packets */
446 psize = le16_to_cpu(ep->desc.wMaxPacketSize); 506 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
447 507
448 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ 508 if (gspca_dev->alt != 0) { /* isoc */
449 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); 509
450 npkt = ISO_MAX_SIZE / psize; 510 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
451 if (npkt > ISO_MAX_PKT) 511 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
452 npkt = ISO_MAX_PKT; 512 npkt = ISO_MAX_SIZE / psize;
453 bsize = psize * npkt; 513 if (npkt > ISO_MAX_PKT)
454 PDEBUG(D_STREAM, 514 npkt = ISO_MAX_PKT;
455 "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); 515 bsize = psize * npkt;
456 nurbs = DEF_NURBS; 516 PDEBUG(D_STREAM,
517 "isoc %d pkts size %d = bsize:%d",
518 npkt, psize, bsize);
519 nurbs = DEF_NURBS;
520 } else { /* bulk */
521 npkt = 0;
522 bsize = gspca_dev->cam. bulk_size;
523 if (bsize == 0)
524 bsize = psize;
525 PDEBUG(D_STREAM, "bulk bsize:%d", bsize);
526 nurbs = 1;
527 }
528
457 gspca_dev->nurbs = nurbs; 529 gspca_dev->nurbs = nurbs;
458 for (n = 0; n < nurbs; n++) { 530 for (n = 0; n < nurbs; n++) {
459 urb = usb_alloc_urb(npkt, GFP_KERNEL); 531 urb = usb_alloc_urb(npkt, GFP_KERNEL);
@@ -476,17 +548,24 @@ static int create_urbs(struct gspca_dev *gspca_dev,
476 gspca_dev->urb[n] = urb; 548 gspca_dev->urb[n] = urb;
477 urb->dev = gspca_dev->dev; 549 urb->dev = gspca_dev->dev;
478 urb->context = gspca_dev; 550 urb->context = gspca_dev;
479 urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
480 ep->desc.bEndpointAddress);
481 urb->transfer_flags = URB_ISO_ASAP
482 | URB_NO_TRANSFER_DMA_MAP;
483 urb->interval = ep->desc.bInterval;
484 urb->complete = isoc_irq;
485 urb->number_of_packets = npkt;
486 urb->transfer_buffer_length = bsize; 551 urb->transfer_buffer_length = bsize;
487 for (i = 0; i < npkt; i++) { 552 if (npkt != 0) { /* ISOC */
488 urb->iso_frame_desc[i].length = psize; 553 urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
489 urb->iso_frame_desc[i].offset = psize * i; 554 ep->desc.bEndpointAddress);
555 urb->transfer_flags = URB_ISO_ASAP
556 | URB_NO_TRANSFER_DMA_MAP;
557 urb->interval = ep->desc.bInterval;
558 urb->complete = isoc_irq;
559 urb->number_of_packets = npkt;
560 for (i = 0; i < npkt; i++) {
561 urb->iso_frame_desc[i].length = psize;
562 urb->iso_frame_desc[i].offset = psize * i;
563 }
564 } else { /* bulk */
565 urb->pipe = usb_rcvbulkpipe(gspca_dev->dev,
566 ep->desc.bEndpointAddress),
567 urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
568 urb->complete = bulk_irq;
490 } 569 }
491 } 570 }
492 return 0; 571 return 0;
@@ -508,7 +587,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
508 gspca_dev->alt = gspca_dev->nbalt; 587 gspca_dev->alt = gspca_dev->nbalt;
509 for (;;) { 588 for (;;) {
510 PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt); 589 PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt);
511 ep = get_isoc_ep(gspca_dev); 590 ep = get_ep(gspca_dev);
512 if (ep == NULL) { 591 if (ep == NULL) {
513 ret = -EIO; 592 ret = -EIO;
514 goto out; 593 goto out;
@@ -518,10 +597,18 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
518 goto out; 597 goto out;
519 598
520 /* start the cam */ 599 /* start the cam */
521 gspca_dev->sd_desc->start(gspca_dev); 600 ret = gspca_dev->sd_desc->start(gspca_dev);
601 if (ret < 0) {
602 destroy_urbs(gspca_dev);
603 goto out;
604 }
522 gspca_dev->streaming = 1; 605 gspca_dev->streaming = 1;
523 atomic_set(&gspca_dev->nevent, 0); 606 atomic_set(&gspca_dev->nevent, 0);
524 607
608 /* bulk transfers are started by the subdriver */
609 if (gspca_dev->alt == 0)
610 break;
611
525 /* submit the URBs */ 612 /* submit the URBs */
526 for (n = 0; n < gspca_dev->nurbs; n++) { 613 for (n = 0; n < gspca_dev->nurbs; n++) {
527 ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); 614 ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL);
@@ -553,7 +640,7 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
553 return ret; 640 return ret;
554} 641}
555 642
556/* Note both the queue and the usb lock should be hold when calling this */ 643/* Note: both the queue and the usb locks should be held when calling this */
557static void gspca_stream_off(struct gspca_dev *gspca_dev) 644static void gspca_stream_off(struct gspca_dev *gspca_dev)
558{ 645{
559 gspca_dev->streaming = 0; 646 gspca_dev->streaming = 0;
@@ -759,6 +846,16 @@ out:
759 return ret; 846 return ret;
760} 847}
761 848
849static void gspca_delete(struct kref *kref)
850{
851 struct gspca_dev *gspca_dev = container_of(kref, struct gspca_dev, kref);
852
853 PDEBUG(D_STREAM, "device deleted");
854
855 kfree(gspca_dev->usb_buf);
856 kfree(gspca_dev);
857}
858
762static int dev_open(struct inode *inode, struct file *file) 859static int dev_open(struct inode *inode, struct file *file)
763{ 860{
764 struct gspca_dev *gspca_dev; 861 struct gspca_dev *gspca_dev;
@@ -778,13 +875,19 @@ static int dev_open(struct inode *inode, struct file *file)
778 goto out; 875 goto out;
779 } 876 }
780 gspca_dev->users++; 877 gspca_dev->users++;
878
879 /* one more user */
880 kref_get(&gspca_dev->kref);
881
781 file->private_data = gspca_dev; 882 file->private_data = gspca_dev;
782#ifdef GSPCA_DEBUG 883#ifdef GSPCA_DEBUG
783 /* activate the v4l2 debug */ 884 /* activate the v4l2 debug */
784 if (gspca_debug & D_V4L2) 885 if (gspca_debug & D_V4L2)
785 gspca_dev->vdev.debug |= 3; 886 gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL
887 | V4L2_DEBUG_IOCTL_ARG;
786 else 888 else
787 gspca_dev->vdev.debug &= ~3; 889 gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
890 | V4L2_DEBUG_IOCTL_ARG);
788#endif 891#endif
789 ret = 0; 892 ret = 0;
790out: 893out:
@@ -818,7 +921,11 @@ static int dev_close(struct inode *inode, struct file *file)
818 } 921 }
819 file->private_data = NULL; 922 file->private_data = NULL;
820 mutex_unlock(&gspca_dev->queue_lock); 923 mutex_unlock(&gspca_dev->queue_lock);
924
821 PDEBUG(D_STREAM, "close done"); 925 PDEBUG(D_STREAM, "close done");
926
927 kref_put(&gspca_dev->kref, gspca_delete);
928
822 return 0; 929 return 0;
823} 930}
824 931
@@ -829,7 +936,6 @@ static int vidioc_querycap(struct file *file, void *priv,
829 936
830 memset(cap, 0, sizeof *cap); 937 memset(cap, 0, sizeof *cap);
831 strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); 938 strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
832/* strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); */
833 if (gspca_dev->dev->product != NULL) { 939 if (gspca_dev->dev->product != NULL) {
834 strncpy(cap->card, gspca_dev->dev->product, 940 strncpy(cap->card, gspca_dev->dev->product,
835 sizeof cap->card); 941 sizeof cap->card);
@@ -1463,7 +1569,6 @@ static int vidioc_qbuf(struct file *file, void *priv,
1463 } 1569 }
1464 1570
1465 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED; 1571 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;
1466/* frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; */
1467 1572
1468 if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { 1573 if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) {
1469 frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; 1574 frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr;
@@ -1610,7 +1715,7 @@ static ssize_t dev_read(struct file *file, char __user *data,
1610 } 1715 }
1611 1716
1612 /* if the process slept for more than 1 second, 1717 /* if the process slept for more than 1 second,
1613 * get anewer frame */ 1718 * get a newer frame */
1614 frame = &gspca_dev->frame[v4l2_buf.index]; 1719 frame = &gspca_dev->frame[v4l2_buf.index];
1615 if (--n < 0) 1720 if (--n < 0)
1616 break; /* avoid infinite loop */ 1721 break; /* avoid infinite loop */
@@ -1728,21 +1833,21 @@ int gspca_dev_probe(struct usb_interface *intf,
1728 if (dev_size < sizeof *gspca_dev) 1833 if (dev_size < sizeof *gspca_dev)
1729 dev_size = sizeof *gspca_dev; 1834 dev_size = sizeof *gspca_dev;
1730 gspca_dev = kzalloc(dev_size, GFP_KERNEL); 1835 gspca_dev = kzalloc(dev_size, GFP_KERNEL);
1731 if (gspca_dev == NULL) { 1836 if (!gspca_dev) {
1732 err("couldn't kzalloc gspca struct"); 1837 err("couldn't kzalloc gspca struct");
1733 return -EIO; 1838 return -ENOMEM;
1734 } 1839 }
1840 kref_init(&gspca_dev->kref);
1735 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL); 1841 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
1736 if (!gspca_dev->usb_buf) { 1842 if (!gspca_dev->usb_buf) {
1737 err("out of memory"); 1843 err("out of memory");
1738 ret = -EIO; 1844 ret = -ENOMEM;
1739 goto out; 1845 goto out;
1740 } 1846 }
1741 gspca_dev->dev = dev; 1847 gspca_dev->dev = dev;
1742 gspca_dev->iface = interface->bInterfaceNumber; 1848 gspca_dev->iface = interface->bInterfaceNumber;
1743 gspca_dev->nbalt = intf->num_altsetting; 1849 gspca_dev->nbalt = intf->num_altsetting;
1744 gspca_dev->sd_desc = sd_desc; 1850 gspca_dev->sd_desc = sd_desc;
1745/* gspca_dev->users = 0; (done by kzalloc) */
1746 gspca_dev->nbufread = 2; 1851 gspca_dev->nbufread = 2;
1747 1852
1748 /* configure the subdriver and initialize the USB device */ 1853 /* configure the subdriver and initialize the USB device */
@@ -1781,8 +1886,7 @@ int gspca_dev_probe(struct usb_interface *intf,
1781 PDEBUG(D_PROBE, "probe ok"); 1886 PDEBUG(D_PROBE, "probe ok");
1782 return 0; 1887 return 0;
1783out: 1888out:
1784 kfree(gspca_dev->usb_buf); 1889 kref_put(&gspca_dev->kref, gspca_delete);
1785 kfree(gspca_dev);
1786 return ret; 1890 return ret;
1787} 1891}
1788EXPORT_SYMBOL(gspca_dev_probe); 1892EXPORT_SYMBOL(gspca_dev_probe);
@@ -1797,25 +1901,16 @@ void gspca_disconnect(struct usb_interface *intf)
1797{ 1901{
1798 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 1902 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
1799 1903
1800 if (!gspca_dev) 1904 usb_set_intfdata(intf, NULL);
1801 return; 1905
1802 gspca_dev->present = 0;
1803 mutex_lock(&gspca_dev->queue_lock);
1804 mutex_lock(&gspca_dev->usb_lock);
1805 gspca_dev->streaming = 0;
1806 destroy_urbs(gspca_dev);
1807 mutex_unlock(&gspca_dev->usb_lock);
1808 mutex_unlock(&gspca_dev->queue_lock);
1809 while (gspca_dev->users != 0) { /* wait until fully closed */
1810 atomic_inc(&gspca_dev->nevent);
1811 wake_up_interruptible(&gspca_dev->wq); /* wake processes */
1812 schedule();
1813 }
1814/* We don't want people trying to open up the device */ 1906/* We don't want people trying to open up the device */
1815 video_unregister_device(&gspca_dev->vdev); 1907 video_unregister_device(&gspca_dev->vdev);
1816/* Free the memory */ 1908
1817 kfree(gspca_dev->usb_buf); 1909 gspca_dev->present = 0;
1818 kfree(gspca_dev); 1910 gspca_dev->streaming = 0;
1911
1912 kref_put(&gspca_dev->kref, gspca_delete);
1913
1819 PDEBUG(D_PROBE, "disconnect complete"); 1914 PDEBUG(D_PROBE, "disconnect complete");
1820} 1915}
1821EXPORT_SYMBOL(gspca_disconnect); 1916EXPORT_SYMBOL(gspca_disconnect);
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index c17625cff9ba..4779dd0b06da 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -49,13 +49,14 @@ extern int gspca_debug;
49 } while (0) 49 } while (0)
50 50
51#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ 51#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
52/* ISOC transfers */ 52/* image transfers */
53#define MAX_NURBS 16 /* max number of URBs */ 53#define MAX_NURBS 4 /* max number of URBs */
54#define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ 54#define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */
55#define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ 55#define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */
56 56
57/* device information - set at probe time */ 57/* device information - set at probe time */
58struct cam { 58struct cam {
59 int bulk_size; /* buffer size when image transfer by bulk */
59 struct v4l2_pix_format *cam_mode; /* size nmodes */ 60 struct v4l2_pix_format *cam_mode; /* size nmodes */
60 char nmodes; 61 char nmodes;
61 __u8 epaddr; 62 __u8 epaddr;
@@ -93,7 +94,7 @@ struct sd_desc {
93/* mandatory operations */ 94/* mandatory operations */
94 cam_cf_op config; /* called on probe */ 95 cam_cf_op config; /* called on probe */
95 cam_op init; /* called on probe and resume */ 96 cam_op init; /* called on probe and resume */
96 cam_v_op start; /* called on stream on */ 97 cam_op start; /* called on stream on */
97 cam_pkt_op pkt_scan; 98 cam_pkt_op pkt_scan;
98/* optional operations */ 99/* optional operations */
99 cam_v_op stopN; /* called on stream off - main alt */ 100 cam_v_op stopN; /* called on stream off - main alt */
@@ -105,10 +106,12 @@ struct sd_desc {
105}; 106};
106 107
107/* packet types when moving from iso buf to frame buf */ 108/* packet types when moving from iso buf to frame buf */
108#define DISCARD_PACKET 0 109enum gspca_packet_type {
109#define FIRST_PACKET 1 110 DISCARD_PACKET,
110#define INTER_PACKET 2 111 FIRST_PACKET,
111#define LAST_PACKET 3 112 INTER_PACKET,
113 LAST_PACKET
114};
112 115
113struct gspca_frame { 116struct gspca_frame {
114 __u8 *data; /* frame buffer */ 117 __u8 *data; /* frame buffer */
@@ -121,6 +124,7 @@ struct gspca_dev {
121 struct video_device vdev; /* !! must be the first item */ 124 struct video_device vdev; /* !! must be the first item */
122 struct file_operations fops; 125 struct file_operations fops;
123 struct usb_device *dev; 126 struct usb_device *dev;
127 struct kref kref;
124 struct file *capt_file; /* file doing video capture */ 128 struct file *capt_file; /* file doing video capture */
125 129
126 struct cam cam; /* device information */ 130 struct cam cam; /* device information */
@@ -173,10 +177,11 @@ int gspca_dev_probe(struct usb_interface *intf,
173 struct module *module); 177 struct module *module);
174void gspca_disconnect(struct usb_interface *intf); 178void gspca_disconnect(struct usb_interface *intf);
175struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 179struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
176 int packet_type, 180 enum gspca_packet_type packet_type,
177 struct gspca_frame *frame, 181 struct gspca_frame *frame,
178 const __u8 *data, 182 const __u8 *data,
179 int len); 183 int len);
184struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev);
180#ifdef CONFIG_PM 185#ifdef CONFIG_PM
181int gspca_suspend(struct usb_interface *intf, pm_message_t message); 186int gspca_suspend(struct usb_interface *intf, pm_message_t message);
182int gspca_resume(struct usb_interface *intf); 187int gspca_resume(struct usb_interface *intf);
diff --git a/drivers/media/video/gspca/m5602/Kconfig b/drivers/media/video/gspca/m5602/Kconfig
new file mode 100644
index 000000000000..5a69016ed75f
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/Kconfig
@@ -0,0 +1,11 @@
1config USB_M5602
2 tristate "ALi USB m5602 Camera Driver"
3 depends on VIDEO_V4L2 && USB_GSPCA
4 help
5 Say Y here if you want support for cameras based on the
6 ALi m5602 connected to various image sensors.
7
8 See <file:Documentation/video4linux/m5602.txt> for more info.
9
10 To compile this driver as a module, choose M here: the
11 module will be called gspca_m5602.
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile
new file mode 100644
index 000000000000..226ab4fc9d60
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/Makefile
@@ -0,0 +1,11 @@
1obj-$(CONFIG_USB_M5602) += gspca_m5602.o
2
3gspca_m5602-objs := m5602_core.o \
4 m5602_ov9650.o \
5 m5602_mt9m111.o \
6 m5602_po1030.o \
7 m5602_s5k83a.o \
8 m5602_s5k4aa.o
9
10EXTRA_CFLAGS += -Idrivers/media/video/gspca
11
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
new file mode 100644
index 000000000000..c786d7d3d44a
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -0,0 +1,170 @@
1/*
2 * USB Driver for ALi m5602 based webcams
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#ifndef M5602_BRIDGE_H_
20#define M5602_BRIDGE_H_
21
22#include "gspca.h"
23
24#define MODULE_NAME "ALi m5602"
25
26/*****************************************************************************/
27
28#undef PDEBUG
29#undef info
30#undef err
31
32#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \
33 format "\n" , ## arg)
34#define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \
35 format "\n" , ## arg)
36
37/* Debug parameters */
38#define DBG_INIT 0x1
39#define DBG_PROBE 0x2
40#define DBG_V4L2 0x4
41#define DBG_TRACE 0x8
42#define DBG_DATA 0x10
43#define DBG_V4L2_CID 0x20
44#define DBG_GSPCA 0x40
45
46#define PDEBUG(level, fmt, args...) \
47 do { \
48 if (m5602_debug & level) \
49 info("[%s:%d] " fmt, __func__, __LINE__ , \
50 ## args); \
51 } while (0)
52
53/*****************************************************************************/
54
55#define M5602_XB_SENSOR_TYPE 0x00
56#define M5602_XB_SENSOR_CTRL 0x01
57#define M5602_XB_LINE_OF_FRAME_H 0x02
58#define M5602_XB_LINE_OF_FRAME_L 0x03
59#define M5602_XB_PIX_OF_LINE_H 0x04
60#define M5602_XB_PIX_OF_LINE_L 0x05
61#define M5602_XB_VSYNC_PARA 0x06
62#define M5602_XB_HSYNC_PARA 0x07
63#define M5602_XB_TEST_MODE_1 0x08
64#define M5602_XB_TEST_MODE_2 0x09
65#define M5602_XB_SIG_INI 0x0a
66#define M5602_XB_DS_PARA 0x0e
67#define M5602_XB_TRIG_PARA 0x0f
68#define M5602_XB_CLK_PD 0x10
69#define M5602_XB_MCU_CLK_CTRL 0x12
70#define M5602_XB_MCU_CLK_DIV 0x13
71#define M5602_XB_SEN_CLK_CTRL 0x14
72#define M5602_XB_SEN_CLK_DIV 0x15
73#define M5602_XB_AUD_CLK_CTRL 0x16
74#define M5602_XB_AUD_CLK_DIV 0x17
75#define M5602_XB_DEVCTR1 0x41
76#define M5602_XB_EPSETR0 0x42
77#define M5602_XB_EPAFCTR 0x47
78#define M5602_XB_EPBFCTR 0x49
79#define M5602_XB_EPEFCTR 0x4f
80#define M5602_XB_TEST_REG 0x53
81#define M5602_XB_ALT2SIZE 0x54
82#define M5602_XB_ALT3SIZE 0x55
83#define M5602_XB_OBSFRAME 0x56
84#define M5602_XB_PWR_CTL 0x59
85#define M5602_XB_ADC_CTRL 0x60
86#define M5602_XB_ADC_DATA 0x61
87#define M5602_XB_MISC_CTRL 0x62
88#define M5602_XB_SNAPSHOT 0x63
89#define M5602_XB_SCRATCH_1 0x64
90#define M5602_XB_SCRATCH_2 0x65
91#define M5602_XB_SCRATCH_3 0x66
92#define M5602_XB_SCRATCH_4 0x67
93#define M5602_XB_I2C_CTRL 0x68
94#define M5602_XB_I2C_CLK_DIV 0x69
95#define M5602_XB_I2C_DEV_ADDR 0x6a
96#define M5602_XB_I2C_REG_ADDR 0x6b
97#define M5602_XB_I2C_DATA 0x6c
98#define M5602_XB_I2C_STATUS 0x6d
99#define M5602_XB_GPIO_DAT_H 0x70
100#define M5602_XB_GPIO_DAT_L 0x71
101#define M5602_XB_GPIO_DIR_H 0x72
102#define M5602_XB_GPIO_DIR_L 0x73
103#define M5602_XB_GPIO_EN_H 0x74
104#define M5602_XB_GPIO_EN_L 0x75
105#define M5602_XB_GPIO_DAT 0x76
106#define M5602_XB_GPIO_DIR 0x77
107#define M5602_XB_MISC_CTL 0x70
108
109#define I2C_BUSY 0x80
110
111/*****************************************************************************/
112
113/* Driver info */
114#define DRIVER_AUTHOR "ALi m5602 Linux Driver Project"
115#define DRIVER_DESC "ALi m5602 webcam driver"
116
117#define M5602_ISOC_ENDPOINT_ADDR 0x81
118#define M5602_INTR_ENDPOINT_ADDR 0x82
119
120#define M5602_MAX_FRAMES 32
121#define M5602_URBS 2
122#define M5602_ISOC_PACKETS 14
123
124#define M5602_URB_TIMEOUT msecs_to_jiffies(2 * M5602_ISOC_PACKETS)
125#define M5602_URB_MSG_TIMEOUT 5000
126#define M5602_FRAME_TIMEOUT 2
127
128/*****************************************************************************/
129
130/* A skeleton used for sending messages to the m5602 bridge */
131static const unsigned char bridge_urb_skeleton[] = {
132 0x13, 0x00, 0x81, 0x00
133};
134
135/* A skeleton used for sending messages to the sensor */
136static const unsigned char sensor_urb_skeleton[] = {
137 0x23, M5602_XB_GPIO_EN_H, 0x81, 0x06,
138 0x23, M5602_XB_MISC_CTRL, 0x81, 0x80,
139 0x13, M5602_XB_I2C_DEV_ADDR, 0x81, 0x00,
140 0x13, M5602_XB_I2C_REG_ADDR, 0x81, 0x00,
141 0x13, M5602_XB_I2C_DATA, 0x81, 0x00,
142 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11
143};
144
145/* m5602 device descriptor, currently it just wraps the m5602_camera struct */
146struct sd {
147 struct gspca_dev gspca_dev;
148
149 /* The name of the m5602 camera */
150 char *name;
151
152 /* A pointer to the currently connected sensor */
153 struct m5602_sensor *sensor;
154
155 struct sd_desc *desc;
156
157 /* The current frame's id, used to detect frame boundaries */
158 u8 frame_id;
159
160 /* The current frame count */
161 u32 frame_count;
162};
163
164int m5602_read_bridge(
165 struct sd *sd, u8 address, u8 *i2c_data);
166
167int m5602_write_bridge(
168 struct sd *sd, u8 address, u8 i2c_data);
169
170#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
new file mode 100644
index 000000000000..19d5e351ccc1
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -0,0 +1,313 @@
1/*
2 * USB Driver for ALi m5602 based webcams
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#include "m5602_ov9650.h"
20#include "m5602_mt9m111.h"
21#include "m5602_po1030.h"
22#include "m5602_s5k83a.h"
23#include "m5602_s5k4aa.h"
24
25/* Kernel module parameters */
26int force_sensor;
27int dump_bridge;
28int dump_sensor;
29unsigned int m5602_debug;
30
31static const __devinitdata struct usb_device_id m5602_table[] = {
32 {USB_DEVICE(0x0402, 0x5602)},
33 {}
34};
35
36MODULE_DEVICE_TABLE(usb, m5602_table);
37
38/* Reads a byte from the m5602 */
39int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
40{
41 int err;
42 struct usb_device *udev = sd->gspca_dev.dev;
43 __u8 *buf = sd->gspca_dev.usb_buf;
44
45 err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
46 0x04, 0xc0, 0x14,
47 0x8100 + address, buf,
48 1, M5602_URB_MSG_TIMEOUT);
49 *i2c_data = buf[0];
50
51 PDEBUG(DBG_TRACE, "Reading bridge register 0x%x containing 0x%x",
52 address, *i2c_data);
53
54 /* usb_control_msg(...) returns the number of bytes sent upon success,
55 mask that and return zero upon success instead*/
56 return (err < 0) ? err : 0;
57}
58
59/* Writes a byte to to the m5602 */
60int m5602_write_bridge(struct sd *sd, u8 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 PDEBUG(DBG_TRACE, "Writing bridge register 0x%x with 0x%x",
67 address, i2c_data);
68
69 memcpy(buf, bridge_urb_skeleton,
70 sizeof(bridge_urb_skeleton));
71 buf[1] = address;
72 buf[3] = i2c_data;
73
74 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
75 0x04, 0x40, 0x19,
76 0x0000, buf,
77 4, M5602_URB_MSG_TIMEOUT);
78
79 /* usb_control_msg(...) returns the number of bytes sent upon success,
80 mask that and return zero upon success instead */
81 return (err < 0) ? err : 0;
82}
83
84/* Dump all the registers of the m5602 bridge,
85 unfortunately this breaks the camera until it's power cycled */
86static void m5602_dump_bridge(struct sd *sd)
87{
88 int i;
89 for (i = 0; i < 0x80; i++) {
90 unsigned char val = 0;
91 m5602_read_bridge(sd, i, &val);
92 info("ALi m5602 address 0x%x contains 0x%x", i, val);
93 }
94 info("Warning: The camera probably won't work until it's power cycled");
95}
96
97static int m5602_probe_sensor(struct sd *sd)
98{
99 /* Try the po1030 */
100 sd->sensor = &po1030;
101 if (!sd->sensor->probe(sd))
102 return 0;
103
104 /* Try the mt9m111 sensor */
105 sd->sensor = &mt9m111;
106 if (!sd->sensor->probe(sd))
107 return 0;
108
109 /* Try the s5k4aa */
110 sd->sensor = &s5k4aa;
111 if (!sd->sensor->probe(sd))
112 return 0;
113
114 /* Try the ov9650 */
115 sd->sensor = &ov9650;
116 if (!sd->sensor->probe(sd))
117 return 0;
118
119 /* Try the s5k83a */
120 sd->sensor = &s5k83a;
121 if (!sd->sensor->probe(sd))
122 return 0;
123
124 /* More sensor probe function goes here */
125 info("Failed to find a sensor");
126 sd->sensor = NULL;
127 return -ENODEV;
128}
129
130static int m5602_configure(struct gspca_dev *gspca_dev,
131 const struct usb_device_id *id);
132
133static int m5602_init(struct gspca_dev *gspca_dev)
134{
135 struct sd *sd = (struct sd *) gspca_dev;
136 int err;
137
138 PDEBUG(DBG_TRACE, "Initializing ALi m5602 webcam");
139 /* Run the init sequence */
140 err = sd->sensor->init(sd);
141
142 return err;
143}
144
145static int m5602_start_transfer(struct gspca_dev *gspca_dev)
146{
147 struct sd *sd = (struct sd *) gspca_dev;
148 __u8 *buf = sd->gspca_dev.usb_buf;
149
150 /* Send start command to the camera */
151 const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01};
152 memcpy(buf, buffer, sizeof(buffer));
153 usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
154 0x04, 0x40, 0x19, 0x0000, buf,
155 4, M5602_URB_MSG_TIMEOUT);
156
157 PDEBUG(DBG_V4L2, "Transfer started");
158 return 0;
159}
160
161static void m5602_urb_complete(struct gspca_dev *gspca_dev,
162 struct gspca_frame *frame,
163 __u8 *data, int len)
164{
165 struct sd *sd = (struct sd *) gspca_dev;
166
167 if (len < 6) {
168 PDEBUG(DBG_DATA, "Packet is less than 6 bytes");
169 return;
170 }
171
172 /* Frame delimiter: ff xx xx xx ff ff */
173 if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff &&
174 data[2] != sd->frame_id) {
175 PDEBUG(DBG_DATA, "Frame delimiter detected");
176 sd->frame_id = data[2];
177
178 /* Remove the extra fluff appended on each header */
179 data += 6;
180 len -= 6;
181
182 /* Complete the last frame (if any) */
183 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
184 frame, data, 0);
185 sd->frame_count++;
186
187 /* Create a new frame */
188 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
189
190 PDEBUG(DBG_V4L2, "Starting new frame %d",
191 sd->frame_count);
192
193 } else {
194 int cur_frame_len = frame->data_end - frame->data;
195
196 /* Remove urb header */
197 data += 4;
198 len -= 4;
199
200 if (cur_frame_len + len <= frame->v4l2_buf.length) {
201 PDEBUG(DBG_DATA, "Continuing frame %d copying %d bytes",
202 sd->frame_count, len);
203
204 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
205 data, len);
206 } else if (frame->v4l2_buf.length - cur_frame_len > 0) {
207 /* Add the remaining data up to frame size */
208 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data,
209 frame->v4l2_buf.length - cur_frame_len);
210 }
211 }
212}
213
214static void m5602_stop_transfer(struct gspca_dev *gspca_dev)
215{
216 /* Is there are a command to stop a data transfer? */
217}
218
219/* sub-driver description, the ctrl and nctrl is filled at probe time */
220static struct sd_desc sd_desc = {
221 .name = MODULE_NAME,
222 .config = m5602_configure,
223 .init = m5602_init,
224 .start = m5602_start_transfer,
225 .stopN = m5602_stop_transfer,
226 .pkt_scan = m5602_urb_complete
227};
228
229/* this function is called at probe time */
230static int m5602_configure(struct gspca_dev *gspca_dev,
231 const struct usb_device_id *id)
232{
233 struct sd *sd = (struct sd *) gspca_dev;
234 struct cam *cam;
235 int err;
236
237 PDEBUG(DBG_GSPCA, "m5602_configure start");
238
239 cam = &gspca_dev->cam;
240 cam->epaddr = M5602_ISOC_ENDPOINT_ADDR;
241 sd->desc = &sd_desc;
242
243 if (dump_bridge)
244 m5602_dump_bridge(sd);
245
246 /* Probe sensor */
247 err = m5602_probe_sensor(sd);
248 if (err)
249 goto fail;
250
251 PDEBUG(DBG_GSPCA, "m5602_configure end");
252 return 0;
253
254fail:
255 PDEBUG(DBG_GSPCA, "m5602_configure failed");
256 cam->cam_mode = NULL;
257 cam->nmodes = 0;
258
259 return err;
260}
261
262static int m5602_probe(struct usb_interface *intf,
263 const struct usb_device_id *id)
264{
265 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
266 THIS_MODULE);
267}
268
269static struct usb_driver sd_driver = {
270 .name = MODULE_NAME,
271 .id_table = m5602_table,
272 .probe = m5602_probe,
273#ifdef CONFIG_PM
274 .suspend = gspca_suspend,
275 .resume = gspca_resume,
276#endif
277 .disconnect = gspca_disconnect
278};
279
280/* -- module insert / remove -- */
281static int __init mod_m5602_init(void)
282{
283 if (usb_register(&sd_driver) < 0)
284 return -1;
285 PDEBUG(D_PROBE, "m5602 module registered");
286 return 0;
287}
288static void __exit mod_m5602_exit(void)
289{
290 usb_deregister(&sd_driver);
291 PDEBUG(D_PROBE, "m5602 module deregistered");
292}
293
294module_init(mod_m5602_init);
295module_exit(mod_m5602_exit);
296
297MODULE_AUTHOR(DRIVER_AUTHOR);
298MODULE_DESCRIPTION(DRIVER_DESC);
299MODULE_LICENSE("GPL");
300module_param_named(debug, m5602_debug, int, S_IRUGO | S_IWUSR);
301MODULE_PARM_DESC(debug, "toggles debug on/off");
302
303module_param(force_sensor, int, S_IRUGO | S_IWUSR);
304MODULE_PARM_DESC(force_sensor,
305 "force detection of sensor, "
306 "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030");
307
308module_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
309MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
310
311module_param(dump_sensor, bool, S_IRUGO | S_IWUSR);
312MODULE_PARM_DESC(dump_sensor, "Dumps all usb sensor registers "
313 "at startup providing a sensor is found");
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
new file mode 100644
index 000000000000..566d4925a0e8
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -0,0 +1,345 @@
1/*
2 * Driver for the mt9m111 sensor
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#include "m5602_mt9m111.h"
20
21int mt9m111_probe(struct sd *sd)
22{
23 u8 data[2] = {0x00, 0x00};
24 int i;
25
26 if (force_sensor) {
27 if (force_sensor == MT9M111_SENSOR) {
28 info("Forcing a %s sensor", mt9m111.name);
29 goto sensor_found;
30 }
31 /* If we want to force another sensor, don't try to probe this
32 * one */
33 return -ENODEV;
34 }
35
36 info("Probing for a mt9m111 sensor");
37
38 /* Do the preinit */
39 for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
40 if (preinit_mt9m111[i][0] == BRIDGE) {
41 m5602_write_bridge(sd,
42 preinit_mt9m111[i][1],
43 preinit_mt9m111[i][2]);
44 } else {
45 data[0] = preinit_mt9m111[i][2];
46 data[1] = preinit_mt9m111[i][3];
47 mt9m111_write_sensor(sd,
48 preinit_mt9m111[i][1], data, 2);
49 }
50 }
51
52 if (mt9m111_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2))
53 return -ENODEV;
54
55 if ((data[0] == 0x14) && (data[1] == 0x3a)) {
56 info("Detected a mt9m111 sensor");
57 goto sensor_found;
58 }
59
60 return -ENODEV;
61
62sensor_found:
63 sd->gspca_dev.cam.cam_mode = mt9m111.modes;
64 sd->gspca_dev.cam.nmodes = mt9m111.nmodes;
65 sd->desc->ctrls = mt9m111.ctrls;
66 sd->desc->nctrls = mt9m111.nctrls;
67 return 0;
68}
69
70int mt9m111_init(struct sd *sd)
71{
72 int i, err = 0;
73
74 /* Init the sensor */
75 for (i = 0; i < ARRAY_SIZE(init_mt9m111); i++) {
76 u8 data[2];
77
78 if (init_mt9m111[i][0] == BRIDGE) {
79 err = m5602_write_bridge(sd,
80 init_mt9m111[i][1],
81 init_mt9m111[i][2]);
82 } else {
83 data[0] = init_mt9m111[i][2];
84 data[1] = init_mt9m111[i][3];
85 err = mt9m111_write_sensor(sd,
86 init_mt9m111[i][1], data, 2);
87 }
88 }
89
90 if (dump_sensor)
91 mt9m111_dump_registers(sd);
92
93 return (err < 0) ? err : 0;
94}
95
96int mt9m111_power_down(struct sd *sd)
97{
98 return 0;
99}
100
101int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
102{
103 int err;
104 u8 data[2] = {0x00, 0x00};
105 struct sd *sd = (struct sd *) gspca_dev;
106
107 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
108 data, 2);
109 *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
110 PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
111
112 return (err < 0) ? err : 0;
113}
114
115int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
116{
117 int err;
118 u8 data[2] = {0x00, 0x00};
119 struct sd *sd = (struct sd *) gspca_dev;
120
121 PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
122
123 /* Set the correct page map */
124 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
125 if (err < 0)
126 goto out;
127
128 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
129 if (err < 0)
130 goto out;
131
132 data[0] = (data[0] & 0xfe) | val;
133 err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
134 data, 2);
135out:
136 return (err < 0) ? err : 0;
137}
138
139int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
140{
141 int err;
142 u8 data[2] = {0x00, 0x00};
143 struct sd *sd = (struct sd *) gspca_dev;
144
145 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
146 data, 2);
147 *val = data[0] & MT9M111_RMB_MIRROR_COLS;
148 PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
149
150 return (err < 0) ? err : 0;
151}
152
153int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
154{
155 int err;
156 u8 data[2] = {0x00, 0x00};
157 struct sd *sd = (struct sd *) gspca_dev;
158
159 PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val);
160
161 /* Set the correct page map */
162 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
163 if (err < 0)
164 goto out;
165
166 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
167 if (err < 0)
168 goto out;
169
170 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
171 err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
172 data, 2);
173out:
174 return (err < 0) ? err : 0;
175}
176
177int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
178{
179 int err, tmp;
180 u8 data[2] = {0x00, 0x00};
181 struct sd *sd = (struct sd *) gspca_dev;
182
183 err = mt9m111_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2);
184 tmp = ((data[1] << 8) | data[0]);
185
186 *val = ((tmp & (1 << 10)) * 2) |
187 ((tmp & (1 << 9)) * 2) |
188 ((tmp & (1 << 8)) * 2) |
189 (tmp & 0x7f);
190
191 PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
192
193 return (err < 0) ? err : 0;
194}
195
196int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
197{
198 int err, tmp;
199 u8 data[2] = {0x00, 0x00};
200 struct sd *sd = (struct sd *) gspca_dev;
201
202 /* Set the correct page map */
203 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
204 if (err < 0)
205 goto out;
206
207 if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2)
208 return -EINVAL;
209
210 if ((val >= INITIAL_MAX_GAIN * 2 * 2) &&
211 (val < (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2))
212 tmp = (1 << 10) | (val << 9) |
213 (val << 8) | (val / 8);
214 else if ((val >= INITIAL_MAX_GAIN * 2) &&
215 (val < INITIAL_MAX_GAIN * 2 * 2))
216 tmp = (1 << 9) | (1 << 8) | (val / 4);
217 else if ((val >= INITIAL_MAX_GAIN) &&
218 (val < INITIAL_MAX_GAIN * 2))
219 tmp = (1 << 8) | (val / 2);
220 else
221 tmp = val;
222
223 data[1] = (tmp & 0xff00) >> 8;
224 data[0] = (tmp & 0xff);
225 PDEBUG(DBG_V4L2_CID, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
226 data[1], data[0]);
227
228 err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
229 data, 2);
230out:
231 return (err < 0) ? err : 0;
232}
233
234int mt9m111_read_sensor(struct sd *sd, const u8 address,
235 u8 *i2c_data, const u8 len) {
236 int err, i;
237
238 do {
239 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
240 } while ((*i2c_data & I2C_BUSY) && !err);
241 if (err < 0)
242 goto out;
243
244 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
245 sd->sensor->i2c_slave_id);
246 if (err < 0)
247 goto out;
248
249 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
250 if (err < 0)
251 goto out;
252
253 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x1a);
254 if (err < 0)
255 goto out;
256
257 for (i = 0; i < len && !err; i++) {
258 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
259
260 PDEBUG(DBG_TRACE, "Reading sensor register "
261 "0x%x contains 0x%x ", address, *i2c_data);
262 }
263out:
264 return (err < 0) ? err : 0;
265}
266
267int mt9m111_write_sensor(struct sd *sd, const u8 address,
268 u8 *i2c_data, const u8 len)
269{
270 int err, i;
271 u8 *p;
272 struct usb_device *udev = sd->gspca_dev.dev;
273 __u8 *buf = sd->gspca_dev.usb_buf;
274
275 /* No sensor with a data width larger
276 than 16 bits has yet been seen, nor with 0 :p*/
277 if (len > 2 || !len)
278 return -EINVAL;
279
280 memcpy(buf, sensor_urb_skeleton,
281 sizeof(sensor_urb_skeleton));
282
283 buf[11] = sd->sensor->i2c_slave_id;
284 buf[15] = address;
285
286 p = buf + 16;
287
288 /* Copy a four byte write sequence for each byte to be written to */
289 for (i = 0; i < len; i++) {
290 memcpy(p, sensor_urb_skeleton + 16, 4);
291 p[3] = i2c_data[i];
292 p += 4;
293 PDEBUG(DBG_TRACE, "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}
310
311void mt9m111_dump_registers(struct sd *sd)
312{
313 u8 address, value[2] = {0x00, 0x00};
314
315 info("Dumping the mt9m111 register state");
316
317 info("Dumping the mt9m111 sensor core registers");
318 value[1] = MT9M111_SENSOR_CORE;
319 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
320 for (address = 0; address < 0xff; address++) {
321 mt9m111_read_sensor(sd, address, value, 2);
322 info("register 0x%x contains 0x%x%x",
323 address, value[0], value[1]);
324 }
325
326 info("Dumping the mt9m111 color pipeline registers");
327 value[1] = MT9M111_COLORPIPE;
328 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
329 for (address = 0; address < 0xff; address++) {
330 mt9m111_read_sensor(sd, address, value, 2);
331 info("register 0x%x contains 0x%x%x",
332 address, value[0], value[1]);
333 }
334
335 info("Dumping the mt9m111 camera control registers");
336 value[1] = MT9M111_CAMERA_CONTROL;
337 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
338 for (address = 0; address < 0xff; address++) {
339 mt9m111_read_sensor(sd, address, value, 2);
340 info("register 0x%x contains 0x%x%x",
341 address, value[0], value[1]);
342 }
343
344 info("mt9m111 register state dump complete");
345}
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
new file mode 100644
index 000000000000..79a5d8878190
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -0,0 +1,1020 @@
1/*
2 * Driver for the mt9m111 sensor
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * Some defines taken from the mt9m111 sensor driver
14 * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation, version 2.
19 *
20 */
21
22#ifndef M5602_MT9M111_H_
23#define M5602_MT9M111_H_
24
25#include "m5602_sensor.h"
26
27/*****************************************************************************/
28
29#define MT9M111_SC_CHIPVER 0x00
30#define MT9M111_SC_ROWSTART 0x01
31#define MT9M111_SC_COLSTART 0x02
32#define MT9M111_SC_WINDOW_HEIGHT 0x03
33#define MT9M111_SC_WINDOW_WIDTH 0x04
34#define MT9M111_SC_HBLANK_CONTEXT_B 0x05
35#define MT9M111_SC_VBLANK_CONTEXT_B 0x06
36#define MT9M111_SC_HBLANK_CONTEXT_A 0x07
37#define MT9M111_SC_VBLANK_CONTEXT_A 0x08
38#define MT9M111_SC_SHUTTER_WIDTH 0x09
39#define MT9M111_SC_ROW_SPEED 0x0a
40
41#define MT9M111_SC_EXTRA_DELAY 0x0b
42#define MT9M111_SC_SHUTTER_DELAY 0x0c
43#define MT9M111_SC_RESET 0x0d
44#define MT9M111_SC_R_MODE_CONTEXT_B 0x20
45#define MT9M111_SC_R_MODE_CONTEXT_A 0x21
46#define MT9M111_SC_FLASH_CONTROL 0x23
47#define MT9M111_SC_GREEN_1_GAIN 0x2b
48#define MT9M111_SC_BLUE_GAIN 0x2c
49#define MT9M111_SC_RED_GAIN 0x2d
50#define MT9M111_SC_GREEN_2_GAIN 0x2e
51#define MT9M111_SC_GLOBAL_GAIN 0x2f
52
53#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
54#define MT9M111_RMB_MIRROR_COLS (1 << 1)
55
56#define MT9M111_CONTEXT_CONTROL 0xc8
57#define MT9M111_PAGE_MAP 0xf0
58#define MT9M111_BYTEWISE_ADDRESS 0xf1
59
60#define MT9M111_CP_OPERATING_MODE_CTL 0x06
61#define MT9M111_CP_LUMA_OFFSET 0x34
62#define MT9M111_CP_LUMA_CLIP 0x35
63#define MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A 0x3a
64#define MT9M111_CP_LENS_CORRECTION_1 0x3b
65#define MT9M111_CP_DEFECT_CORR_CONTEXT_A 0x4c
66#define MT9M111_CP_DEFECT_CORR_CONTEXT_B 0x4d
67#define MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B 0x9b
68#define MT9M111_CP_GLOBAL_CLK_CONTROL 0xb3
69
70#define MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18 0x65
71#define MT9M111_CC_AWB_PARAMETER_7 0x28
72
73#define MT9M111_SENSOR_CORE 0x00
74#define MT9M111_COLORPIPE 0x01
75#define MT9M111_CAMERA_CONTROL 0x02
76
77#define INITIAL_MAX_GAIN 64
78#define DEFAULT_GAIN 283
79
80/*****************************************************************************/
81
82/* Kernel module parameters */
83extern int force_sensor;
84extern int dump_sensor;
85extern unsigned int m5602_debug;
86
87int mt9m111_probe(struct sd *sd);
88int mt9m111_init(struct sd *sd);
89int mt9m111_power_down(struct sd *sd);
90
91int mt9m111_read_sensor(struct sd *sd, const u8 address,
92 u8 *i2c_data, const u8 len);
93
94int mt9m111_write_sensor(struct sd *sd, const u8 address,
95 u8 *i2c_data, const u8 len);
96
97void mt9m111_dump_registers(struct sd *sd);
98
99int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
100int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
101int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
102int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
103int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
104int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
105
106static struct m5602_sensor mt9m111 = {
107 .name = "MT9M111",
108
109 .i2c_slave_id = 0xba,
110
111 .probe = mt9m111_probe,
112 .init = mt9m111_init,
113 .power_down = mt9m111_power_down,
114
115 .read_sensor = mt9m111_read_sensor,
116 .write_sensor = mt9m111_write_sensor,
117
118 .nctrls = 3,
119 .ctrls = {
120 {
121 {
122 .id = V4L2_CID_VFLIP,
123 .type = V4L2_CTRL_TYPE_BOOLEAN,
124 .name = "vertical flip",
125 .minimum = 0,
126 .maximum = 1,
127 .step = 1,
128 .default_value = 0
129 },
130 .set = mt9m111_set_vflip,
131 .get = mt9m111_get_vflip
132 }, {
133 {
134 .id = V4L2_CID_HFLIP,
135 .type = V4L2_CTRL_TYPE_BOOLEAN,
136 .name = "horizontal flip",
137 .minimum = 0,
138 .maximum = 1,
139 .step = 1,
140 .default_value = 0
141 },
142 .set = mt9m111_set_hflip,
143 .get = mt9m111_get_hflip
144 }, {
145 {
146 .id = V4L2_CID_GAIN,
147 .type = V4L2_CTRL_TYPE_INTEGER,
148 .name = "gain",
149 .minimum = 0,
150 .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
151 .step = 1,
152 .default_value = DEFAULT_GAIN,
153 .flags = V4L2_CTRL_FLAG_SLIDER
154 },
155 .set = mt9m111_set_hflip,
156 .get = mt9m111_get_hflip
157 }
158 },
159
160 .nmodes = 1,
161 .modes = {
162 {
163 M5602_DEFAULT_FRAME_WIDTH,
164 M5602_DEFAULT_FRAME_HEIGHT,
165 V4L2_PIX_FMT_SBGGR8,
166 V4L2_FIELD_NONE,
167 .sizeimage =
168 M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
169 .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
170 .colorspace = V4L2_COLORSPACE_SRGB,
171 .priv = 1
172 }
173 }
174};
175
176static const unsigned char preinit_mt9m111[][4] =
177{
178 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
179 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
180 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
181 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
182 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
183 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
184 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
185 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
186
187 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
188 {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7},
189
190 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
191 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
192 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
193 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
194 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
195 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
196 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
197 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
198
199 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
200 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
201 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
202 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
203 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
204 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
205
206 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}
207};
208
209static const unsigned char init_mt9m111[][4] =
210{
211 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
212 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
213 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
214 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
215 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
216 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
217 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
218 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
219 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
220 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
221 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
222
223 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
224 {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
225 {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
226 {SENSOR, MT9M111_SC_RESET, 0xff, 0xde},
227 {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
228 {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7},
229 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
230
231 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
232
233 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff},
234
235 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
236 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
237 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
238 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
239 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
240 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
241 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
242 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
243 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
244 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
245 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
246 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
247 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
248 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
249 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
250 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
251 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
252 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
253 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
254 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
255 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
256
257 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
258 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
259 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
260 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
261 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
262 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
263 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
264 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
265 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
266 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
267 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
268 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
269 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
270 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
271 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
272 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
273
274 {SENSOR, 0xcd, 0x00, 0x0e},
275 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
276 {SENSOR, 0xd0, 0x00, 0x40},
277 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
278 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
279 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
280 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
281 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
282 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
283 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
284 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
285 {SENSOR, 0x33, 0x03, 0x49},
286 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
287
288 {SENSOR, 0x33, 0x03, 0x49},
289 {SENSOR, 0x34, 0xc0, 0x19},
290 {SENSOR, 0x3f, 0x20, 0x20},
291 {SENSOR, 0x40, 0x20, 0x20},
292 {SENSOR, 0x5a, 0xc0, 0x0a},
293 {SENSOR, 0x70, 0x7b, 0x0a},
294 {SENSOR, 0x71, 0xff, 0x00},
295 {SENSOR, 0x72, 0x19, 0x0e},
296 {SENSOR, 0x73, 0x18, 0x0f},
297 {SENSOR, 0x74, 0x57, 0x32},
298 {SENSOR, 0x75, 0x56, 0x34},
299 {SENSOR, 0x76, 0x73, 0x35},
300 {SENSOR, 0x77, 0x30, 0x12},
301 {SENSOR, 0x78, 0x79, 0x02},
302 {SENSOR, 0x79, 0x75, 0x06},
303 {SENSOR, 0x7a, 0x77, 0x0a},
304 {SENSOR, 0x7b, 0x78, 0x09},
305 {SENSOR, 0x7c, 0x7d, 0x06},
306 {SENSOR, 0x7d, 0x31, 0x10},
307 {SENSOR, 0x7e, 0x00, 0x7e},
308 {SENSOR, 0x80, 0x59, 0x04},
309 {SENSOR, 0x81, 0x59, 0x04},
310 {SENSOR, 0x82, 0x57, 0x0a},
311 {SENSOR, 0x83, 0x58, 0x0b},
312 {SENSOR, 0x84, 0x47, 0x0c},
313 {SENSOR, 0x85, 0x48, 0x0e},
314 {SENSOR, 0x86, 0x5b, 0x02},
315 {SENSOR, 0x87, 0x00, 0x5c},
316 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
317 {SENSOR, 0x60, 0x00, 0x80},
318 {SENSOR, 0x61, 0x00, 0x00},
319 {SENSOR, 0x62, 0x00, 0x00},
320 {SENSOR, 0x63, 0x00, 0x00},
321 {SENSOR, 0x64, 0x00, 0x00},
322
323 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
324 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
325 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
326 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
327 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
328 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
329 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
330 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
331 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
332 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
333 {SENSOR, 0x30, 0x04, 0x00},
334
335 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
336 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
337 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
338 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
339 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
340 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
341 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
342 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
343 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
344 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
345 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
346 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
347 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
348 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
349 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
350 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
351 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
352 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
353 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
354 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
355 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
356 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
357 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
358 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
359 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
360 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
361 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
362
363 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
364 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
365 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
366 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
367 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
368 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
369 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
370 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
371 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
372 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
373 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
374 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
375 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
376 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
377 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
378 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
379 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
380 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
381 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
382 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
383 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
384 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
385 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
386 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
387
388 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
389 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
390 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
391 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
392 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
393 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
394 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
395 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
396 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
397 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
398 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
399 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
400 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
401 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
402 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
403 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
404 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
405 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
406 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
407 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
408 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
409 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
410 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
411 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
412 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
413 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
414 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
415 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
416 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
417 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
418
419 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
420 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
421 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
422 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
423 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
424 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
425 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
426 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
427 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
428 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
429 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
430 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
431 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
432 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
433 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
434
435 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
436 {SENSOR, 0xcd, 0x00, 0x0e},
437 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
438 {SENSOR, 0xd0, 0x00, 0x40},
439 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
440 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
441 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
442 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
443 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
444 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
445 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
446 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
447 {SENSOR, 0x33, 0x03, 0x49},
448 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
449
450 {SENSOR, 0x33, 0x03, 0x49},
451 {SENSOR, 0x34, 0xc0, 0x19},
452 {SENSOR, 0x3f, 0x20, 0x20},
453 {SENSOR, 0x40, 0x20, 0x20},
454 {SENSOR, 0x5a, 0xc0, 0x0a},
455 {SENSOR, 0x70, 0x7b, 0x0a},
456 {SENSOR, 0x71, 0xff, 0x00},
457 {SENSOR, 0x72, 0x19, 0x0e},
458 {SENSOR, 0x73, 0x18, 0x0f},
459 {SENSOR, 0x74, 0x57, 0x32},
460 {SENSOR, 0x75, 0x56, 0x34},
461 {SENSOR, 0x76, 0x73, 0x35},
462 {SENSOR, 0x77, 0x30, 0x12},
463 {SENSOR, 0x78, 0x79, 0x02},
464 {SENSOR, 0x79, 0x75, 0x06},
465 {SENSOR, 0x7a, 0x77, 0x0a},
466 {SENSOR, 0x7b, 0x78, 0x09},
467 {SENSOR, 0x7c, 0x7d, 0x06},
468 {SENSOR, 0x7d, 0x31, 0x10},
469 {SENSOR, 0x7e, 0x00, 0x7e},
470 {SENSOR, 0x80, 0x59, 0x04},
471 {SENSOR, 0x81, 0x59, 0x04},
472 {SENSOR, 0x82, 0x57, 0x0a},
473 {SENSOR, 0x83, 0x58, 0x0b},
474 {SENSOR, 0x84, 0x47, 0x0c},
475 {SENSOR, 0x85, 0x48, 0x0e},
476 {SENSOR, 0x86, 0x5b, 0x02},
477 {SENSOR, 0x87, 0x00, 0x5c},
478 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
479 {SENSOR, 0x60, 0x00, 0x80},
480 {SENSOR, 0x61, 0x00, 0x00},
481 {SENSOR, 0x62, 0x00, 0x00},
482 {SENSOR, 0x63, 0x00, 0x00},
483 {SENSOR, 0x64, 0x00, 0x00},
484
485 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
486 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
487 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
488 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
489 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
490 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
491 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
492 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
493 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
494 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
495 {SENSOR, 0x30, 0x04, 0x00},
496
497 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
498 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
499 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
500 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
501 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
502 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
503 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
504 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
505 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
506 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
507 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
508 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
509 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
510 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
511 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
512 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
513 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
514 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
515 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
516 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
517 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
518 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
519 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
520 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
521 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
522 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
523 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
524 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
525 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
526
527 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
528 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
529 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
530 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
531 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
532 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
533 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
534
535 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
536 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
537 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
538 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
539 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
540 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
541 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
542 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
543 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
544 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
545 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
546 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
547 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
548 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
549 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
550 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
551 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
552 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
553 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
554 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
555 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
556 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
557 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
558
559 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
560 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
561 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
562 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
563 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
564 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
565 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
566 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
567 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
568 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
569 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
570 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
571 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
572 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
573 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
574
575 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
576 {SENSOR, 0xcd, 0x00, 0x0e},
577 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
578 {SENSOR, 0xd0, 0x00, 0x40},
579 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
580 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
581 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
582 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
583 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
584 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
585 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
586 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
587 {SENSOR, 0x33, 0x03, 0x49},
588 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
589
590 {SENSOR, 0x33, 0x03, 0x49},
591 {SENSOR, 0x34, 0xc0, 0x19},
592 {SENSOR, 0x3f, 0x20, 0x20},
593 {SENSOR, 0x40, 0x20, 0x20},
594 {SENSOR, 0x5a, 0xc0, 0x0a},
595 {SENSOR, 0x70, 0x7b, 0x0a},
596 {SENSOR, 0x71, 0xff, 0x00},
597 {SENSOR, 0x72, 0x19, 0x0e},
598 {SENSOR, 0x73, 0x18, 0x0f},
599 {SENSOR, 0x74, 0x57, 0x32},
600 {SENSOR, 0x75, 0x56, 0x34},
601 {SENSOR, 0x76, 0x73, 0x35},
602 {SENSOR, 0x77, 0x30, 0x12},
603 {SENSOR, 0x78, 0x79, 0x02},
604 {SENSOR, 0x79, 0x75, 0x06},
605 {SENSOR, 0x7a, 0x77, 0x0a},
606 {SENSOR, 0x7b, 0x78, 0x09},
607 {SENSOR, 0x7c, 0x7d, 0x06},
608 {SENSOR, 0x7d, 0x31, 0x10},
609 {SENSOR, 0x7e, 0x00, 0x7e},
610 {SENSOR, 0x80, 0x59, 0x04},
611 {SENSOR, 0x81, 0x59, 0x04},
612 {SENSOR, 0x82, 0x57, 0x0a},
613 {SENSOR, 0x83, 0x58, 0x0b},
614 {SENSOR, 0x84, 0x47, 0x0c},
615 {SENSOR, 0x85, 0x48, 0x0e},
616 {SENSOR, 0x86, 0x5b, 0x02},
617 {SENSOR, 0x87, 0x00, 0x5c},
618 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
619 {SENSOR, 0x60, 0x00, 0x80},
620 {SENSOR, 0x61, 0x00, 0x00},
621 {SENSOR, 0x62, 0x00, 0x00},
622 {SENSOR, 0x63, 0x00, 0x00},
623 {SENSOR, 0x64, 0x00, 0x00},
624
625 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
626 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
627 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
628 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
629 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
630 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
631 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
632 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
633 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
634 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
635 {SENSOR, 0x30, 0x04, 0x00},
636
637 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
638 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
639 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
640 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
641 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
642 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
643 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
644 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
645 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
646 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
647 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
648 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
649 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
650 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
651 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
652 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
653 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
654 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
655 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
656 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
657 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
658 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
659 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
660 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
661 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
662 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
663 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
664 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
665 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
666 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
667 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
668 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
669 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
670 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
671 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
672 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
673 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
674 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
675 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
676 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
677 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
678 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
679 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
680 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
681 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
682 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
683 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
684 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
685 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
686 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
687 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
688 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
689 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
690 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
691 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
692 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
693 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
694 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
695 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
696 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
697 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
698 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
699 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
700 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
701 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
702 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
703 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
704 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
705 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
706 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
707 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
708 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
709 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
710 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
711 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
712 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
713 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
714 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
715 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
716 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
717 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
718 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
719 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
720 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
721 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
722 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
723 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
724 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
725
726 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
727 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
728 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
729 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
730 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
731 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
732 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
733 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
734 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
735 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
736
737 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
738 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
739 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
740 {SENSOR, 0xcd, 0x00, 0x0e},
741 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
742 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
743 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
744 {SENSOR, 0xd0, 0x00, 0x40},
745 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
746 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
747 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
748 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
749 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
750 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
751 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
752 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
753 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
754 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
755 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
756 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
757 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
758 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
759 {SENSOR, 0x33, 0x03, 0x49},
760 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
761 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
762 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
763
764 {SENSOR, 0x33, 0x03, 0x49},
765 {SENSOR, 0x34, 0xc0, 0x19},
766 {SENSOR, 0x3f, 0x20, 0x20},
767 {SENSOR, 0x40, 0x20, 0x20},
768 {SENSOR, 0x5a, 0xc0, 0x0a},
769 {SENSOR, 0x70, 0x7b, 0x0a},
770 {SENSOR, 0x71, 0xff, 0x00},
771 {SENSOR, 0x72, 0x19, 0x0e},
772 {SENSOR, 0x73, 0x18, 0x0f},
773 {SENSOR, 0x74, 0x57, 0x32},
774 {SENSOR, 0x75, 0x56, 0x34},
775 {SENSOR, 0x76, 0x73, 0x35},
776 {SENSOR, 0x77, 0x30, 0x12},
777 {SENSOR, 0x78, 0x79, 0x02},
778 {SENSOR, 0x79, 0x75, 0x06},
779 {SENSOR, 0x7a, 0x77, 0x0a},
780 {SENSOR, 0x7b, 0x78, 0x09},
781 {SENSOR, 0x7c, 0x7d, 0x06},
782 {SENSOR, 0x7d, 0x31, 0x10},
783 {SENSOR, 0x7e, 0x00, 0x7e},
784 {SENSOR, 0x80, 0x59, 0x04},
785 {SENSOR, 0x81, 0x59, 0x04},
786 {SENSOR, 0x82, 0x57, 0x0a},
787 {SENSOR, 0x83, 0x58, 0x0b},
788 {SENSOR, 0x84, 0x47, 0x0c},
789 {SENSOR, 0x85, 0x48, 0x0e},
790 {SENSOR, 0x86, 0x5b, 0x02},
791 {SENSOR, 0x87, 0x00, 0x5c},
792 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
793 {SENSOR, 0x60, 0x00, 0x80},
794 {SENSOR, 0x61, 0x00, 0x00},
795 {SENSOR, 0x62, 0x00, 0x00},
796 {SENSOR, 0x63, 0x00, 0x00},
797 {SENSOR, 0x64, 0x00, 0x00},
798 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
799 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12},
800 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00},
801 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10},
802 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60},
803 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
804 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60},
805 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
806 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f},
807 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
808 {SENSOR, 0x30, 0x04, 0x00},
809
810 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
811 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
812 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
813 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
814 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
815 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
816 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
817 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
818 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
819 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
820 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
821 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
822 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe3, 0x00},
823 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
824 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
825 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
826 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
827 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
828 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
829 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
830 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
831 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
832 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
833 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
834
835 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
836 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
837 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xe6},
838 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
839 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
840 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
841 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
842 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
843 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
844 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
845 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
846 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
847 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
848 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
849 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
850 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
851 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
852 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
853 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
854 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
855 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
856 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
857 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
858 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
859 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
860 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
861 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
862 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
863 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
864 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
865 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
866
867 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
868 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
869 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
870 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
871 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
872 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
873 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
874 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
875 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
876 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
877 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
878 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
879 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
880 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
881 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
882 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
883 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
884 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
885 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
886 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
887 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
888 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
889 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
890 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
891 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
892 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
893 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
894 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
895 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
896 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
897 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
898 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
899 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
900 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
901 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
902 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
903 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
904 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
905 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
906 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
907 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
908 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
909 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
910 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
911 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
912
913 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
914 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
915 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
916 {SENSOR, 0xcd, 0x00, 0x0e},
917 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
918 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
919 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
920 {SENSOR, 0xd0, 0x00, 0x40},
921 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
922 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
923 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
924 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
925 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
926 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
927 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
928 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
929 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
930 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
931 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
932
933 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
934 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
935 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
936 {SENSOR, 0x33, 0x03, 0x49},
937 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
938 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
939 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
940
941 {SENSOR, 0x33, 0x03, 0x49},
942 {SENSOR, 0x34, 0xc0, 0x19},
943 {SENSOR, 0x3f, 0x20, 0x20},
944 {SENSOR, 0x40, 0x20, 0x20},
945 {SENSOR, 0x5a, 0xc0, 0x0a},
946 {SENSOR, 0x70, 0x7b, 0x0a},
947 {SENSOR, 0x71, 0xff, 0x00},
948 {SENSOR, 0x72, 0x19, 0x0e},
949 {SENSOR, 0x73, 0x18, 0x0f},
950 {SENSOR, 0x74, 0x57, 0x32},
951 {SENSOR, 0x75, 0x56, 0x34},
952 {SENSOR, 0x76, 0x73, 0x35},
953 {SENSOR, 0x77, 0x30, 0x12},
954 {SENSOR, 0x78, 0x79, 0x02},
955 {SENSOR, 0x79, 0x75, 0x06},
956 {SENSOR, 0x7a, 0x77, 0x0a},
957 {SENSOR, 0x7b, 0x78, 0x09},
958 {SENSOR, 0x7c, 0x7d, 0x06},
959 {SENSOR, 0x7d, 0x31, 0x10},
960 {SENSOR, 0x7e, 0x00, 0x7e},
961 {SENSOR, 0x80, 0x59, 0x04},
962 {SENSOR, 0x81, 0x59, 0x04},
963 {SENSOR, 0x82, 0x57, 0x0a},
964 {SENSOR, 0x83, 0x58, 0x0b},
965 {SENSOR, 0x84, 0x47, 0x0c},
966 {SENSOR, 0x85, 0x48, 0x0e},
967 {SENSOR, 0x86, 0x5b, 0x02},
968 {SENSOR, 0x87, 0x00, 0x5c},
969 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
970 {SENSOR, 0x60, 0x00, 0x80},
971 {SENSOR, 0x61, 0x00, 0x00},
972 {SENSOR, 0x62, 0x00, 0x00},
973 {SENSOR, 0x63, 0x00, 0x00},
974 {SENSOR, 0x64, 0x00, 0x00},
975
976 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
977 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12},
978 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00},
979 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10},
980 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60},
981 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
982 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60},
983 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
984 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f},
985 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
986 {SENSOR, 0x30, 0x04, 0x00},
987
988 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
989 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
990 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
991 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
992 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
993 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
994 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
995 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
996 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
997 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
998 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
999 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
1000 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
1001 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
1002 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
1003 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
1004 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
1005 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
1006 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
1007 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
1008 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
1009 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
1010 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
1011 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
1012
1013 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
1014 /* Set number of blank rows chosen to 400 */
1015 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
1016 /* Set the global gain to 283 (of 512) */
1017 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x03, 0x63}
1018};
1019
1020#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
new file mode 100644
index 000000000000..31c5896250e7
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -0,0 +1,546 @@
1/*
2 * Driver for the ov9650 sensor
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#include "m5602_ov9650.h"
20
21int ov9650_read_sensor(struct sd *sd, const u8 address,
22 u8 *i2c_data, const u8 len)
23{
24 int err, i;
25
26 /* The ov9650 registers have a max depth of one byte */
27 if (len > 1 || !len)
28 return -EINVAL;
29
30 do {
31 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
32 } while ((*i2c_data & I2C_BUSY) && !err);
33
34 m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
35 ov9650.i2c_slave_id);
36 m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
37 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len);
38 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
39
40 for (i = 0; i < len; i++) {
41 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
42
43 PDEBUG(DBG_TRACE, "Reading sensor register "
44 "0x%x containing 0x%x ", address, *i2c_data);
45 }
46 return (err < 0) ? err : 0;
47}
48
49int ov9650_write_sensor(struct sd *sd, const u8 address,
50 u8 *i2c_data, const u8 len)
51{
52 int err, i;
53 u8 *p;
54 struct usb_device *udev = sd->gspca_dev.dev;
55 __u8 *buf = sd->gspca_dev.usb_buf;
56
57 /* The ov9650 only supports one byte writes */
58 if (len > 1 || !len)
59 return -EINVAL;
60
61 memcpy(buf, sensor_urb_skeleton,
62 sizeof(sensor_urb_skeleton));
63
64 buf[11] = sd->sensor->i2c_slave_id;
65 buf[15] = address;
66
67 /* Special case larger sensor writes */
68 p = buf + 16;
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(DBG_TRACE, "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
90 return (err < 0) ? err : 0;
91}
92
93int ov9650_probe(struct sd *sd)
94{
95 u8 prod_id = 0, ver_id = 0, i;
96
97 if (force_sensor) {
98 if (force_sensor == OV9650_SENSOR) {
99 info("Forcing an %s sensor", ov9650.name);
100 goto sensor_found;
101 }
102 /* If we want to force another sensor,
103 don't try to probe this one */
104 return -ENODEV;
105 }
106
107 info("Probing for an ov9650 sensor");
108
109 /* Run the pre-init to actually probe the unit */
110 for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) {
111 u8 data = preinit_ov9650[i][2];
112 if (preinit_ov9650[i][0] == SENSOR)
113 ov9650_write_sensor(sd,
114 preinit_ov9650[i][1], &data, 1);
115 else
116 m5602_write_bridge(sd, preinit_ov9650[i][1], data);
117 }
118
119 if (ov9650_read_sensor(sd, OV9650_PID, &prod_id, 1))
120 return -ENODEV;
121
122 if (ov9650_read_sensor(sd, OV9650_VER, &ver_id, 1))
123 return -ENODEV;
124
125 if ((prod_id == 0x96) && (ver_id == 0x52)) {
126 info("Detected an ov9650 sensor");
127 goto sensor_found;
128 }
129
130 return -ENODEV;
131
132sensor_found:
133 sd->gspca_dev.cam.cam_mode = ov9650.modes;
134 sd->gspca_dev.cam.nmodes = ov9650.nmodes;
135 sd->desc->ctrls = ov9650.ctrls;
136 sd->desc->nctrls = ov9650.nctrls;
137 return 0;
138}
139
140int ov9650_init(struct sd *sd)
141{
142 int i, err = 0;
143 u8 data;
144
145 if (dump_sensor)
146 ov9650_dump_registers(sd);
147
148 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) {
149 data = init_ov9650[i][2];
150 if (init_ov9650[i][0] == SENSOR)
151 err = ov9650_write_sensor(sd, init_ov9650[i][1],
152 &data, 1);
153 else
154 err = m5602_write_bridge(sd, init_ov9650[i][1], data);
155 }
156
157 if (!err && dmi_check_system(ov9650_flip_dmi_table)) {
158 info("vflip quirk active");
159 data = 0x30;
160 err = ov9650_write_sensor(sd, OV9650_MVFP, &data, 1);
161 }
162
163 return (err < 0) ? err : 0;
164}
165
166int ov9650_power_down(struct sd *sd)
167{
168 int i;
169 for (i = 0; i < ARRAY_SIZE(power_down_ov9650); i++) {
170 u8 data = power_down_ov9650[i][2];
171 if (power_down_ov9650[i][0] == SENSOR)
172 ov9650_write_sensor(sd,
173 power_down_ov9650[i][1], &data, 1);
174 else
175 m5602_write_bridge(sd, power_down_ov9650[i][1], data);
176 }
177
178 return 0;
179}
180
181int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
182{
183 struct sd *sd = (struct sd *) gspca_dev;
184 u8 i2c_data;
185 int err;
186
187 err = ov9650_read_sensor(sd, OV9650_COM1, &i2c_data, 1);
188 if (err < 0)
189 goto out;
190 *val = i2c_data & 0x03;
191
192 err = ov9650_read_sensor(sd, OV9650_AECH, &i2c_data, 1);
193 if (err < 0)
194 goto out;
195 *val |= (i2c_data << 2);
196
197 err = ov9650_read_sensor(sd, OV9650_AECHM, &i2c_data, 1);
198 if (err < 0)
199 goto out;
200 *val |= (i2c_data & 0x3f) << 10;
201
202 PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val);
203out:
204 return (err < 0) ? err : 0;
205}
206
207int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
208{
209 struct sd *sd = (struct sd *) gspca_dev;
210 u8 i2c_data;
211 int err;
212
213 PDEBUG(DBG_V4L2_CID, "Set exposure to %d",
214 val & 0xffff);
215
216 /* The 6 MSBs */
217 i2c_data = (val >> 10) & 0x3f;
218 err = ov9650_write_sensor(sd, OV9650_AECHM,
219 &i2c_data, 1);
220 if (err < 0)
221 goto out;
222
223 /* The 8 middle bits */
224 i2c_data = (val >> 2) & 0xff;
225 err = ov9650_write_sensor(sd, OV9650_AECH,
226 &i2c_data, 1);
227 if (err < 0)
228 goto out;
229
230 /* The 2 LSBs */
231 i2c_data = val & 0x03;
232 err = ov9650_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
233
234out:
235 return (err < 0) ? err : 0;
236}
237
238int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
239{
240 int err;
241 u8 i2c_data;
242 struct sd *sd = (struct sd *) gspca_dev;
243
244 ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
245 *val = (i2c_data & 0x03) << 8;
246
247 err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
248 *val |= i2c_data;
249 PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
250 return (err < 0) ? err : 0;
251}
252
253int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
254{
255 int err;
256 u8 i2c_data;
257 struct sd *sd = (struct sd *) gspca_dev;
258
259 /* The 2 MSB */
260 /* Read the OV9650_VREF register first to avoid
261 corrupting the VREF high and low bits */
262 ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
263 /* Mask away all uninteresting bits */
264 i2c_data = ((val & 0x0300) >> 2) |
265 (i2c_data & 0x3F);
266 err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
267
268 /* The 8 LSBs */
269 i2c_data = val & 0xff;
270 err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
271 return (err < 0) ? err : 0;
272}
273
274int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
275{
276 int err;
277 u8 i2c_data;
278 struct sd *sd = (struct sd *) gspca_dev;
279
280 err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1);
281 *val = i2c_data;
282
283 PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val);
284
285 return (err < 0) ? err : 0;
286}
287
288int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
289{
290 int err;
291 u8 i2c_data;
292 struct sd *sd = (struct sd *) gspca_dev;
293
294 PDEBUG(DBG_V4L2_CID, "Set red gain to %d",
295 val & 0xff);
296
297 i2c_data = val & 0xff;
298 err = ov9650_write_sensor(sd, OV9650_RED, &i2c_data, 1);
299
300 return (err < 0) ? err : 0;
301}
302
303int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
304{
305 int err;
306 u8 i2c_data;
307 struct sd *sd = (struct sd *) gspca_dev;
308
309 err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1);
310 *val = i2c_data;
311
312 PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val);
313
314 return (err < 0) ? err : 0;
315}
316
317int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
318{
319 int err;
320 u8 i2c_data;
321 struct sd *sd = (struct sd *) gspca_dev;
322
323 PDEBUG(DBG_V4L2_CID, "Set blue gain to %d",
324 val & 0xff);
325
326 i2c_data = val & 0xff;
327 err = ov9650_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
328
329 return (err < 0) ? err : 0;
330}
331
332int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
333{
334 int err;
335 u8 i2c_data;
336 struct sd *sd = (struct sd *) gspca_dev;
337
338 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
339 if (dmi_check_system(ov9650_flip_dmi_table))
340 *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1;
341 else
342 *val = (i2c_data & OV9650_HFLIP) >> 5;
343 PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
344
345 return (err < 0) ? err : 0;
346}
347
348int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
349{
350 int err;
351 u8 i2c_data;
352 struct sd *sd = (struct sd *) gspca_dev;
353
354 PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val);
355 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
356 if (err < 0)
357 goto out;
358
359 if (dmi_check_system(ov9650_flip_dmi_table))
360 i2c_data = ((i2c_data & 0xdf) |
361 (((val ? 0 : 1) & 0x01) << 5));
362 else
363 i2c_data = ((i2c_data & 0xdf) |
364 ((val & 0x01) << 5));
365
366 err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
367out:
368 return (err < 0) ? err : 0;
369}
370
371int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
372{
373 int err;
374 u8 i2c_data;
375 struct sd *sd = (struct sd *) gspca_dev;
376
377 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
378 if (dmi_check_system(ov9650_flip_dmi_table))
379 *val = ((i2c_data & 0x10) >> 4) ? 0 : 1;
380 else
381 *val = (i2c_data & 0x10) >> 4;
382 PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
383
384 return (err < 0) ? err : 0;
385}
386
387int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
388{
389 int err;
390 u8 i2c_data;
391 struct sd *sd = (struct sd *) gspca_dev;
392
393 PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
394 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
395 if (err < 0)
396 goto out;
397
398 if (dmi_check_system(ov9650_flip_dmi_table))
399 i2c_data = ((i2c_data & 0xef) |
400 (((val ? 0 : 1) & 0x01) << 4));
401 else
402 i2c_data = ((i2c_data & 0xef) |
403 ((val & 0x01) << 4));
404
405 err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
406out:
407 return (err < 0) ? err : 0;
408}
409
410int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
411{
412 int err;
413 u8 i2c_data;
414 struct sd *sd = (struct sd *) gspca_dev;
415
416 err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
417 if (err < 0)
418 goto out;
419 *val = (i2c_data & 0x03) << 8;
420
421 err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
422 *val |= i2c_data;
423 PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
424out:
425 return (err < 0) ? err : 0;
426}
427
428int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
429{
430 int err;
431 u8 i2c_data;
432 struct sd *sd = (struct sd *) gspca_dev;
433
434 PDEBUG(DBG_V4L2_CID, "Set gain to %d", val & 0x3ff);
435
436 /* Read the OV9650_VREF register first to avoid
437 corrupting the VREF high and low bits */
438 err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
439 if (err < 0)
440 goto out;
441
442 /* Mask away all uninteresting bits */
443 i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
444 err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
445 if (err < 0)
446 goto out;
447
448 /* The 8 LSBs */
449 i2c_data = val & 0xff;
450 err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
451
452out:
453 return (err < 0) ? err : 0;
454}
455
456int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
457{
458 int err;
459 u8 i2c_data;
460 struct sd *sd = (struct sd *) gspca_dev;
461
462 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
463 *val = (i2c_data & OV9650_AWB_EN) >> 1;
464 PDEBUG(DBG_V4L2_CID, "Read auto white balance %d", *val);
465
466 return (err < 0) ? err : 0;
467}
468
469int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
470{
471 int err;
472 u8 i2c_data;
473 struct sd *sd = (struct sd *) gspca_dev;
474
475 PDEBUG(DBG_V4L2_CID, "Set auto white balance to %d", val);
476 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
477 if (err < 0)
478 goto out;
479
480 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
481 err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
482out:
483 return (err < 0) ? err : 0;
484}
485
486int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
487{
488 int err;
489 u8 i2c_data;
490 struct sd *sd = (struct sd *) gspca_dev;
491
492 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
493 *val = (i2c_data & OV9650_AGC_EN) >> 2;
494 PDEBUG(DBG_V4L2_CID, "Read auto gain control %d", *val);
495
496 return (err < 0) ? err : 0;
497}
498
499int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
500{
501 int err;
502 u8 i2c_data;
503 struct sd *sd = (struct sd *) gspca_dev;
504
505 PDEBUG(DBG_V4L2_CID, "Set auto gain control to %d", val);
506 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
507 if (err < 0)
508 goto out;
509
510 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
511 err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
512out:
513 return (err < 0) ? err : 0;
514}
515
516void ov9650_dump_registers(struct sd *sd)
517{
518 int address;
519 info("Dumping the ov9650 register state");
520 for (address = 0; address < 0xa9; address++) {
521 u8 value;
522 ov9650_read_sensor(sd, address, &value, 1);
523 info("register 0x%x contains 0x%x",
524 address, value);
525 }
526
527 info("ov9650 register state dump complete");
528
529 info("Probing for which registers that are read/write");
530 for (address = 0; address < 0xff; address++) {
531 u8 old_value, ctrl_value;
532 u8 test_value[2] = {0xff, 0xff};
533
534 ov9650_read_sensor(sd, address, &old_value, 1);
535 ov9650_write_sensor(sd, address, test_value, 1);
536 ov9650_read_sensor(sd, address, &ctrl_value, 1);
537
538 if (ctrl_value == test_value[0])
539 info("register 0x%x is writeable", address);
540 else
541 info("register 0x%x is read only", address);
542
543 /* Restore original value */
544 ov9650_write_sensor(sd, address, &old_value, 1);
545 }
546}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
new file mode 100644
index 000000000000..2f29cb056f30
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -0,0 +1,503 @@
1/*
2 * Driver for the ov9650 sensor
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#ifndef M5602_OV9650_H_
20#define M5602_OV9650_H_
21
22#include <linux/dmi.h>
23
24#include "m5602_sensor.h"
25
26/*****************************************************************************/
27
28#define OV9650_GAIN 0x00
29#define OV9650_BLUE 0x01
30#define OV9650_RED 0x02
31#define OV9650_VREF 0x03
32#define OV9650_COM1 0x04
33#define OV9650_BAVE 0x05
34#define OV9650_GEAVE 0x06
35#define OV9650_RSVD7 0x07
36#define OV9650_PID 0x0a
37#define OV9650_VER 0x0b
38#define OV9650_COM3 0x0c
39#define OV9650_COM5 0x0e
40#define OV9650_COM6 0x0f
41#define OV9650_AECH 0x10
42#define OV9650_CLKRC 0x11
43#define OV9650_COM7 0x12
44#define OV9650_COM8 0x13
45#define OV9650_COM9 0x14
46#define OV9650_COM10 0x15
47#define OV9650_RSVD16 0x16
48#define OV9650_HSTART 0x17
49#define OV9650_HSTOP 0x18
50#define OV9650_VSTRT 0x19
51#define OV9650_VSTOP 0x1a
52#define OV9650_PSHFT 0x1b
53#define OV9650_MVFP 0x1e
54#define OV9650_AEW 0x24
55#define OV9650_AEB 0x25
56#define OV9650_VPT 0x26
57#define OV9650_BBIAS 0x27
58#define OV9650_GbBIAS 0x28
59#define OV9650_Gr_COM 0x29
60#define OV9650_RBIAS 0x2c
61#define OV9650_HREF 0x32
62#define OV9650_CHLF 0x33
63#define OV9650_ARBLM 0x34
64#define OV9650_RSVD35 0x35
65#define OV9650_RSVD36 0x36
66#define OV9650_ADC 0x37
67#define OV9650_ACOM38 0x38
68#define OV9650_OFON 0x39
69#define OV9650_TSLB 0x3a
70#define OV9650_COM12 0x3c
71#define OV9650_COM13 0x3d
72#define OV9650_COM15 0x40
73#define OV9650_COM16 0x41
74#define OV9650_LCC1 0x62
75#define OV9650_LCC2 0x63
76#define OV9650_LCC3 0x64
77#define OV9650_LCC4 0x65
78#define OV9650_LCC5 0x66
79#define OV9650_HV 0x69
80#define OV9650_DBLV 0x6b
81#define OV9650_COM21 0x8b
82#define OV9650_COM22 0x8c
83#define OV9650_COM24 0x8e
84#define OV9650_DBLC1 0x8f
85#define OV9650_RSVD94 0x94
86#define OV9650_RSVD95 0x95
87#define OV9650_RSVD96 0x96
88#define OV9650_LCCFB 0x9d
89#define OV9650_LCCFR 0x9e
90#define OV9650_AECHM 0xa1
91#define OV9650_COM26 0xa5
92#define OV9650_ACOMA8 0xa8
93#define OV9650_ACOMA9 0xa9
94
95#define OV9650_REGISTER_RESET (1 << 7)
96#define OV9650_VGA_SELECT (1 << 6)
97#define OV9650_RGB_SELECT (1 << 2)
98#define OV9650_RAW_RGB_SELECT (1 << 0)
99
100#define OV9650_FAST_AGC_AEC (1 << 7)
101#define OV9650_AEC_UNLIM_STEP_SIZE (1 << 6)
102#define OV9650_BANDING (1 << 5)
103#define OV9650_AGC_EN (1 << 2)
104#define OV9650_AWB_EN (1 << 1)
105#define OV9650_AEC_EN (1 << 0)
106
107#define OV9650_VARIOPIXEL (1 << 2)
108#define OV9650_SYSTEM_CLK_SEL (1 << 7)
109#define OV9650_SLAM_MODE (1 << 4)
110
111#define OV9650_VFLIP (1 << 4)
112#define OV9650_HFLIP (1 << 5)
113
114#define GAIN_DEFAULT 0x14
115#define RED_GAIN_DEFAULT 0x70
116#define BLUE_GAIN_DEFAULT 0x20
117#define EXPOSURE_DEFAULT 0x5003
118
119/*****************************************************************************/
120
121/* Kernel module parameters */
122extern int force_sensor;
123extern int dump_sensor;
124extern unsigned int m5602_debug;
125
126int ov9650_probe(struct sd *sd);
127int ov9650_init(struct sd *sd);
128int ov9650_power_down(struct sd *sd);
129
130int ov9650_read_sensor(struct sd *sd, const u8 address,
131 u8 *i2c_data, const u8 len);
132int ov9650_write_sensor(struct sd *sd, const u8 address,
133 u8 *i2c_data, const u8 len);
134
135void ov9650_dump_registers(struct sd *sd);
136
137int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
138int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
139int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
140int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
141int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
142int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
143int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
144int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
145int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
146int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
147int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
148int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
149int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
150int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
151int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val);
152int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
153int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
154int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
155
156static struct m5602_sensor ov9650 = {
157 .name = "OV9650",
158 .i2c_slave_id = 0x60,
159 .probe = ov9650_probe,
160 .init = ov9650_init,
161 .power_down = ov9650_power_down,
162 .read_sensor = ov9650_read_sensor,
163 .write_sensor = ov9650_write_sensor,
164
165 .nctrls = 8,
166 .ctrls = {
167 {
168 {
169 .id = V4L2_CID_EXPOSURE,
170 .type = V4L2_CTRL_TYPE_INTEGER,
171 .name = "exposure",
172 .minimum = 0x00,
173 .maximum = 0xffff,
174 .step = 0x1,
175 .default_value = EXPOSURE_DEFAULT,
176 .flags = V4L2_CTRL_FLAG_SLIDER
177 },
178 .set = ov9650_set_exposure,
179 .get = ov9650_get_exposure
180 }, {
181 {
182 .id = V4L2_CID_GAIN,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "gain",
185 .minimum = 0x00,
186 .maximum = 0x3ff,
187 .step = 0x1,
188 .default_value = GAIN_DEFAULT,
189 .flags = V4L2_CTRL_FLAG_SLIDER
190 },
191 .set = ov9650_set_gain,
192 .get = ov9650_get_gain
193 }, {
194 {
195 .type = V4L2_CTRL_TYPE_INTEGER,
196 .name = "red balance",
197 .minimum = 0x00,
198 .maximum = 0xff,
199 .step = 0x1,
200 .default_value = RED_GAIN_DEFAULT,
201 .flags = V4L2_CTRL_FLAG_SLIDER
202 },
203 .set = ov9650_set_red_balance,
204 .get = ov9650_get_red_balance
205 }, {
206 {
207 .type = V4L2_CTRL_TYPE_INTEGER,
208 .name = "blue balance",
209 .minimum = 0x00,
210 .maximum = 0xff,
211 .step = 0x1,
212 .default_value = BLUE_GAIN_DEFAULT,
213 .flags = V4L2_CTRL_FLAG_SLIDER
214 },
215 .set = ov9650_set_blue_balance,
216 .get = ov9650_get_blue_balance
217 }, {
218 {
219 .id = V4L2_CID_HFLIP,
220 .type = V4L2_CTRL_TYPE_BOOLEAN,
221 .name = "horizontal flip",
222 .minimum = 0,
223 .maximum = 1,
224 .step = 1,
225 .default_value = 0
226 },
227 .set = ov9650_set_hflip,
228 .get = ov9650_get_hflip
229 }, {
230 {
231 .id = V4L2_CID_VFLIP,
232 .type = V4L2_CTRL_TYPE_BOOLEAN,
233 .name = "vertical flip",
234 .minimum = 0,
235 .maximum = 1,
236 .step = 1,
237 .default_value = 0
238 },
239 .set = ov9650_set_vflip,
240 .get = ov9650_get_vflip
241 }, {
242 {
243 .id = V4L2_CID_AUTO_WHITE_BALANCE,
244 .type = V4L2_CTRL_TYPE_BOOLEAN,
245 .name = "auto white balance",
246 .minimum = 0,
247 .maximum = 1,
248 .step = 1,
249 .default_value = 0
250 },
251 .set = ov9650_set_auto_white_balance,
252 .get = ov9650_get_auto_white_balance
253 }, {
254 {
255 .id = V4L2_CID_AUTOGAIN,
256 .type = V4L2_CTRL_TYPE_BOOLEAN,
257 .name = "auto gain control",
258 .minimum = 0,
259 .maximum = 1,
260 .step = 1,
261 .default_value = 0
262 },
263 .set = ov9650_set_auto_gain,
264 .get = ov9650_get_auto_gain
265 }
266 },
267
268 .nmodes = 1,
269 .modes = {
270 {
271 M5602_DEFAULT_FRAME_WIDTH,
272 M5602_DEFAULT_FRAME_HEIGHT,
273 V4L2_PIX_FMT_SBGGR8,
274 V4L2_FIELD_NONE,
275 .sizeimage =
276 M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
277 .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
278 .colorspace = V4L2_COLORSPACE_SRGB,
279 .priv = 1
280 }
281 }
282};
283
284static const unsigned char preinit_ov9650[][3] =
285{
286 /* [INITCAM] */
287 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
288 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
289 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
290 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
291 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
292 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
293
294 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
295 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
296 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
297 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
298 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
299 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
300 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
301 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
302 /* Reset chip */
303 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
304 /* Enable double clock */
305 {SENSOR, OV9650_CLKRC, 0x80},
306 /* Do something out of spec with the power */
307 {SENSOR, OV9650_OFON, 0x40}
308};
309
310static const unsigned char init_ov9650[][3] =
311{
312 /* [INITCAM] */
313 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
314 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
315 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
316 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
317 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
318 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
319
320 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
321 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
322 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
323 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
324 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
325 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
326 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
327 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
328 /* Reset chip */
329 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
330 /* Enable double clock */
331 {SENSOR, OV9650_CLKRC, 0x80},
332 /* Do something out of spec with the power */
333 {SENSOR, OV9650_OFON, 0x40},
334
335 /* Set QQVGA */
336 {SENSOR, OV9650_COM1, 0x20},
337 /* Set fast AGC/AEC algorithm with unlimited step size */
338 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
339 OV9650_AEC_UNLIM_STEP_SIZE |
340 OV9650_AWB_EN | OV9650_AGC_EN},
341
342 {SENSOR, OV9650_CHLF, 0x10},
343 {SENSOR, OV9650_ARBLM, 0xbf},
344 {SENSOR, OV9650_ACOM38, 0x81},
345 /* Turn off color matrix coefficient double option */
346 {SENSOR, OV9650_COM16, 0x00},
347 /* Enable color matrix for RGB/YUV, Delay Y channel,
348 set output Y/UV delay to 1 */
349 {SENSOR, OV9650_COM13, 0x19},
350 /* Enable digital BLC, Set output mode to U Y V Y */
351 {SENSOR, OV9650_TSLB, 0x0c},
352 /* Limit the AGC/AEC stable upper region */
353 {SENSOR, OV9650_COM24, 0x00},
354 /* Enable HREF and some out of spec things */
355 {SENSOR, OV9650_COM12, 0x73},
356 /* Set all DBLC offset signs to positive and
357 do some out of spec stuff */
358 {SENSOR, OV9650_DBLC1, 0xdf},
359 {SENSOR, OV9650_COM21, 0x06},
360 {SENSOR, OV9650_RSVD35, 0x91},
361 /* Necessary, no camera stream without it */
362 {SENSOR, OV9650_RSVD16, 0x06},
363 {SENSOR, OV9650_RSVD94, 0x99},
364 {SENSOR, OV9650_RSVD95, 0x99},
365 {SENSOR, OV9650_RSVD96, 0x04},
366 /* Enable full range output */
367 {SENSOR, OV9650_COM15, 0x0},
368 /* Enable HREF at optical black, enable ADBLC bias,
369 enable ADBLC, reset timings at format change */
370 {SENSOR, OV9650_COM6, 0x4b},
371 /* Subtract 32 from the B channel bias */
372 {SENSOR, OV9650_BBIAS, 0xa0},
373 /* Subtract 32 from the Gb channel bias */
374 {SENSOR, OV9650_GbBIAS, 0xa0},
375 /* Do not bypass the analog BLC and to some out of spec stuff */
376 {SENSOR, OV9650_Gr_COM, 0x00},
377 /* Subtract 32 from the R channel bias */
378 {SENSOR, OV9650_RBIAS, 0xa0},
379 /* Subtract 32 from the R channel bias */
380 {SENSOR, OV9650_RBIAS, 0x0},
381 {SENSOR, OV9650_COM26, 0x80},
382 {SENSOR, OV9650_ACOMA9, 0x98},
383 /* Set the AGC/AEC stable region upper limit */
384 {SENSOR, OV9650_AEW, 0x68},
385 /* Set the AGC/AEC stable region lower limit */
386 {SENSOR, OV9650_AEB, 0x5c},
387 /* Set the high and low limit nibbles to 3 */
388 {SENSOR, OV9650_VPT, 0xc3},
389 /* Set the Automatic Gain Ceiling (AGC) to 128x,
390 drop VSYNC at frame drop,
391 limit exposure timing,
392 drop frame when the AEC step is larger than the exposure gap */
393 {SENSOR, OV9650_COM9, 0x6e},
394 /* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync)
395 and set PWDN to SLVS (slave mode vertical sync) */
396 {SENSOR, OV9650_COM10, 0x42},
397 /* Set horizontal column start high to default value */
398 {SENSOR, OV9650_HSTART, 0x1a},
399 /* Set horizontal column end */
400 {SENSOR, OV9650_HSTOP, 0xbf},
401 /* Complementing register to the two writes above */
402 {SENSOR, OV9650_HREF, 0xb2},
403 /* Set vertical row start high bits */
404 {SENSOR, OV9650_VSTRT, 0x02},
405 /* Set vertical row end low bits */
406 {SENSOR, OV9650_VSTOP, 0x7e},
407 /* Set complementing vertical frame control */
408 {SENSOR, OV9650_VREF, 0x10},
409 /* Set raw RGB output format with VGA resolution */
410 {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
411 OV9650_RGB_SELECT |
412 OV9650_RAW_RGB_SELECT},
413 {SENSOR, OV9650_ADC, 0x04},
414 {SENSOR, OV9650_HV, 0x40},
415 /* Enable denoise, and white-pixel erase */
416 {SENSOR, OV9650_COM22, 0x23},
417
418 /* Set the high bits of the exposure value */
419 {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)},
420
421 /* Set the low bits of the exposure value */
422 {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)},
423 {SENSOR, OV9650_GAIN, GAIN_DEFAULT},
424 {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT},
425 {SENSOR, OV9650_RED, RED_GAIN_DEFAULT},
426
427 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
428 {SENSOR, OV9650_COM5, OV9650_SYSTEM_CLK_SEL},
429
430 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
431 {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
432 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
433 {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
434 {BRIDGE, M5602_XB_SIG_INI, 0x01},
435 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
436 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
437 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
438 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
439 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0},
440 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
441 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
442 {BRIDGE, M5602_XB_HSYNC_PARA, 0x5e},
443 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
444 {BRIDGE, M5602_XB_HSYNC_PARA, 0xde}
445};
446
447static const unsigned char power_down_ov9650[][3] =
448{
449 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
450 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
451 {SENSOR, OV9650_COM7, 0x80},
452 {SENSOR, OV9650_OFON, 0xf4},
453 {SENSOR, OV9650_MVFP, 0x80},
454 {SENSOR, OV9650_DBLV, 0x3f},
455 {SENSOR, OV9650_RSVD36, 0x49},
456 {SENSOR, OV9650_COM7, 0x05},
457
458 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
459 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
460 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
461 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
462 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
463 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
464 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}
465};
466
467/* Vertically and horizontally flips the image if matched, needed for machines
468 where the sensor is mounted upside down */
469static
470 const
471 struct dmi_system_id ov9650_flip_dmi_table[] = {
472 {
473 .ident = "ASUS A6VC",
474 .matches = {
475 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
476 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
477 }
478 },
479 {
480 .ident = "ASUS A6VM",
481 .matches = {
482 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
483 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
484 }
485 },
486 {
487 .ident = "ASUS A6JC",
488 .matches = {
489 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
490 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
491 }
492 },
493 {
494 .ident = "ASUS A6Kt",
495 .matches = {
496 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
497 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
498 }
499 },
500 { }
501};
502
503#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
new file mode 100644
index 000000000000..08c015bde115
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -0,0 +1,336 @@
1/*
2 * Driver for the po1030 sensor
3 *
4 * Copyright (c) 2008 Erik Andren
5 * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#include "m5602_po1030.h"
20
21int po1030_probe(struct sd *sd)
22{
23 u8 prod_id = 0, ver_id = 0, i;
24
25 if (force_sensor) {
26 if (force_sensor == PO1030_SENSOR) {
27 info("Forcing a %s sensor", po1030.name);
28 goto sensor_found;
29 }
30 /* If we want to force another sensor, don't try to probe this
31 * one */
32 return -ENODEV;
33 }
34
35 info("Probing for a po1030 sensor");
36
37 /* Run the pre-init to actually probe the unit */
38 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
39 u8 data = preinit_po1030[i][2];
40 if (preinit_po1030[i][0] == SENSOR)
41 po1030_write_sensor(sd,
42 preinit_po1030[i][1], &data, 1);
43 else
44 m5602_write_bridge(sd, preinit_po1030[i][1], data);
45 }
46
47 if (po1030_read_sensor(sd, 0x3, &prod_id, 1))
48 return -ENODEV;
49
50 if (po1030_read_sensor(sd, 0x4, &ver_id, 1))
51 return -ENODEV;
52
53 if ((prod_id == 0x02) && (ver_id == 0xef)) {
54 info("Detected a po1030 sensor");
55 goto sensor_found;
56 }
57 return -ENODEV;
58
59sensor_found:
60 sd->gspca_dev.cam.cam_mode = po1030.modes;
61 sd->gspca_dev.cam.nmodes = po1030.nmodes;
62 sd->desc->ctrls = po1030.ctrls;
63 sd->desc->nctrls = po1030.nctrls;
64 return 0;
65}
66
67int po1030_read_sensor(struct sd *sd, const u8 address,
68 u8 *i2c_data, const u8 len)
69{
70 int err, i;
71
72 do {
73 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
74 } while ((*i2c_data & I2C_BUSY) && !err);
75
76 m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
77 sd->sensor->i2c_slave_id);
78 m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
79 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len);
80 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
81
82 for (i = 0; i < len; i++) {
83 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
84
85 PDEBUG(DBG_TRACE, "Reading sensor register "
86 "0x%x containing 0x%x ", address, *i2c_data);
87 }
88 return (err < 0) ? err : 0;
89}
90
91int po1030_write_sensor(struct sd *sd, const u8 address,
92 u8 *i2c_data, const u8 len)
93{
94 int err, i;
95 u8 *p;
96 struct usb_device *udev = sd->gspca_dev.dev;
97 __u8 *buf = sd->gspca_dev.usb_buf;
98
99 /* The po1030 only supports one byte writes */
100 if (len > 1 || !len)
101 return -EINVAL;
102
103 memcpy(buf, sensor_urb_skeleton, sizeof(sensor_urb_skeleton));
104
105 buf[11] = sd->sensor->i2c_slave_id;
106 buf[15] = address;
107
108 p = buf + 16;
109
110 /* Copy a four byte write sequence for each byte to be written to */
111 for (i = 0; i < len; i++) {
112 memcpy(p, sensor_urb_skeleton + 16, 4);
113 p[3] = i2c_data[i];
114 p += 4;
115 PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
116 address, i2c_data[i]);
117 }
118
119 /* Copy the footer */
120 memcpy(p, sensor_urb_skeleton + 20, 4);
121
122 /* Set the total length */
123 p[3] = 0x10 + len;
124
125 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
126 0x04, 0x40, 0x19,
127 0x0000, buf,
128 20 + len * 4, M5602_URB_MSG_TIMEOUT);
129
130 return (err < 0) ? err : 0;
131}
132
133int po1030_init(struct sd *sd)
134{
135 int i, err = 0;
136
137 /* Init the sensor */
138 for (i = 0; i < ARRAY_SIZE(init_po1030); i++) {
139 u8 data[2] = {0x00, 0x00};
140
141 switch (init_po1030[i][0]) {
142 case BRIDGE:
143 err = m5602_write_bridge(sd,
144 init_po1030[i][1],
145 init_po1030[i][2]);
146 break;
147
148 case SENSOR:
149 data[0] = init_po1030[i][2];
150 err = po1030_write_sensor(sd,
151 init_po1030[i][1], data, 1);
152 break;
153
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:
161 info("Invalid stream command, exiting init");
162 return -EINVAL;
163 }
164 }
165
166 if (dump_sensor)
167 po1030_dump_registers(sd);
168
169 return (err < 0) ? err : 0;
170}
171
172int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
173{
174 struct sd *sd = (struct sd *) gspca_dev;
175 u8 i2c_data;
176 int err;
177
178 err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_H,
179 &i2c_data, 1);
180 if (err < 0)
181 goto out;
182 *val = (i2c_data << 8);
183
184 err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_M,
185 &i2c_data, 1);
186 *val |= i2c_data;
187
188 PDEBUG(DBG_V4L2_CID, "Exposure read as %d", *val);
189out:
190 return (err < 0) ? err : 0;
191}
192
193int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
194{
195 struct sd *sd = (struct sd *) gspca_dev;
196 u8 i2c_data;
197 int err;
198
199 PDEBUG(DBG_V4L2, "Set exposure to %d", val & 0xffff);
200
201 i2c_data = ((val & 0xff00) >> 8);
202 PDEBUG(DBG_V4L2, "Set exposure to high byte to 0x%x",
203 i2c_data);
204
205 err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H,
206 &i2c_data, 1);
207 if (err < 0)
208 goto out;
209
210 i2c_data = (val & 0xff);
211 PDEBUG(DBG_V4L2, "Set exposure to low byte to 0x%x",
212 i2c_data);
213 err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M,
214 &i2c_data, 1);
215
216out:
217 return (err < 0) ? err : 0;
218}
219
220int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
221{
222 struct sd *sd = (struct sd *) gspca_dev;
223 u8 i2c_data;
224 int err;
225
226 err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
227 &i2c_data, 1);
228 *val = i2c_data;
229 PDEBUG(DBG_V4L2_CID, "Read global gain %d", *val);
230
231 return (err < 0) ? err : 0;
232}
233
234int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
235{
236 struct sd *sd = (struct sd *) gspca_dev;
237 u8 i2c_data;
238 int err;
239
240 i2c_data = val & 0xff;
241 PDEBUG(DBG_V4L2, "Set global gain to %d", i2c_data);
242 err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN,
243 &i2c_data, 1);
244 return (err < 0) ? err : 0;
245}
246
247int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
248{
249 struct sd *sd = (struct sd *) gspca_dev;
250 u8 i2c_data;
251 int err;
252
253 err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN,
254 &i2c_data, 1);
255 *val = i2c_data;
256 PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val);
257 return (err < 0) ? err : 0;
258}
259
260int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
261{
262 struct sd *sd = (struct sd *) gspca_dev;
263 u8 i2c_data;
264 int err;
265
266 i2c_data = val & 0xff;
267 PDEBUG(DBG_V4L2, "Set red gain to %d", i2c_data);
268 err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN,
269 &i2c_data, 1);
270 return (err < 0) ? err : 0;
271}
272
273int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
274{
275 struct sd *sd = (struct sd *) gspca_dev;
276 u8 i2c_data;
277 int err;
278
279 err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN,
280 &i2c_data, 1);
281 *val = i2c_data;
282 PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val);
283
284 return (err < 0) ? err : 0;
285}
286
287int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
288{
289 struct sd *sd = (struct sd *) gspca_dev;
290 u8 i2c_data;
291 int err;
292 i2c_data = val & 0xff;
293 PDEBUG(DBG_V4L2, "Set blue gain to %d", i2c_data);
294 err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN,
295 &i2c_data, 1);
296
297 return (err < 0) ? err : 0;
298}
299
300int po1030_power_down(struct sd *sd)
301{
302 return 0;
303}
304
305void po1030_dump_registers(struct sd *sd)
306{
307 int address;
308 u8 value = 0;
309
310 info("Dumping the po1030 sensor core registers");
311 for (address = 0; address < 0x7f; address++) {
312 po1030_read_sensor(sd, address, &value, 1);
313 info("register 0x%x contains 0x%x",
314 address, value);
315 }
316
317 info("po1030 register state dump complete");
318
319 info("Probing for which registers that are read/write");
320 for (address = 0; address < 0xff; address++) {
321 u8 old_value, ctrl_value;
322 u8 test_value[2] = {0xff, 0xff};
323
324 po1030_read_sensor(sd, address, &old_value, 1);
325 po1030_write_sensor(sd, address, test_value, 1);
326 po1030_read_sensor(sd, address, &ctrl_value, 1);
327
328 if (ctrl_value == test_value[0])
329 info("register 0x%x is writeable", address);
330 else
331 info("register 0x%x is read only", address);
332
333 /* Restore original value */
334 po1030_write_sensor(sd, address, &old_value, 1);
335 }
336}
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
new file mode 100644
index 000000000000..68f34c97bf44
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -0,0 +1,478 @@
1/*
2 * Driver for the po1030 sensor.
3 * This is probably a pixel plus sensor but we haven't identified it yet
4 *
5 * Copyright (c) 2008 Erik Andren
6 * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
7 * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
8 *
9 * Portions of code to USB interface and ALi driver software,
10 * Copyright (c) 2006 Willem Duinker
11 * v4l2 interface modeled after the V4L2 driver
12 * for SN9C10x PC Camera Controllers
13 *
14 * Register defines taken from Pascal Stangs Proxycon Armlib
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation, version 2.
19 *
20 */
21
22#ifndef M5602_PO1030_H_
23#define M5602_PO1030_H_
24
25#include "m5602_sensor.h"
26
27/*****************************************************************************/
28
29#define PO1030_REG_DEVID_H 0x00
30#define PO1030_REG_DEVID_L 0x01
31#define PO1030_REG_FRAMEWIDTH_H 0x04
32#define PO1030_REG_FRAMEWIDTH_L 0x05
33#define PO1030_REG_FRAMEHEIGHT_H 0x06
34#define PO1030_REG_FRAMEHEIGHT_L 0x07
35#define PO1030_REG_WINDOWX_H 0x08
36#define PO1030_REG_WINDOWX_L 0x09
37#define PO1030_REG_WINDOWY_H 0x0a
38#define PO1030_REG_WINDOWY_L 0x0b
39#define PO1030_REG_WINDOWWIDTH_H 0x0c
40#define PO1030_REG_WINDOWWIDTH_L 0x0d
41#define PO1030_REG_WINDOWHEIGHT_H 0x0e
42#define PO1030_REG_WINDOWHEIGHT_L 0x0f
43
44#define PO1030_REG_GLOBALIBIAS 0x12
45#define PO1030_REG_PIXELIBIAS 0x13
46
47#define PO1030_REG_GLOBALGAIN 0x15
48#define PO1030_REG_RED_GAIN 0x16
49#define PO1030_REG_GREEN_1_GAIN 0x17
50#define PO1030_REG_BLUE_GAIN 0x18
51#define PO1030_REG_GREEN_2_GAIN 0x19
52
53#define PO1030_REG_INTEGLINES_H 0x1a
54#define PO1030_REG_INTEGLINES_M 0x1b
55#define PO1030_REG_INTEGLINES_L 0x1c
56
57#define PO1030_REG_CONTROL1 0x1d
58#define PO1030_REG_CONTROL2 0x1e
59#define PO1030_REG_CONTROL3 0x1f
60#define PO1030_REG_CONTROL4 0x20
61
62#define PO1030_REG_PERIOD50_H 0x23
63#define PO1030_REG_PERIOD50_L 0x24
64#define PO1030_REG_PERIOD60_H 0x25
65#define PO1030_REG_PERIOD60_L 0x26
66#define PO1030_REG_REGCLK167 0x27
67#define PO1030_REG_DELTA50 0x28
68#define PO1030_REG_DELTA60 0x29
69
70#define PO1030_REG_ADCOFFSET 0x2c
71
72/* Gamma Correction Coeffs */
73#define PO1030_REG_GC0 0x2d
74#define PO1030_REG_GC1 0x2e
75#define PO1030_REG_GC2 0x2f
76#define PO1030_REG_GC3 0x30
77#define PO1030_REG_GC4 0x31
78#define PO1030_REG_GC5 0x32
79#define PO1030_REG_GC6 0x33
80#define PO1030_REG_GC7 0x34
81
82/* Color Transform Matrix */
83#define PO1030_REG_CT0 0x35
84#define PO1030_REG_CT1 0x36
85#define PO1030_REG_CT2 0x37
86#define PO1030_REG_CT3 0x38
87#define PO1030_REG_CT4 0x39
88#define PO1030_REG_CT5 0x3a
89#define PO1030_REG_CT6 0x3b
90#define PO1030_REG_CT7 0x3c
91#define PO1030_REG_CT8 0x3d
92
93#define PO1030_REG_AUTOCTRL1 0x3e
94#define PO1030_REG_AUTOCTRL2 0x3f
95
96#define PO1030_REG_YTARGET 0x40
97#define PO1030_REG_GLOBALGAINMIN 0x41
98#define PO1030_REG_GLOBALGAINMAX 0x42
99
100/* Output format control */
101#define PO1030_REG_OUTFORMCTRL1 0x5a
102#define PO1030_REG_OUTFORMCTRL2 0x5b
103#define PO1030_REG_OUTFORMCTRL3 0x5c
104#define PO1030_REG_OUTFORMCTRL4 0x5d
105#define PO1030_REG_OUTFORMCTRL5 0x5e
106
107/* Imaging coefficients */
108#define PO1030_REG_YBRIGHT 0x73
109#define PO1030_REG_YCONTRAST 0x74
110#define PO1030_REG_YSATURATION 0x75
111
112/*****************************************************************************/
113
114#define PO1030_GLOBAL_GAIN_DEFAULT 0x12
115#define PO1030_EXPOSURE_DEFAULT 0xf0ff
116#define PO1030_BLUE_GAIN_DEFAULT 0x40
117#define PO1030_RED_GAIN_DEFAULT 0x40
118
119/*****************************************************************************/
120
121/* Kernel module parameters */
122extern int force_sensor;
123extern int dump_sensor;
124extern unsigned int m5602_debug;
125
126int po1030_probe(struct sd *sd);
127int po1030_init(struct sd *sd);
128int po1030_power_down(struct sd *sd);
129
130void po1030_dump_registers(struct sd *sd);
131
132int po1030_read_sensor(struct sd *sd, const u8 address,
133 u8 *i2c_data, const u8 len);
134int po1030_write_sensor(struct sd *sd, const u8 address,
135 u8 *i2c_data, const u8 len);
136
137int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
138int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
139int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
140int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
141int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
142int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
143int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
144int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
145
146static struct m5602_sensor po1030 = {
147 .name = "PO1030",
148
149 .i2c_slave_id = 0xdc,
150
151 .probe = po1030_probe,
152 .init = po1030_init,
153 .power_down = po1030_power_down,
154
155 .nctrls = 4,
156 .ctrls = {
157 {
158 {
159 .id = V4L2_CID_GAIN,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "gain",
162 .minimum = 0x00,
163 .maximum = 0xff,
164 .step = 0x1,
165 .default_value = PO1030_GLOBAL_GAIN_DEFAULT,
166 .flags = V4L2_CTRL_FLAG_SLIDER
167 },
168 .set = po1030_set_gain,
169 .get = po1030_get_gain
170 }, {
171 {
172 .id = V4L2_CID_EXPOSURE,
173 .type = V4L2_CTRL_TYPE_INTEGER,
174 .name = "exposure",
175 .minimum = 0x00,
176 .maximum = 0xffff,
177 .step = 0x1,
178 .default_value = PO1030_EXPOSURE_DEFAULT,
179 .flags = V4L2_CTRL_FLAG_SLIDER
180 },
181 .set = po1030_set_exposure,
182 .get = po1030_get_exposure
183 }, {
184 {
185 .id = V4L2_CID_RED_BALANCE,
186 .type = V4L2_CTRL_TYPE_INTEGER,
187 .name = "red balance",
188 .minimum = 0x00,
189 .maximum = 0xff,
190 .step = 0x1,
191 .default_value = PO1030_RED_GAIN_DEFAULT,
192 .flags = V4L2_CTRL_FLAG_SLIDER
193 },
194 .set = po1030_set_red_balance,
195 .get = po1030_get_red_balance
196 }, {
197 {
198 .id = V4L2_CID_BLUE_BALANCE,
199 .type = V4L2_CTRL_TYPE_INTEGER,
200 .name = "blue balance",
201 .minimum = 0x00,
202 .maximum = 0xff,
203 .step = 0x1,
204 .default_value = PO1030_BLUE_GAIN_DEFAULT,
205 .flags = V4L2_CTRL_FLAG_SLIDER
206 },
207 .set = po1030_set_blue_balance,
208 .get = po1030_get_blue_balance
209 }
210 },
211 .nmodes = 1,
212 .modes = {
213 {
214 M5602_DEFAULT_FRAME_WIDTH,
215 M5602_DEFAULT_FRAME_HEIGHT,
216 V4L2_PIX_FMT_SBGGR8,
217 V4L2_FIELD_NONE,
218 .sizeimage =
219 M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
220 .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
221 .colorspace = V4L2_COLORSPACE_SRGB,
222 .priv = 1
223 }
224 }
225};
226
227static const unsigned char preinit_po1030[][3] =
228{
229 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
230 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
231 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
232 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
233 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
234 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
235 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
236 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
237 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
238
239 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
240
241 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
242 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
243 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
244 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
245 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
246 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
247 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
248 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
249 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
250 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
251 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
252 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
253 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
254 {BRIDGE, M5602_XB_SIG_INI, 0x01},
255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
256 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
257 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
258 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
259 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
260 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
261 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
262 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
263 {BRIDGE, M5602_XB_SIG_INI, 0x00},
264 {BRIDGE, M5602_XB_SIG_INI, 0x02},
265 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
266 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
267 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
268 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
269 {BRIDGE, M5602_XB_SIG_INI, 0x00},
270
271 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
272
273 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
274 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
275 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
276 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
277 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
278 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
279 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
280 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
281 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
282 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
283 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
284 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
285 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}
286};
287
288static const unsigned char init_po1030[][4] =
289{
290 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
291 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
292 /*sequence 1*/
293 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
294 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
295 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
296 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
297
298 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
299 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
300 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
301 /*end of sequence 1*/
302
303 /*sequence 2 (same as stop sequence)*/
304 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
305 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
306 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
307 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
308 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
309 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
310
311 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
312 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
313 /*end of sequence 2*/
314
315 /*sequence 5*/
316 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
317 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
318 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
319 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
320 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
321 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
322 {BRIDGE, M5602_XB_SIG_INI, 0x01},
323 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
324 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
325 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
326 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
327 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
328 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
329 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
330 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
331 {BRIDGE, M5602_XB_SIG_INI, 0x00},
332 {BRIDGE, M5602_XB_SIG_INI, 0x02},
333 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
334 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
335 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
336 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
337 {BRIDGE, M5602_XB_SIG_INI, 0x00},
338 /*end of sequence 5*/
339
340 /*sequence 2 stop */
341 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
342
343 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
344 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
345 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
346 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
347 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
348 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
349 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
350 /*end of sequence 2 stop */
351
352/* ---------------------------------
353 * end of init - begin of start
354 * --------------------------------- */
355
356 /*sequence 3*/
357 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
358 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
359 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
360 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
361 /*end of sequence 3*/
362 /*sequence 4*/
363 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
364 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
365 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
366 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
367
368 {SENSOR, PO1030_REG_AUTOCTRL2, 0x04},
369
370 /* Set the width to 751 */
371 {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02},
372 {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef},
373
374 /* Set the height to 540 */
375 {SENSOR, PO1030_REG_FRAMEHEIGHT_H, 0x02},
376 {SENSOR, PO1030_REG_FRAMEHEIGHT_L, 0x1c},
377
378 /* Set the x window to 1 */
379 {SENSOR, PO1030_REG_WINDOWX_H, 0x00},
380 {SENSOR, PO1030_REG_WINDOWX_L, 0x01},
381
382 /* Set the y window to 1 */
383 {SENSOR, PO1030_REG_WINDOWY_H, 0x00},
384 {SENSOR, PO1030_REG_WINDOWX_L, 0x01},
385
386 {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02},
387 {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87},
388 {SENSOR, PO1030_REG_WINDOWHEIGHT_H, 0x01},
389 {SENSOR, PO1030_REG_WINDOWHEIGHT_L, 0xe3},
390
391 {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
392 {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
393 {SENSOR, PO1030_REG_AUTOCTRL1, 0x08},
394 {SENSOR, PO1030_REG_CONTROL2, 0x03},
395 {SENSOR, 0x21, 0x90},
396 {SENSOR, PO1030_REG_YTARGET, 0x60},
397 {SENSOR, 0x59, 0x13},
398 {SENSOR, PO1030_REG_OUTFORMCTRL1, 0x40},
399 {SENSOR, 0x5f, 0x00},
400 {SENSOR, 0x60, 0x80},
401 {SENSOR, 0x78, 0x14},
402 {SENSOR, 0x6f, 0x01},
403 {SENSOR, PO1030_REG_CONTROL1, 0x18},
404 {SENSOR, PO1030_REG_GLOBALGAINMAX, 0x14},
405 {SENSOR, 0x63, 0x38},
406 {SENSOR, 0x64, 0x38},
407 {SENSOR, PO1030_REG_CONTROL1, 0x58},
408 {SENSOR, PO1030_REG_RED_GAIN, 0x30},
409 {SENSOR, PO1030_REG_GREEN_1_GAIN, 0x30},
410 {SENSOR, PO1030_REG_BLUE_GAIN, 0x30},
411 {SENSOR, PO1030_REG_GREEN_2_GAIN, 0x30},
412 {SENSOR, PO1030_REG_GC0, 0x10},
413 {SENSOR, PO1030_REG_GC1, 0x20},
414 {SENSOR, PO1030_REG_GC2, 0x40},
415 {SENSOR, PO1030_REG_GC3, 0x60},
416 {SENSOR, PO1030_REG_GC4, 0x80},
417 {SENSOR, PO1030_REG_GC5, 0xa0},
418 {SENSOR, PO1030_REG_GC6, 0xc0},
419 {SENSOR, PO1030_REG_GC7, 0xff},
420 /*end of sequence 4*/
421 /*sequence 5*/
422 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
423 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
424 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
425 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
426 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
427 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
428 {BRIDGE, M5602_XB_SIG_INI, 0x01},
429 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
430 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
431 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
432 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
433 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
434 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
435 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
436 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
437 {BRIDGE, M5602_XB_SIG_INI, 0x00},
438 {BRIDGE, M5602_XB_SIG_INI, 0x00},
439 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
440 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
441 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
442 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7e},
443 {BRIDGE, M5602_XB_SIG_INI, 0x00},
444 /*end of sequence 5*/
445
446 /*sequence 6*/
447 /* Changing 40 in f0 the image becomes green in bayer mode and red in
448 * rgb mode */
449 {SENSOR, PO1030_REG_RED_GAIN, PO1030_RED_GAIN_DEFAULT},
450 /* in changing 40 in f0 the image becomes green in bayer mode and red in
451 * rgb mode */
452 {SENSOR, PO1030_REG_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT},
453
454 /* with a very low lighted environment increase the exposure but
455 * decrease the FPS (Frame Per Second) */
456 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
457 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
458
459 /* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in
460 * low lighted environment (f0 is more than ff ?)*/
461 {SENSOR, PO1030_REG_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2)
462 & 0xff)},
463
464 /* Controls middle exposure, use only in high lighted environment */
465 {SENSOR, PO1030_REG_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff},
466
467 /* Controls clarity (not sure) */
468 {SENSOR, PO1030_REG_INTEGLINES_L, 0x00},
469 /* Controls gain (the image is more lighted) */
470 {SENSOR, PO1030_REG_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT},
471
472 /* Sets the width */
473 {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02},
474 {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}
475 /*end of sequence 6*/
476};
477
478#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
new file mode 100644
index 000000000000..68202565325d
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -0,0 +1,463 @@
1/*
2 * Driver for the s5k4aa sensor
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#include "m5602_s5k4aa.h"
20
21int s5k4aa_probe(struct sd *sd)
22{
23 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
24 const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75};
25 int i, err = 0;
26
27 if (force_sensor) {
28 if (force_sensor == S5K4AA_SENSOR) {
29 info("Forcing a %s sensor", s5k4aa.name);
30 goto sensor_found;
31 }
32 /* If we want to force another sensor, don't try to probe this
33 * one */
34 return -ENODEV;
35 }
36
37 info("Probing for a s5k4aa sensor");
38
39 /* Preinit the sensor */
40 for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) {
41 u8 data[2] = {0x00, 0x00};
42
43 switch (preinit_s5k4aa[i][0]) {
44 case BRIDGE:
45 err = m5602_write_bridge(sd,
46 preinit_s5k4aa[i][1],
47 preinit_s5k4aa[i][2]);
48 break;
49
50 case SENSOR:
51 data[0] = preinit_s5k4aa[i][2];
52 err = s5k4aa_write_sensor(sd,
53 preinit_s5k4aa[i][1],
54 data, 1);
55 break;
56
57 case SENSOR_LONG:
58 data[0] = preinit_s5k4aa[i][2];
59 data[1] = preinit_s5k4aa[i][3];
60 err = s5k4aa_write_sensor(sd,
61 preinit_s5k4aa[i][1],
62 data, 2);
63 break;
64 default:
65 info("Invalid stream command, exiting init");
66 return -EINVAL;
67 }
68 }
69
70 /* Test some registers, but we don't know their exact meaning yet */
71 if (s5k4aa_read_sensor(sd, 0x00, prod_id, sizeof(prod_id)))
72 return -ENODEV;
73
74 if (memcmp(prod_id, expected_prod_id, sizeof(prod_id)))
75 return -ENODEV;
76 else
77 info("Detected a s5k4aa sensor");
78sensor_found:
79 sd->gspca_dev.cam.cam_mode = s5k4aa.modes;
80 sd->gspca_dev.cam.nmodes = s5k4aa.nmodes;
81 sd->desc->ctrls = s5k4aa.ctrls;
82 sd->desc->nctrls = s5k4aa.nctrls;
83
84 return 0;
85}
86
87int s5k4aa_read_sensor(struct sd *sd, const u8 address,
88 u8 *i2c_data, const u8 len)
89{
90 int err, i;
91
92 do {
93 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
94 } while ((*i2c_data & I2C_BUSY) && !err);
95 if (err < 0)
96 goto out;
97
98 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
99 sd->sensor->i2c_slave_id);
100 if (err < 0)
101 goto out;
102
103 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
104 if (err < 0)
105 goto out;
106
107 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
108 if (err < 0)
109 goto out;
110
111 do {
112 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
113 } while ((*i2c_data & I2C_BUSY) && !err);
114 if (err < 0)
115 goto out;
116
117 for (i = 0; (i < len) & !err; i++) {
118 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
119
120 PDEBUG(DBG_TRACE, "Reading sensor register "
121 "0x%x containing 0x%x ", address, *i2c_data);
122 }
123out:
124 return (err < 0) ? err : 0;
125}
126
127int s5k4aa_write_sensor(struct sd *sd, const u8 address,
128 u8 *i2c_data, const u8 len)
129{
130 int err, i;
131 u8 *p;
132 struct usb_device *udev = sd->gspca_dev.dev;
133 __u8 *buf = sd->gspca_dev.usb_buf;
134
135 /* No sensor with a data width larger than 16 bits has yet been seen */
136 if (len > 2 || !len)
137 return -EINVAL;
138
139 memcpy(buf, sensor_urb_skeleton,
140 sizeof(sensor_urb_skeleton));
141
142 buf[11] = sd->sensor->i2c_slave_id;
143 buf[15] = address;
144
145 /* Special case larger sensor writes */
146 p = buf + 16;
147
148 /* Copy a four byte write sequence for each byte to be written to */
149 for (i = 0; i < len; i++) {
150 memcpy(p, sensor_urb_skeleton + 16, 4);
151 p[3] = i2c_data[i];
152 p += 4;
153 PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
154 address, i2c_data[i]);
155 }
156
157 /* Copy the tailer */
158 memcpy(p, sensor_urb_skeleton + 20, 4);
159
160 /* Set the total length */
161 p[3] = 0x10 + len;
162
163 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
164 0x04, 0x40, 0x19,
165 0x0000, buf,
166 20 + len * 4, M5602_URB_MSG_TIMEOUT);
167
168 return (err < 0) ? err : 0;
169}
170
171int s5k4aa_init(struct sd *sd)
172{
173 int i, err = 0;
174
175 for (i = 0; i < ARRAY_SIZE(init_s5k4aa) && !err; i++) {
176 u8 data[2] = {0x00, 0x00};
177
178 switch (init_s5k4aa[i][0]) {
179 case BRIDGE:
180 err = m5602_write_bridge(sd,
181 init_s5k4aa[i][1],
182 init_s5k4aa[i][2]);
183 break;
184
185 case SENSOR:
186 data[0] = init_s5k4aa[i][2];
187 err = s5k4aa_write_sensor(sd,
188 init_s5k4aa[i][1], data, 1);
189 break;
190
191 case SENSOR_LONG:
192 data[0] = init_s5k4aa[i][2];
193 data[1] = init_s5k4aa[i][3];
194 err = s5k4aa_write_sensor(sd,
195 init_s5k4aa[i][1], data, 2);
196 break;
197 default:
198 info("Invalid stream command, exiting init");
199 return -EINVAL;
200 }
201 }
202
203 if (dump_sensor)
204 s5k4aa_dump_registers(sd);
205
206 if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) {
207 u8 data = 0x02;
208 info("vertical flip quirk active");
209 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
210 s5k4aa_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
211 data |= S5K4AA_RM_V_FLIP;
212 data &= ~S5K4AA_RM_H_FLIP;
213 s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
214
215 /* Decrement COLSTART to preserve color order (BGGR) */
216 s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
217 data--;
218 s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
219
220 /* Increment ROWSTART to preserve color order (BGGR) */
221 s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
222 data++;
223 s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
224 }
225
226 return (err < 0) ? err : 0;
227}
228
229int s5k4aa_power_down(struct sd *sd)
230{
231 return 0;
232}
233
234int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
235{
236 struct sd *sd = (struct sd *) gspca_dev;
237 u8 data = S5K4AA_PAGE_MAP_2;
238 int err;
239
240 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
241 if (err < 0)
242 goto out;
243
244 err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
245 if (err < 0)
246 goto out;
247
248 *val = data << 8;
249 err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
250 *val |= data;
251 PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val);
252out:
253 return (err < 0) ? err : 0;
254}
255
256int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
257{
258 struct sd *sd = (struct sd *) gspca_dev;
259 u8 data = S5K4AA_PAGE_MAP_2;
260 int err;
261
262 PDEBUG(DBG_V4L2_CID, "Set exposure to %d", val);
263 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
264 if (err < 0)
265 goto out;
266 data = (val >> 8) & 0xff;
267 err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
268 if (err < 0)
269 goto out;
270 data = val & 0xff;
271 err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
272out:
273 return (err < 0) ? err : 0;
274}
275
276int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
277{
278 struct sd *sd = (struct sd *) gspca_dev;
279 u8 data = S5K4AA_PAGE_MAP_2;
280 int err;
281
282 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
283 if (err < 0)
284 goto out;
285
286 err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
287 *val = (data & S5K4AA_RM_V_FLIP) >> 7;
288 PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
289
290out:
291 return (err < 0) ? err : 0;
292}
293
294int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
295{
296 struct sd *sd = (struct sd *) gspca_dev;
297 u8 data = S5K4AA_PAGE_MAP_2;
298 int err;
299
300 PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
301 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
302 if (err < 0)
303 goto out;
304 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
305 if (err < 0)
306 goto out;
307 data = ((data & ~S5K4AA_RM_V_FLIP)
308 | ((val & 0x01) << 7));
309 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
310 if (err < 0)
311 goto out;
312
313 if (val) {
314 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
315 if (err < 0)
316 goto out;
317
318 data++;
319 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
320 } else {
321 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
322 if (err < 0)
323 goto out;
324
325 data--;
326 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
327 }
328out:
329 return (err < 0) ? err : 0;
330}
331
332int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
333{
334 struct sd *sd = (struct sd *) gspca_dev;
335 u8 data = S5K4AA_PAGE_MAP_2;
336 int err;
337
338 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
339 if (err < 0)
340 goto out;
341
342 err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
343 *val = (data & S5K4AA_RM_H_FLIP) >> 6;
344 PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
345out:
346 return (err < 0) ? err : 0;
347}
348
349int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
350{
351 struct sd *sd = (struct sd *) gspca_dev;
352 u8 data = S5K4AA_PAGE_MAP_2;
353 int err;
354
355 PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d",
356 val);
357 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
358 if (err < 0)
359 goto out;
360 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
361 if (err < 0)
362 goto out;
363
364 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
365 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
366 if (err < 0)
367 goto out;
368
369 if (val) {
370 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
371 if (err < 0)
372 goto out;
373 data++;
374 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
375 if (err < 0)
376 goto out;
377 } else {
378 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
379 if (err < 0)
380 goto out;
381 data--;
382 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
383 }
384out:
385 return (err < 0) ? err : 0;
386}
387
388int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
389{
390 struct sd *sd = (struct sd *) gspca_dev;
391 u8 data = S5K4AA_PAGE_MAP_2;
392 int err;
393
394 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
395 if (err < 0)
396 goto out;
397
398 err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
399 *val = data;
400 PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
401
402out:
403 return (err < 0) ? err : 0;
404}
405
406int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
407{
408 struct sd *sd = (struct sd *) gspca_dev;
409 u8 data = S5K4AA_PAGE_MAP_2;
410 int err;
411
412 PDEBUG(DBG_V4L2_CID, "Set gain to %d", val);
413 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
414 if (err < 0)
415 goto out;
416
417 data = val & 0xff;
418 err = s5k4aa_write_sensor(sd, S5K4AA_GAIN_2, &data, 1);
419
420out:
421 return (err < 0) ? err : 0;
422}
423
424void s5k4aa_dump_registers(struct sd *sd)
425{
426 int address;
427 u8 page, old_page;
428 s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
429 for (page = 0; page < 16; page++) {
430 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
431 info("Dumping the s5k4aa register state for page 0x%x", page);
432 for (address = 0; address <= 0xff; address++) {
433 u8 value = 0;
434 s5k4aa_read_sensor(sd, address, &value, 1);
435 info("register 0x%x contains 0x%x",
436 address, value);
437 }
438 }
439 info("s5k4aa register state dump complete");
440
441 for (page = 0; page < 16; page++) {
442 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
443 info("Probing for which registers that are "
444 "read/write for page 0x%x", page);
445 for (address = 0; address <= 0xff; address++) {
446 u8 old_value, ctrl_value, test_value = 0xff;
447
448 s5k4aa_read_sensor(sd, address, &old_value, 1);
449 s5k4aa_write_sensor(sd, address, &test_value, 1);
450 s5k4aa_read_sensor(sd, address, &ctrl_value, 1);
451
452 if (ctrl_value == test_value)
453 info("register 0x%x is writeable", address);
454 else
455 info("register 0x%x is read only", address);
456
457 /* Restore original value */
458 s5k4aa_write_sensor(sd, address, &old_value, 1);
459 }
460 }
461 info("Read/write register probing complete");
462 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
463}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
new file mode 100644
index 000000000000..bb7f7e3e90af
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -0,0 +1,370 @@
1/*
2 * Driver for the s5k4aa sensor
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#ifndef M5602_S5K4AA_H_
20#define M5602_S5K4AA_H_
21
22#include <linux/dmi.h>
23
24#include "m5602_sensor.h"
25
26/*****************************************************************************/
27
28#define S5K4AA_PAGE_MAP 0xec
29
30#define S5K4AA_PAGE_MAP_0 0x00
31#define S5K4AA_PAGE_MAP_1 0x01
32#define S5K4AA_PAGE_MAP_2 0x02
33
34/* Sensor register definitions for page 0x02 */
35#define S5K4AA_READ_MODE 0x03
36#define S5K4AA_ROWSTART_HI 0x04
37#define S5K4AA_ROWSTART_LO 0x05
38#define S5K4AA_COLSTART_HI 0x06
39#define S5K4AA_COLSTART_LO 0x07
40#define S5K4AA_WINDOW_HEIGHT_HI 0x08
41#define S5K4AA_WINDOW_HEIGHT_LO 0x09
42#define S5K4AA_WINDOW_WIDTH_HI 0x0a
43#define S5K4AA_WINDOW_WIDTH_LO 0x0b
44#define S5K4AA_GLOBAL_GAIN__ 0x0f /* Only a guess ATM !!! */
45#define S5K4AA_H_BLANK_HI__ 0x1d /* Only a guess ATM !!! sync lost
46 if too low, reduces frame rate
47 if too high */
48#define S5K4AA_H_BLANK_LO__ 0x1e /* Only a guess ATM !!! */
49#define S5K4AA_EXPOSURE_HI 0x17
50#define S5K4AA_EXPOSURE_LO 0x18
51#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */
52#define S5K4AA_GAIN_2 0x20 /* (analogue?) gain : 7 bits */
53
54#define S5K4AA_RM_ROW_SKIP_4X 0x08
55#define S5K4AA_RM_ROW_SKIP_2X 0x04
56#define S5K4AA_RM_COL_SKIP_4X 0x02
57#define S5K4AA_RM_COL_SKIP_2X 0x01
58#define S5K4AA_RM_H_FLIP 0x40
59#define S5K4AA_RM_V_FLIP 0x80
60
61/*****************************************************************************/
62
63/* Kernel module parameters */
64extern int force_sensor;
65extern int dump_sensor;
66extern unsigned int m5602_debug;
67
68int s5k4aa_probe(struct sd *sd);
69int s5k4aa_init(struct sd *sd);
70int s5k4aa_power_down(struct sd *sd);
71
72void s5k4aa_dump_registers(struct sd *sd);
73
74int s5k4aa_read_sensor(struct sd *sd, const u8 address,
75 u8 *i2c_data, const u8 len);
76int s5k4aa_write_sensor(struct sd *sd, const u8 address,
77 u8 *i2c_data, const u8 len);
78
79int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
80int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
81int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
82int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
83int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
84int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
85int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
86int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
87
88static struct m5602_sensor s5k4aa = {
89 .name = "S5K4AA",
90 .probe = s5k4aa_probe,
91 .init = s5k4aa_init,
92 .power_down = s5k4aa_power_down,
93 .read_sensor = s5k4aa_read_sensor,
94 .write_sensor = s5k4aa_write_sensor,
95 .i2c_slave_id = 0x5a,
96 .nctrls = 4,
97 .ctrls = {
98 {
99 {
100 .id = V4L2_CID_VFLIP,
101 .type = V4L2_CTRL_TYPE_BOOLEAN,
102 .name = "vertical flip",
103 .minimum = 0,
104 .maximum = 1,
105 .step = 1,
106 .default_value = 0
107 },
108 .set = s5k4aa_set_vflip,
109 .get = s5k4aa_get_vflip
110
111 }, {
112 {
113 .id = V4L2_CID_HFLIP,
114 .type = V4L2_CTRL_TYPE_BOOLEAN,
115 .name = "horizontal flip",
116 .minimum = 0,
117 .maximum = 1,
118 .step = 1,
119 .default_value = 0
120 },
121 .set = s5k4aa_set_hflip,
122 .get = s5k4aa_get_hflip
123
124 }, {
125 {
126 .id = V4L2_CID_GAIN,
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Gain",
129 .minimum = 0,
130 .maximum = 127,
131 .step = 1,
132 .default_value = 0xa0,
133 .flags = V4L2_CTRL_FLAG_SLIDER
134 },
135 .set = s5k4aa_set_gain,
136 .get = s5k4aa_get_gain
137 }, {
138 {
139 .id = V4L2_CID_EXPOSURE,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "Exposure",
142 .minimum = 13,
143 .maximum = 0xfff,
144 .step = 1,
145 .default_value = 0x100,
146 .flags = V4L2_CTRL_FLAG_SLIDER
147 },
148 .set = s5k4aa_set_exposure,
149 .get = s5k4aa_get_exposure
150 }
151 },
152
153 .nmodes = 1,
154 .modes = {
155 {
156 M5602_DEFAULT_FRAME_WIDTH,
157 M5602_DEFAULT_FRAME_HEIGHT,
158 V4L2_PIX_FMT_SBGGR8,
159 V4L2_FIELD_NONE,
160 .sizeimage =
161 M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
162 .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
163 .colorspace = V4L2_COLORSPACE_SRGB,
164 .priv = 1
165 }
166 }
167};
168
169static const unsigned char preinit_s5k4aa[][4] =
170{
171 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
172 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
173 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
174 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
175 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
176 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
177 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
178
179 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
180 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
181 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
182 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
183 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
184 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
185 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
186 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
187 {BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00},
188 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
189 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
190 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
191 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
192 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
193 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
194 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
195
196 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
197 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
198 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
199 {BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00},
200 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
201 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
202 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
203 {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
204 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
205 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
206 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
207 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
208 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
209
210 {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00}
211};
212
213static const unsigned char init_s5k4aa[][4] =
214{
215 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
216 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
217 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
218 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
219 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
220 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
221 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
222
223 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
224 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
225 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
226 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
227 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
228 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
229 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
230 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
231 {BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00},
232 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
233 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
234 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
235 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
236 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
237 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
238 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
239
240 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
241 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
242 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
243 {BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00},
244 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
245 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
246 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
247 {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
248 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
249 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
250 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
251 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
252 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
253
254 {SENSOR, S5K4AA_PAGE_MAP, 0x07, 0x00},
255 {SENSOR, 0x36, 0x01, 0x00},
256 {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00},
257 {SENSOR, 0x7b, 0xff, 0x00},
258 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
259 {SENSOR, 0x0c, 0x05, 0x00},
260 {SENSOR, 0x02, 0x0e, 0x00},
261 {SENSOR, S5K4AA_GAIN_1, 0x0f, 0x00},
262 {SENSOR, S5K4AA_GAIN_2, 0x00, 0x00},
263 {SENSOR, S5K4AA_GLOBAL_GAIN__, 0x01, 0x00},
264 {SENSOR, 0x11, 0x00, 0x00},
265 {SENSOR, 0x12, 0x00, 0x00},
266 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
267 {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00},
268 {SENSOR, 0x37, 0x00, 0x00},
269 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
270 {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
271 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
272 {SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00},
273 {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
274 {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc4, 0x00},
275 {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
276 {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x08, 0x00},
277 {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
278 {SENSOR, S5K4AA_H_BLANK_LO__, 0x48, 0x00},
279 {SENSOR, S5K4AA_EXPOSURE_HI, 0x00, 0x00},
280 {SENSOR, S5K4AA_EXPOSURE_LO, 0x43, 0x00},
281 {SENSOR, 0x11, 0x04, 0x00},
282 {SENSOR, 0x12, 0xc3, 0x00},
283 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
284
285 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
286 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
287 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
288 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
289 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
290 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
291 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
292 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
293 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
294 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
295 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
296 /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */
297 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
298 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
299 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
300 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
301 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
302 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
303 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
304 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
305 /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */
306 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
307 {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00},
308 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
309 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
310 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
311
312 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
313 {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
314 | S5K4AA_RM_COL_SKIP_2X, 0x00},
315 /* 0x37 : Fix image stability when light is too bright and improves
316 * image quality in 640x480, but worsens it in 1280x1024 */
317 {SENSOR, 0x37, 0x01, 0x00},
318 /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
319 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
320 {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
321 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
322 {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
323 /* window_height_hi, window_height_lo : 960 = 0x03c0 */
324 {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
325 {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
326 /* window_width_hi, window_width_lo : 1280 = 0x0500 */
327 {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
328 {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
329 {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
330 {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */
331 {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
332 {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
333 {SENSOR, 0x11, 0x04, 0x00},
334 {SENSOR, 0x12, 0xc3, 0x00},
335 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
336 {SENSOR, 0x02, 0x0e, 0x00},
337 {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
338 {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
339 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
340};
341
342static
343 const
344 struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
345 {
346 .ident = "Fujitsu-Siemens Amilo Xa 2528",
347 .matches = {
348 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
349 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
350 }
351 },
352 {
353 .ident = "Fujitsu-Siemens Amilo Xi 2550",
354 .matches = {
355 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
356 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
357 }
358 },
359 {
360 .ident = "MSI GX700",
361 .matches = {
362 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
363 DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
364 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
365 }
366 },
367 { }
368};
369
370#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
new file mode 100644
index 000000000000..b4b33c2d0499
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -0,0 +1,423 @@
1/*
2 * Driver for the s5k83a sensor
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#include "m5602_s5k83a.h"
20
21int s5k83a_probe(struct sd *sd)
22{
23 u8 prod_id = 0, ver_id = 0;
24 int i, err = 0;
25
26 if (force_sensor) {
27 if (force_sensor == S5K83A_SENSOR) {
28 info("Forcing a %s sensor", s5k83a.name);
29 goto sensor_found;
30 }
31 /* If we want to force another sensor, don't try to probe this
32 * one */
33 return -ENODEV;
34 }
35
36 info("Probing for a s5k83a sensor");
37
38 /* Preinit the sensor */
39 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
40 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
41 if (preinit_s5k83a[i][0] == SENSOR)
42 err = s5k83a_write_sensor(sd, preinit_s5k83a[i][1],
43 data, 2);
44 else
45 err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
46 data[0]);
47 }
48
49 /* 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
51 * on multiple machines */
52 if (s5k83a_read_sensor(sd, 0x00, &prod_id, 1))
53 return -ENODEV;
54
55 if (s5k83a_read_sensor(sd, 0x01, &ver_id, 1))
56 return -ENODEV;
57
58 if ((prod_id == 0xff) || (ver_id == 0xff))
59 return -ENODEV;
60 else
61 info("Detected a s5k83a sensor");
62
63sensor_found:
64 sd->gspca_dev.cam.cam_mode = s5k83a.modes;
65 sd->gspca_dev.cam.nmodes = s5k83a.nmodes;
66 sd->desc->ctrls = s5k83a.ctrls;
67 sd->desc->nctrls = s5k83a.nctrls;
68 return 0;
69}
70
71int s5k83a_read_sensor(struct sd *sd, const u8 address,
72 u8 *i2c_data, const u8 len)
73{
74 int err, i;
75
76 do {
77 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
78 } while ((*i2c_data & I2C_BUSY) && !err);
79 if (err < 0)
80 goto out;
81
82 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
83 sd->sensor->i2c_slave_id);
84 if (err < 0)
85 goto out;
86
87 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
88 if (err < 0)
89 goto out;
90
91 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
92 if (err < 0)
93 goto out;
94
95 do {
96 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
97 } while ((*i2c_data & I2C_BUSY) && !err);
98
99 if (err < 0)
100 goto out;
101 for (i = 0; i < len && !len; i++) {
102 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
103
104 PDEBUG(DBG_TRACE, "Reading sensor register "
105 "0x%x containing 0x%x ", address, *i2c_data);
106 }
107
108out:
109 return (err < 0) ? err : 0;
110}
111
112int s5k83a_write_sensor(struct sd *sd, const u8 address,
113 u8 *i2c_data, const u8 len)
114{
115 int err, i;
116 u8 *p;
117 struct usb_device *udev = sd->gspca_dev.dev;
118 __u8 *buf = sd->gspca_dev.usb_buf;
119
120 /* No sensor with a data width larger than 16 bits has yet been seen */
121 if (len > 2 || !len)
122 return -EINVAL;
123
124 memcpy(buf, sensor_urb_skeleton,
125 sizeof(sensor_urb_skeleton));
126
127 buf[11] = sd->sensor->i2c_slave_id;
128 buf[15] = address;
129
130 /* Special case larger sensor writes */
131 p = buf + 16;
132
133 /* Copy a four byte write sequence for each byte to be written to */
134 for (i = 0; i < len; i++) {
135 memcpy(p, sensor_urb_skeleton + 16, 4);
136 p[3] = i2c_data[i];
137 p += 4;
138 PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
139 address, i2c_data[i]);
140 }
141
142 /* Copy the tailer */
143 memcpy(p, sensor_urb_skeleton + 20, 4);
144
145 /* Set the total length */
146 p[3] = 0x10 + len;
147
148 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
149 0x04, 0x40, 0x19,
150 0x0000, buf,
151 20 + len * 4, M5602_URB_MSG_TIMEOUT);
152
153 return (err < 0) ? err : 0;
154}
155
156int s5k83a_init(struct sd *sd)
157{
158 int i, err = 0;
159
160 for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
161 u8 data[2] = {0x00, 0x00};
162
163 switch (init_s5k83a[i][0]) {
164 case BRIDGE:
165 err = m5602_write_bridge(sd,
166 init_s5k83a[i][1],
167 init_s5k83a[i][2]);
168 break;
169
170 case SENSOR:
171 data[0] = init_s5k83a[i][2];
172 err = s5k83a_write_sensor(sd,
173 init_s5k83a[i][1], data, 1);
174 break;
175
176 case SENSOR_LONG:
177 data[0] = init_s5k83a[i][2];
178 data[1] = init_s5k83a[i][3];
179 err = s5k83a_write_sensor(sd,
180 init_s5k83a[i][1], data, 2);
181 break;
182 default:
183 info("Invalid stream command, exiting init");
184 return -EINVAL;
185 }
186 }
187
188 if (dump_sensor)
189 s5k83a_dump_registers(sd);
190
191 return (err < 0) ? err : 0;
192}
193
194int s5k83a_power_down(struct sd *sd)
195{
196 return 0;
197}
198
199void s5k83a_dump_registers(struct sd *sd)
200{
201 int address;
202 u8 page, old_page;
203 s5k83a_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
204
205 for (page = 0; page < 16; page++) {
206 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
207 info("Dumping the s5k83a register state for page 0x%x", page);
208 for (address = 0; address <= 0xff; address++) {
209 u8 val = 0;
210 s5k83a_read_sensor(sd, address, &val, 1);
211 info("register 0x%x contains 0x%x",
212 address, val);
213 }
214 }
215 info("s5k83a register state dump complete");
216
217 for (page = 0; page < 16; page++) {
218 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
219 info("Probing for which registers that are read/write "
220 "for page 0x%x", page);
221 for (address = 0; address <= 0xff; address++) {
222 u8 old_val, ctrl_val, test_val = 0xff;
223
224 s5k83a_read_sensor(sd, address, &old_val, 1);
225 s5k83a_write_sensor(sd, address, &test_val, 1);
226 s5k83a_read_sensor(sd, address, &ctrl_val, 1);
227
228 if (ctrl_val == test_val)
229 info("register 0x%x is writeable", address);
230 else
231 info("register 0x%x is read only", address);
232
233 /* Restore original val */
234 s5k83a_write_sensor(sd, address, &old_val, 1);
235 }
236 }
237 info("Read/write register probing complete");
238 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
239}
240
241int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
242{
243 int err;
244 u8 data[2];
245 struct sd *sd = (struct sd *) gspca_dev;
246
247 err = s5k83a_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
248 data[1] = data[1] << 1;
249 *val = data[1];
250
251 return (err < 0) ? err : 0;
252}
253
254int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
255{
256 int err;
257 u8 data[2];
258 struct sd *sd = (struct sd *) gspca_dev;
259
260 data[0] = 0x00;
261 data[1] = 0x20;
262 err = s5k83a_write_sensor(sd, 0x14, data, 2);
263 if (err < 0)
264 return err;
265
266 data[0] = 0x01;
267 data[1] = 0x00;
268 err = s5k83a_write_sensor(sd, 0x0d, data, 2);
269 if (err < 0)
270 return err;
271
272 /* FIXME: This is not sane, we need to figure out the composition
273 of these registers */
274 data[0] = val >> 3; /* brightness, high 5 bits */
275 data[1] = val >> 1; /* brightness, high 7 bits */
276 err = s5k83a_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
277
278 return (err < 0) ? err : 0;
279}
280
281int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
282{
283 int err;
284 u8 data;
285 struct sd *sd = (struct sd *) gspca_dev;
286
287 err = s5k83a_read_sensor(sd, S5K83A_WHITENESS, &data, 1);
288
289 *val = data;
290 return (err < 0) ? err : 0;
291}
292
293int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
294{
295 int err;
296 u8 data[1];
297 struct sd *sd = (struct sd *) gspca_dev;
298
299 data[0] = val;
300 err = s5k83a_write_sensor(sd, S5K83A_WHITENESS, data, 1);
301
302 return (err < 0) ? err : 0;
303}
304
305int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
306{
307 int err;
308 u8 data[2];
309 struct sd *sd = (struct sd *) gspca_dev;
310
311 err = s5k83a_read_sensor(sd, S5K83A_GAIN, data, 2);
312
313 data[1] = data[1] & 0x3f;
314 if (data[1] > S5K83A_MAXIMUM_GAIN)
315 data[1] = S5K83A_MAXIMUM_GAIN;
316
317 *val = data[1];
318
319 return (err < 0) ? err : 0;
320}
321
322int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
323{
324 int err;
325 u8 data[2];
326 struct sd *sd = (struct sd *) gspca_dev;
327
328 data[0] = 0;
329 data[1] = val;
330 err = s5k83a_write_sensor(sd, S5K83A_GAIN, data, 2);
331
332 return (err < 0) ? err : 0;
333}
334
335int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
336{
337 int err;
338 u8 data[1];
339 struct sd *sd = (struct sd *) gspca_dev;
340
341 data[0] = 0x05;
342 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
343 if (err < 0)
344 return err;
345
346 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1);
347 *val = (data[0] | 0x40) ? 1 : 0;
348
349 return (err < 0) ? err : 0;
350}
351
352int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
353{
354 int err;
355 u8 data[1];
356 struct sd *sd = (struct sd *) gspca_dev;
357
358 data[0] = 0x05;
359 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
360 if (err < 0)
361 return err;
362
363 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1);
364 if (err < 0)
365 return err;
366
367 /* set or zero six bit, seven is hflip */
368 data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
369 : (data[0] & 0x80) | S5K83A_FLIP_MASK;
370 err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1);
371 if (err < 0)
372 return err;
373
374 data[0] = (val) ? 0x0b : 0x0a;
375 err = s5k83a_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
376
377 return (err < 0) ? err : 0;
378}
379
380int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
381{
382 int err;
383 u8 data[1];
384 struct sd *sd = (struct sd *) gspca_dev;
385
386 data[0] = 0x05;
387 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
388 if (err < 0)
389 return err;
390
391 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1);
392 *val = (data[0] | 0x80) ? 1 : 0;
393
394 return (err < 0) ? err : 0;
395}
396
397int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
398{
399 int err;
400 u8 data[1];
401 struct sd *sd = (struct sd *) gspca_dev;
402
403 data[0] = 0x05;
404 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
405 if (err < 0)
406 return err;
407
408 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1);
409 if (err < 0)
410 return err;
411
412 /* set or zero seven bit, six is vflip */
413 data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
414 : (data[0] & 0x40) | S5K83A_FLIP_MASK;
415 err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1);
416 if (err < 0)
417 return err;
418
419 data[0] = (val) ? 0x0a : 0x0b;
420 err = s5k83a_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
421
422 return (err < 0) ? err : 0;
423}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
new file mode 100644
index 000000000000..833708eb5a42
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -0,0 +1,484 @@
1/*
2 * Driver for the s5k83a sensor
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#ifndef M5602_S5K83A_H_
20#define M5602_S5K83A_H_
21
22#include "m5602_sensor.h"
23
24#define S5K83A_FLIP 0x01
25#define S5K83A_HFLIP_TUNE 0x03
26#define S5K83A_VFLIP_TUNE 0x05
27#define S5K83A_WHITENESS 0x0a
28#define S5K83A_GAIN 0x18
29#define S5K83A_BRIGHTNESS 0x1b
30#define S5K83A_PAGE_MAP 0xec
31
32#define S5K83A_DEFAULT_BRIGHTNESS 0x71
33#define S5K83A_DEFAULT_WHITENESS 0x7e
34#define S5K83A_DEFAULT_GAIN 0x00
35#define S5K83A_MAXIMUM_GAIN 0x3c
36#define S5K83A_FLIP_MASK 0x10
37
38
39/*****************************************************************************/
40
41/* Kernel module parameters */
42extern int force_sensor;
43extern int dump_sensor;
44extern unsigned int m5602_debug;
45
46
47int s5k83a_probe(struct sd *sd);
48int s5k83a_init(struct sd *sd);
49int s5k83a_power_down(struct sd *sd);
50
51void s5k83a_dump_registers(struct sd *sd);
52
53int s5k83a_read_sensor(struct sd *sd, const u8 address,
54 u8 *i2c_data, const u8 len);
55int s5k83a_write_sensor(struct sd *sd, const u8 address,
56 u8 *i2c_data, const u8 len);
57
58int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
59int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
60int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
61int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val);
62int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
63int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
64int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
65int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
66int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
67int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
68
69
70static struct m5602_sensor s5k83a = {
71 .name = "S5K83A",
72 .probe = s5k83a_probe,
73 .init = s5k83a_init,
74 .power_down = s5k83a_power_down,
75 .read_sensor = s5k83a_read_sensor,
76 .write_sensor = s5k83a_write_sensor,
77 .i2c_slave_id = 0x5a,
78 .nctrls = 5,
79 .ctrls = {
80 {
81 {
82 .id = V4L2_CID_BRIGHTNESS,
83 .type = V4L2_CTRL_TYPE_INTEGER,
84 .name = "brightness",
85 .minimum = 0x00,
86 .maximum = 0xff,
87 .step = 0x01,
88 .default_value = S5K83A_DEFAULT_BRIGHTNESS,
89 .flags = V4L2_CTRL_FLAG_SLIDER
90 },
91 .set = s5k83a_set_brightness,
92 .get = s5k83a_get_brightness
93
94 }, {
95 {
96 .id = V4L2_CID_WHITENESS,
97 .type = V4L2_CTRL_TYPE_INTEGER,
98 .name = "whiteness",
99 .minimum = 0x00,
100 .maximum = 0xff,
101 .step = 0x01,
102 .default_value = S5K83A_DEFAULT_WHITENESS,
103 .flags = V4L2_CTRL_FLAG_SLIDER
104 },
105 .set = s5k83a_set_whiteness,
106 .get = s5k83a_get_whiteness,
107 }, {
108 {
109 .id = V4L2_CID_GAIN,
110 .type = V4L2_CTRL_TYPE_INTEGER,
111 .name = "gain",
112 .minimum = 0x00,
113 .maximum = S5K83A_MAXIMUM_GAIN,
114 .step = 0x01,
115 .default_value = S5K83A_DEFAULT_GAIN,
116 .flags = V4L2_CTRL_FLAG_SLIDER
117 },
118 .set = s5k83a_set_gain,
119 .get = s5k83a_get_gain
120 }, {
121 {
122 .id = V4L2_CID_HFLIP,
123 .type = V4L2_CTRL_TYPE_BOOLEAN,
124 .name = "horizontal flip",
125 .minimum = 0,
126 .maximum = 1,
127 .step = 1,
128 .default_value = 0
129 },
130 .set = s5k83a_set_hflip,
131 .get = s5k83a_get_hflip
132 }, {
133 {
134 .id = V4L2_CID_VFLIP,
135 .type = V4L2_CTRL_TYPE_BOOLEAN,
136 .name = "vertical flip",
137 .minimum = 0,
138 .maximum = 1,
139 .step = 1,
140 .default_value = 0
141 },
142 .set = s5k83a_set_vflip,
143 .get = s5k83a_get_vflip
144 }
145 },
146 .nmodes = 1,
147 .modes = {
148 {
149 M5602_DEFAULT_FRAME_WIDTH,
150 M5602_DEFAULT_FRAME_HEIGHT,
151 V4L2_PIX_FMT_SBGGR8,
152 V4L2_FIELD_NONE,
153 .sizeimage =
154 M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
155 .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
156 .colorspace = V4L2_COLORSPACE_SRGB,
157 .priv = 1
158 }
159 }
160};
161
162static const unsigned char preinit_s5k83a[][4] =
163{
164 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
165 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
166 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
167 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
168 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
169 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
170 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
171
172 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
173 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
174 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
175 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
176 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
177 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
178 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
179 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
180 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
181 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
182 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
183 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
184 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
185 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
186 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
187 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
188 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
189 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
190 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
191 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
192 {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
193 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
194 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
195 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
196 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
197 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
198
199 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}
200};
201
202/* This could probably be considerably shortened.
203 I don't have the hardware to experiment with it, patches welcome
204*/
205static const unsigned char init_s5k83a[][4] =
206{
207 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
208 {SENSOR, 0xaf, 0x01, 0x00},
209 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
210 {SENSOR, 0x7b, 0xff, 0x00},
211 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
212 {SENSOR, 0x01, 0x50, 0x00},
213 {SENSOR, 0x12, 0x20, 0x00},
214 {SENSOR, 0x17, 0x40, 0x00},
215 {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
216 {SENSOR, 0x1c, 0x00, 0x00},
217 {SENSOR, 0x02, 0x70, 0x00},
218 {SENSOR, 0x03, 0x0b, 0x00},
219 {SENSOR, 0x04, 0xf0, 0x00},
220 {SENSOR, 0x05, 0x0b, 0x00},
221 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
222
223 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
224 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
225 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
226 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
227 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
228 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
229 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
230 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
231 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
232 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
233 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
234 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
235 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
236 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
237 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
238 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
239 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
240 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
241 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
242 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
243 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
244 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
245 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
246 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
247
248 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
249 {SENSOR, 0x06, 0x71, 0x00},
250 {SENSOR, 0x07, 0xe8, 0x00},
251 {SENSOR, 0x08, 0x02, 0x00},
252 {SENSOR, 0x09, 0x88, 0x00},
253 {SENSOR, 0x14, 0x00, 0x00},
254 {SENSOR, 0x15, 0x20, 0x00},
255 {SENSOR, 0x19, 0x00, 0x00},
256 {SENSOR, 0x1a, 0x98, 0x00},
257 {SENSOR, 0x0f, 0x02, 0x00},
258 {SENSOR, 0x10, 0xe5, 0x00},
259 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
260 {SENSOR_LONG, 0x14, 0x00, 0x20},
261 {SENSOR_LONG, 0x0d, 0x00, 0x7d},
262 {SENSOR_LONG, 0x1b, 0x0d, 0x05},
263
264 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
265 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
266 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
267 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
268 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
269 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
270 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
271 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
272 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
273 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
274 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
275 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
276 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
277 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
278 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
279 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
280 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
281 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
282 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
283 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
284 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
285
286 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
287 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
288 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
289 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
290 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
291 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
292 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
293 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
294 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
295 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
296 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
297 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
298 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
299 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
300 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
301 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
302 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
303 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
304 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
305 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
306 {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
307 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
308 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
309 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
310 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
311 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
312
313 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
314 {SENSOR, 0xaf, 0x01, 0x00},
315 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
316 /* ff ( init value )is very dark) || 71 and f0 better */
317 {SENSOR, 0x7b, 0xff, 0x00},
318 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
319 {SENSOR, 0x01, 0x50, 0x00},
320 {SENSOR, 0x12, 0x20, 0x00},
321 {SENSOR, 0x17, 0x40, 0x00},
322 {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
323 {SENSOR, 0x1c, 0x00, 0x00},
324 {SENSOR, 0x02, 0x70, 0x00},
325 /* some values like 0x10 give a blue-purple image */
326 {SENSOR, 0x03, 0x0b, 0x00},
327 {SENSOR, 0x04, 0xf0, 0x00},
328 {SENSOR, 0x05, 0x0b, 0x00},
329 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
330
331 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
332 /* under 80 don't work, highter depend on value */
333 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
334
335 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
336 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
337 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
338 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
339 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
340 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
341 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
342 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
343 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
344 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
345 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
346 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
347 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
348 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
349 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
350 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
351 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
352 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
353
354 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
355 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
356 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
357
358 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
359 {SENSOR, 0x06, 0x71, 0x00},
360 {SENSOR, 0x07, 0xe8, 0x00},
361 {SENSOR, 0x08, 0x02, 0x00},
362 {SENSOR, 0x09, 0x88, 0x00},
363 {SENSOR, 0x14, 0x00, 0x00},
364 {SENSOR, 0x15, 0x20, 0x00},
365 {SENSOR, 0x19, 0x00, 0x00},
366 {SENSOR, 0x1a, 0x98, 0x00},
367 {SENSOR, 0x0f, 0x02, 0x00},
368 {SENSOR, 0x10, 0xe5, 0x00},
369 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
370 {SENSOR_LONG, 0x14, 0x00, 0x20},
371 {SENSOR_LONG, 0x0d, 0x00, 0x7d},
372 {SENSOR_LONG, 0x1b, 0x0d, 0x05},
373
374 /* The following sequence is useless after a clean boot
375 but is necessary after resume from suspend */
376 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
377 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
378 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
379 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
380 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
381 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
382 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
383 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
384 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
385 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
386 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
387 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
388 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
389 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
390 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
391 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
392 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
393 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
394 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
395 {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
396 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
397 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
398 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
399 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
400 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
401
402 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
403 {SENSOR, 0xaf, 0x01, 0x00},
404 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
405 {SENSOR, 0x7b, 0xff, 0x00},
406 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
407 {SENSOR, 0x01, 0x50, 0x00},
408 {SENSOR, 0x12, 0x20, 0x00},
409 {SENSOR, 0x17, 0x40, 0x00},
410 {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
411 {SENSOR, 0x1c, 0x00, 0x00},
412 {SENSOR, 0x02, 0x70, 0x00},
413 {SENSOR, 0x03, 0x0b, 0x00},
414 {SENSOR, 0x04, 0xf0, 0x00},
415 {SENSOR, 0x05, 0x0b, 0x00},
416 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
417
418 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
419 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
420 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
421 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
422 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
423 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
424 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
425 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
426 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
427 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
428 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
429 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
430 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
431 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
432 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
433 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
434 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
435 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
436 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
437 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
438 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
439 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
440 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
441 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
442
443 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
444 {SENSOR, 0x06, 0x71, 0x00},
445 {SENSOR, 0x07, 0xe8, 0x00},
446 {SENSOR, 0x08, 0x02, 0x00},
447 {SENSOR, 0x09, 0x88, 0x00},
448 {SENSOR, 0x14, 0x00, 0x00},
449 {SENSOR, 0x15, 0x20, 0x00},
450 {SENSOR, 0x19, 0x00, 0x00},
451 {SENSOR, 0x1a, 0x98, 0x00},
452 {SENSOR, 0x0f, 0x02, 0x00},
453
454 {SENSOR, 0x10, 0xe5, 0x00},
455 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
456 {SENSOR_LONG, 0x14, 0x00, 0x20},
457 {SENSOR_LONG, 0x0d, 0x00, 0x7d},
458 {SENSOR_LONG, 0x1b, 0x0d, 0x05},
459
460 /* normal colors
461 (this is value after boot, but after tries can be different) */
462 {SENSOR, 0x00, 0x06, 0x00},
463
464 /* set default brightness */
465 {SENSOR_LONG, 0x14, 0x00, 0x20},
466 {SENSOR_LONG, 0x0d, 0x01, 0x00},
467 {SENSOR_LONG, 0x1b, S5K83A_DEFAULT_BRIGHTNESS >> 3,
468 S5K83A_DEFAULT_BRIGHTNESS >> 1},
469
470 /* set default whiteness */
471 {SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00},
472
473 /* set default gain */
474 {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN},
475
476 /* set default flip */
477 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
478 {SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00},
479 {SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00},
480 {SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00}
481
482};
483
484#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
new file mode 100644
index 000000000000..930fcaab4416
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -0,0 +1,76 @@
1/*
2 * USB Driver for ALi m5602 based webcams
3 *
4 * Copyright (C) 2008 Erik Andren
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#ifndef M5602_SENSOR_H_
20#define M5602_SENSOR_H_
21
22#include "m5602_bridge.h"
23
24#define M5602_DEFAULT_FRAME_WIDTH 640
25#define M5602_DEFAULT_FRAME_HEIGHT 480
26
27#define M5602_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
28
29/* Enumerates all supported sensors */
30enum sensors {
31 OV9650_SENSOR = 1,
32 S5K83A_SENSOR = 2,
33 S5K4AA_SENSOR = 3,
34 MT9M111_SENSOR = 4,
35 PO1030_SENSOR = 5
36};
37
38/* Enumerates all possible instruction types */
39enum instruction {
40 BRIDGE,
41 SENSOR,
42 SENSOR_LONG
43};
44
45struct m5602_sensor {
46 /* Defines the name of a sensor */
47 char name[32];
48
49 /* What i2c address the sensor is connected to */
50 u8 i2c_slave_id;
51
52 /* Probes if the sensor is connected */
53 int (*probe)(struct sd *sd);
54
55 /* Performs a initialization sequence */
56 int (*init)(struct sd *sd);
57
58 /* Performs a power down sequence */
59 int (*power_down)(struct sd *sd);
60
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;
70 struct ctrl ctrls[M5602_MAX_CTRLS];
71
72 char nmodes;
73 struct v4l2_pix_format modes[];
74};
75
76#endif
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 4d5db47ba8cb..277ca34a8817 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -134,7 +134,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
134 return 0; 134 return 0;
135} 135}
136 136
137static void sd_start(struct gspca_dev *gspca_dev) 137static int sd_start(struct gspca_dev *gspca_dev)
138{ 138{
139 int err_code; 139 int err_code;
140 __u8 *data; 140 __u8 *data;
@@ -143,9 +143,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
143 int intpipe; 143 int intpipe;
144 144
145 PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); 145 PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
146 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8) < 0) { 146 err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8);
147 if (err_code < 0) {
147 PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); 148 PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
148 return; 149 return err_code;
149 } 150 }
150 151
151 data = gspca_dev->usb_buf; 152 data = gspca_dev->usb_buf;
@@ -154,7 +155,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
154 155
155 err_code = reg_w(gspca_dev, data[0], 2); 156 err_code = reg_w(gspca_dev, data[0], 2);
156 if (err_code < 0) 157 if (err_code < 0)
157 return; 158 return err_code;
158 159
159 /* 160 /*
160 Initialize the MR97113 chip register 161 Initialize the MR97113 chip register
@@ -180,14 +181,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
180 181
181 err_code = reg_w(gspca_dev, data[0], 11); 182 err_code = reg_w(gspca_dev, data[0], 11);
182 if (err_code < 0) 183 if (err_code < 0)
183 return; 184 return err_code;
184 185
185 data[0] = 0x23; /* address */ 186 data[0] = 0x23; /* address */
186 data[1] = 0x09; /* reg 35, append frame header */ 187 data[1] = 0x09; /* reg 35, append frame header */
187 188
188 err_code = reg_w(gspca_dev, data[0], 2); 189 err_code = reg_w(gspca_dev, data[0], 2);
189 if (err_code < 0) 190 if (err_code < 0)
190 return; 191 return err_code;
191 192
192 data[0] = 0x3c; /* address */ 193 data[0] = 0x3c; /* address */
193/* if (gspca_dev->width == 1280) */ 194/* if (gspca_dev->width == 1280) */
@@ -198,7 +199,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
198 * (unit: 4KB) 200KB */ 199 * (unit: 4KB) 200KB */
199 err_code = reg_w(gspca_dev, data[0], 2); 200 err_code = reg_w(gspca_dev, data[0], 2);
200 if (err_code < 0) 201 if (err_code < 0)
201 return; 202 return err_code;
202 203
203 if (0) { /* fixed dark-gain */ 204 if (0) { /* fixed dark-gain */
204 data[1] = 0; /* reg 94, Y Gain (1.75) */ 205 data[1] = 0; /* reg 94, Y Gain (1.75) */
@@ -240,13 +241,13 @@ static void sd_start(struct gspca_dev *gspca_dev)
240 241
241 err_code = reg_w(gspca_dev, data[0], 6); 242 err_code = reg_w(gspca_dev, data[0], 6);
242 if (err_code < 0) 243 if (err_code < 0)
243 return; 244 return err_code;
244 245
245 data[0] = 0x67; 246 data[0] = 0x67;
246 data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ 247 data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */
247 err_code = reg_w(gspca_dev, data[0], 2); 248 err_code = reg_w(gspca_dev, data[0], 2);
248 if (err_code < 0) 249 if (err_code < 0)
249 return; 250 return err_code;
250 251
251 /* 252 /*
252 * initialize the value of MI sensor... 253 * initialize the value of MI sensor...
@@ -326,6 +327,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
326 data[0] = 0x00; 327 data[0] = 0x00;
327 data[1] = 0x4d; /* ISOC transfering enable... */ 328 data[1] = 0x4d; /* ISOC transfering enable... */
328 reg_w(gspca_dev, data[0], 2); 329 reg_w(gspca_dev, data[0], 2);
330 return err_code;
329} 331}
330 332
331static void sd_stopN(struct gspca_dev *gspca_dev) 333static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 4df4eec9f7e7..ca671194679e 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1854,7 +1854,7 @@ static int set_ov_sensor_window(struct sd *sd)
1854} 1854}
1855 1855
1856/* -- start the camera -- */ 1856/* -- start the camera -- */
1857static void sd_start(struct gspca_dev *gspca_dev) 1857static int sd_start(struct gspca_dev *gspca_dev)
1858{ 1858{
1859 struct sd *sd = (struct sd *) gspca_dev; 1859 struct sd *sd = (struct sd *) gspca_dev;
1860 int ret; 1860 int ret;
@@ -1871,9 +1871,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
1871 goto out; 1871 goto out;
1872 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); 1872 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
1873 ov51x_led_control(sd, 1); 1873 ov51x_led_control(sd, 1);
1874 return; 1874 return 0;
1875out: 1875out:
1876 PDEBUG(D_ERR, "camera start error:%d", ret); 1876 PDEBUG(D_ERR, "camera start error:%d", ret);
1877 return ret;
1877} 1878}
1878 1879
1879static void sd_stopN(struct gspca_dev *gspca_dev) 1880static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 83b5f740c947..0b0c573d06da 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -281,7 +281,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
281} 281}
282 282
283/* -- start the camera -- */ 283/* -- start the camera -- */
284static void sd_start(struct gspca_dev *gspca_dev) 284static int sd_start(struct gspca_dev *gspca_dev)
285{ 285{
286 struct sd *sd = (struct sd *) gspca_dev; 286 struct sd *sd = (struct sd *) gspca_dev;
287 __u8 mode; 287 __u8 mode;
@@ -323,6 +323,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
323 sd->sof_read = 0; 323 sd->sof_read = 0;
324 sd->autogain_ignore_frames = 0; 324 sd->autogain_ignore_frames = 0;
325 atomic_set(&sd->avg_lum, -1); 325 atomic_set(&sd->avg_lum, -1);
326 return 0;
326} 327}
327 328
328static void sd_stopN(struct gspca_dev *gspca_dev) 329static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -534,6 +535,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
534 {USB_DEVICE(0x093a, 0x2470)}, 535 {USB_DEVICE(0x093a, 0x2470)},
535 {USB_DEVICE(0x093a, 0x2471)}, 536 {USB_DEVICE(0x093a, 0x2471)},
536 {USB_DEVICE(0x093a, 0x2472)}, 537 {USB_DEVICE(0x093a, 0x2472)},
538 {USB_DEVICE(0x093a, 0x2476)},
537 {USB_DEVICE(0x2001, 0xf115)}, 539 {USB_DEVICE(0x2001, 0xf115)},
538 {} 540 {}
539}; 541};
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index ba865b7f1ed8..e5ff9a6199ef 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -675,7 +675,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
675 return 0; 675 return 0;
676} 676}
677 677
678static void sd_start(struct gspca_dev *gspca_dev) 678static int sd_start(struct gspca_dev *gspca_dev)
679{ 679{
680 struct sd *sd = (struct sd *) gspca_dev; 680 struct sd *sd = (struct sd *) gspca_dev;
681 681
@@ -724,6 +724,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
724 reg_w(gspca_dev, 0x78, 0x01); 724 reg_w(gspca_dev, 0x78, 0x01);
725 else 725 else
726 reg_w(gspca_dev, 0x78, 0x05); 726 reg_w(gspca_dev, 0x78, 0x05);
727 return 0;
727} 728}
728 729
729static void sd_stopN(struct gspca_dev *gspca_dev) 730static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 12b81ae526b7..6c69bc7778fc 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -490,7 +490,7 @@ static const __u8 tas5130_sensor_init[][8] = {
490 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, 490 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
491}; 491};
492 492
493struct sensor_data sensor_data[] = { 493static struct sensor_data sensor_data[] = {
494SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), 494SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
495SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), 495SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
496SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, 496SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
@@ -892,7 +892,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
892} 892}
893 893
894/* -- start the camera -- */ 894/* -- start the camera -- */
895static void sd_start(struct gspca_dev *gspca_dev) 895static int sd_start(struct gspca_dev *gspca_dev)
896{ 896{
897 struct sd *sd = (struct sd *) gspca_dev; 897 struct sd *sd = (struct sd *) gspca_dev;
898 struct cam *cam = &gspca_dev->cam; 898 struct cam *cam = &gspca_dev->cam;
@@ -976,6 +976,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
976 sd->frames_to_drop = 0; 976 sd->frames_to_drop = 0;
977 sd->autogain_ignore_frames = 0; 977 sd->autogain_ignore_frames = 0;
978 atomic_set(&sd->avg_lum, -1); 978 atomic_set(&sd->avg_lum, -1);
979 return 0;
979} 980}
980 981
981static void sd_stopN(struct gspca_dev *gspca_dev) 982static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 572b0f363b64..53cb82d9e7c6 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -39,6 +39,7 @@ struct sd {
39 unsigned char contrast; 39 unsigned char contrast;
40 unsigned char colors; 40 unsigned char colors;
41 unsigned char autogain; 41 unsigned char autogain;
42 __u8 vflip; /* ov7630 only */
42 43
43 signed char ag_cnt; 44 signed char ag_cnt;
44#define AG_CNT_START 13 45#define AG_CNT_START 13
@@ -70,6 +71,8 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
70static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 71static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
71static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 72static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
72static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 73static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
73 76
74static struct ctrl sd_ctrls[] = { 77static struct ctrl sd_ctrls[] = {
75 { 78 {
@@ -131,6 +134,22 @@ static struct ctrl sd_ctrls[] = {
131 .set = sd_setautogain, 134 .set = sd_setautogain,
132 .get = sd_getautogain, 135 .get = sd_getautogain,
133 }, 136 },
137/* ov7630 only */
138#define VFLIP_IDX 4
139 {
140 {
141 .id = V4L2_CID_VFLIP,
142 .type = V4L2_CTRL_TYPE_BOOLEAN,
143 .name = "Vflip",
144 .minimum = 0,
145 .maximum = 1,
146 .step = 1,
147#define VFLIP_DEF 1
148 .default_value = VFLIP_DEF,
149 },
150 .set = sd_setvflip,
151 .get = sd_getvflip,
152 },
134}; 153};
135 154
136static struct v4l2_pix_format vga_mode[] = { 155static struct v4l2_pix_format vga_mode[] = {
@@ -248,10 +267,12 @@ static const __u8 gamma_def[] = {
248 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff 267 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
249}; 268};
250 269
270/* color matrix and offsets */
251static const __u8 reg84[] = { 271static const __u8 reg84[] = {
252 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, 272 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
253 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, 273 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
254 0xf7, 0x0f, 0x00, 0x00, 0x00 274 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
275 0x00, 0x00, 0x00 /* YUV offsets */
255}; 276};
256static const __u8 hv7131r_sensor_init[][8] = { 277static const __u8 hv7131r_sensor_init[][8] = {
257 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, 278 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
@@ -434,7 +455,8 @@ static const __u8 ov7630_sensor_init[][8] = {
434 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, 455 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
435 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, 456 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
436/*fixme: + 0x12, 0x04*/ 457/*fixme: + 0x12, 0x04*/
437 {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, 458/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
459 * set by setvflip */
438 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, 460 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, 461 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10}, 462 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
@@ -949,6 +971,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
949 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX); 971 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
950 break; 972 break;
951 } 973 }
974 if (sd->sensor != SENSOR_OV7630)
975 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
952 976
953 return 0; 977 return 0;
954} 978}
@@ -1080,20 +1104,17 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
1080static void setbrightcont(struct gspca_dev *gspca_dev) 1104static void setbrightcont(struct gspca_dev *gspca_dev)
1081{ 1105{
1082 struct sd *sd = (struct sd *) gspca_dev; 1106 struct sd *sd = (struct sd *) gspca_dev;
1083 unsigned val; 1107 int val;
1084 __u8 reg84_full[0x15]; 1108 __u8 reg84_full[0x15];
1085 1109
1086 memset(reg84_full, 0, sizeof reg84_full); 1110 memcpy(reg84_full, reg84, sizeof reg84_full);
1087 val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */ 1111 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1088 reg84_full[2] = val; 1112 reg84_full[0] = (val + 1) / 2; /* red */
1089 reg84_full[0] = (val + 1) / 2; 1113 reg84_full[2] = val; /* green */
1090 reg84_full[4] = (val + 1) / 5; 1114 reg84_full[4] = (val + 1) / 5; /* blue */
1091 if (val > BRIGHTNESS_DEF) 1115 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
1092 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1093 / BRIGHTNESS_MAX; 1116 / BRIGHTNESS_MAX;
1094 else 1117 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
1095 val = 0;
1096 reg84_full[0x12] = val; /* 00..1f */
1097 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full); 1118 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1098} 1119}
1099 1120
@@ -1172,8 +1193,16 @@ static void setautogain(struct gspca_dev *gspca_dev)
1172 sd->ag_cnt = -1; 1193 sd->ag_cnt = -1;
1173} 1194}
1174 1195
1196static void setvflip(struct sd *sd)
1197{
1198 if (sd->sensor != SENSOR_OV7630)
1199 return;
1200 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1201 sd->vflip ? 0x82 : 0x02);
1202}
1203
1175/* -- start the camera -- */ 1204/* -- start the camera -- */
1176static void sd_start(struct gspca_dev *gspca_dev) 1205static int sd_start(struct gspca_dev *gspca_dev)
1177{ 1206{
1178 struct sd *sd = (struct sd *) gspca_dev; 1207 struct sd *sd = (struct sd *) gspca_dev;
1179 int i; 1208 int i;
@@ -1263,6 +1292,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
1263 break; 1292 break;
1264 case SENSOR_OV7630: 1293 case SENSOR_OV7630:
1265 ov7630_InitSensor(gspca_dev); 1294 ov7630_InitSensor(gspca_dev);
1295 setvflip(sd);
1266 reg17 = 0xe2; 1296 reg17 = 0xe2;
1267 reg1 = 0x44; 1297 reg1 = 0x44;
1268 break; 1298 break;
@@ -1320,12 +1350,16 @@ static void sd_start(struct gspca_dev *gspca_dev)
1320 setbrightness(gspca_dev); 1350 setbrightness(gspca_dev);
1321 setcontrast(gspca_dev); 1351 setcontrast(gspca_dev);
1322 break; 1352 break;
1353 case SENSOR_OV7630:
1354 setvflip(sd);
1355 /* fall thru */
1323 default: /* OV76xx */ 1356 default: /* OV76xx */
1324 setbrightcont(gspca_dev); 1357 setbrightcont(gspca_dev);
1325 break; 1358 break;
1326 } 1359 }
1327 setautogain(gspca_dev); 1360 setautogain(gspca_dev);
1328 reg_w1(gspca_dev, 0x01, reg1); 1361 reg_w1(gspca_dev, 0x01, reg1);
1362 return 0;
1329} 1363}
1330 1364
1331static void sd_stopN(struct gspca_dev *gspca_dev) 1365static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -1546,6 +1580,24 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1546 return 0; 1580 return 0;
1547} 1581}
1548 1582
1583static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1584{
1585 struct sd *sd = (struct sd *) gspca_dev;
1586
1587 sd->vflip = val;
1588 if (gspca_dev->streaming)
1589 setvflip(sd);
1590 return 0;
1591}
1592
1593static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1594{
1595 struct sd *sd = (struct sd *) gspca_dev;
1596
1597 *val = sd->vflip;
1598 return 0;
1599}
1600
1549/* sub-driver description */ 1601/* sub-driver description */
1550static const struct sd_desc sd_desc = { 1602static const struct sd_desc sd_desc = {
1551 .name = MODULE_NAME, 1603 .name = MODULE_NAME,
@@ -1567,6 +1619,7 @@ static const struct sd_desc sd_desc = {
1567static const __devinitdata struct usb_device_id device_table[] = { 1619static const __devinitdata struct usb_device_id device_table[] = {
1568#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1620#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1569 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, 1621 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1622 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1570 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, 1623 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1571 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, 1624 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1572 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, 1625 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
@@ -1588,7 +1641,9 @@ static const __devinitdata struct usb_device_id device_table[] = {
1588/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */ 1641/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1589 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)}, 1642 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1590 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)}, 1643 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1591/* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */ 1644#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1645 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1646#endif
1592/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ 1647/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1593/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ 1648/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1594/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 1649/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 6e733901fcca..bca106c153fa 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -660,7 +660,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
660 return 0; 660 return 0;
661} 661}
662 662
663static void sd_start(struct gspca_dev *gspca_dev) 663static int sd_start(struct gspca_dev *gspca_dev)
664{ 664{
665 struct sd *sd = (struct sd *) gspca_dev; 665 struct sd *sd = (struct sd *) gspca_dev;
666 int err; 666 int err;
@@ -867,6 +867,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
867 write_vector(gspca_dev, Clicksmart510_defaults); 867 write_vector(gspca_dev, Clicksmart510_defaults);
868 break; 868 break;
869 } 869 }
870 return 0;
870} 871}
871 872
872static void sd_stopN(struct gspca_dev *gspca_dev) 873static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index e9eb59bae4fb..b742f260c7ca 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1980,7 +1980,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1980 return 0; 1980 return 0;
1981} 1981}
1982 1982
1983static void sd_start(struct gspca_dev *gspca_dev) 1983static int sd_start(struct gspca_dev *gspca_dev)
1984{ 1984{
1985 struct usb_device *dev = gspca_dev->dev; 1985 struct usb_device *dev = gspca_dev->dev;
1986 int mode; 1986 int mode;
@@ -2012,6 +2012,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
2012 setbrightness(gspca_dev); 2012 setbrightness(gspca_dev);
2013 setcontrast(gspca_dev); 2013 setcontrast(gspca_dev);
2014 setcolors(gspca_dev); 2014 setcolors(gspca_dev);
2015 return 0;
2015} 2016}
2016 2017
2017static void sd_stopN(struct gspca_dev *gspca_dev) 2018static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index f601daf19ebe..b345749213cf 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -688,7 +688,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
688 return 0; 688 return 0;
689} 689}
690 690
691static void sd_start(struct gspca_dev *gspca_dev) 691static int sd_start(struct gspca_dev *gspca_dev)
692{ 692{
693 struct usb_device *dev = gspca_dev->dev; 693 struct usb_device *dev = gspca_dev->dev;
694 int ret; 694 int ret;
@@ -733,6 +733,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
733/* reg_write(dev, 0x5, 0x0, 0x0); */ 733/* reg_write(dev, 0x5, 0x0, 0x0); */
734/* reg_write(dev, 0x5, 0x0, 0x1); */ 734/* reg_write(dev, 0x5, 0x0, 0x1); */
735/* reg_write(dev, 0x5, 0x11, 0x2); */ 735/* reg_write(dev, 0x5, 0x11, 0x2); */
736 return ret;
736} 737}
737 738
738static void sd_stopN(struct gspca_dev *gspca_dev) 739static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 195dce96ef06..645ee9d44d02 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -422,7 +422,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
422 return 0; 422 return 0;
423} 423}
424 424
425static void sd_start(struct gspca_dev *gspca_dev) 425static int sd_start(struct gspca_dev *gspca_dev)
426{ 426{
427 struct usb_device *dev = gspca_dev->dev; 427 struct usb_device *dev = gspca_dev->dev;
428 __u16 norme; 428 __u16 norme;
@@ -549,6 +549,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
549 PDEBUG(D_STREAM, "webcam started"); 549 PDEBUG(D_STREAM, "webcam started");
550 spca506_GetNormeInput(gspca_dev, &norme, &channel); 550 spca506_GetNormeInput(gspca_dev, &norme, &channel);
551 spca506_SetNormeInput(gspca_dev, norme, channel); 551 spca506_SetNormeInput(gspca_dev, norme, channel);
552 return 0;
552} 553}
553 554
554static void sd_stopN(struct gspca_dev *gspca_dev) 555static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 281ce02103a3..63ec902c895d 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1528,7 +1528,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1528 return 0; 1528 return 0;
1529} 1529}
1530 1530
1531static void sd_start(struct gspca_dev *gspca_dev) 1531static int sd_start(struct gspca_dev *gspca_dev)
1532{ 1532{
1533 int mode; 1533 int mode;
1534 1534
@@ -1546,6 +1546,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
1546 break; 1546 break;
1547 } 1547 }
1548 reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20); 1548 reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20);
1549 return 0;
1549} 1550}
1550 1551
1551static void sd_stopN(struct gspca_dev *gspca_dev) 1552static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 95fcfcb9e31b..020a03c466c1 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -152,7 +152,7 @@ static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
152 152
153 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 153 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
154 0, /* request */ 154 0, /* request */
155 USB_TYPE_VENDOR | USB_RECIP_DEVICE, 155 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
156 value, index, NULL, 0, 500); 156 value, index, NULL, 0, 500);
157 PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value); 157 PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
158 if (ret < 0) 158 if (ret < 0)
@@ -699,7 +699,7 @@ static void setautogain(struct gspca_dev *gspca_dev)
699 sd->ag_cnt = -1; 699 sd->ag_cnt = -1;
700} 700}
701 701
702static void sd_start_12a(struct gspca_dev *gspca_dev) 702static int sd_start_12a(struct gspca_dev *gspca_dev)
703{ 703{
704 struct usb_device *dev = gspca_dev->dev; 704 struct usb_device *dev = gspca_dev->dev;
705 int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */ 705 int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */
@@ -725,8 +725,9 @@ static void sd_start_12a(struct gspca_dev *gspca_dev)
725 setwhite(gspca_dev); 725 setwhite(gspca_dev);
726 setautogain(gspca_dev); 726 setautogain(gspca_dev);
727 setexposure(gspca_dev); 727 setexposure(gspca_dev);
728 return 0;
728} 729}
729static void sd_start_72a(struct gspca_dev *gspca_dev) 730static int sd_start_72a(struct gspca_dev *gspca_dev)
730{ 731{
731 struct usb_device *dev = gspca_dev->dev; 732 struct usb_device *dev = gspca_dev->dev;
732 int Clck; 733 int Clck;
@@ -750,6 +751,7 @@ static void sd_start_72a(struct gspca_dev *gspca_dev)
750 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ 751 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
751 reg_w_val(dev, 0x8112, 0x10 | 0x20); 752 reg_w_val(dev, 0x8112, 0x10 | 0x20);
752 setautogain(gspca_dev); 753 setautogain(gspca_dev);
754 return 0;
753} 755}
754 756
755static void sd_stopN(struct gspca_dev *gspca_dev) 757static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -1064,7 +1066,7 @@ static struct ctrl sd_ctrls_12a[] = {
1064 { 1066 {
1065 .id = V4L2_CID_DO_WHITE_BALANCE, 1067 .id = V4L2_CID_DO_WHITE_BALANCE,
1066 .type = V4L2_CTRL_TYPE_INTEGER, 1068 .type = V4L2_CTRL_TYPE_INTEGER,
1067 .name = "While Balance", 1069 .name = "White Balance",
1068 .minimum = WHITE_MIN, 1070 .minimum = WHITE_MIN,
1069 .maximum = WHITE_MAX, 1071 .maximum = WHITE_MAX,
1070 .step = 1, 1072 .step = 1,
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 2f2de429e273..d9d64911f22a 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -324,7 +324,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
324} 324}
325 325
326/* -- start the camera -- */ 326/* -- start the camera -- */
327static void sd_start(struct gspca_dev *gspca_dev) 327static int sd_start(struct gspca_dev *gspca_dev)
328{ 328{
329 int ret, value; 329 int ret, value;
330 330
@@ -374,9 +374,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
374 set_par(gspca_dev, 0x01000000); 374 set_par(gspca_dev, 0x01000000);
375 set_par(gspca_dev, 0x01000000); 375 set_par(gspca_dev, 0x01000000);
376 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); 376 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
377 return; 377 return 0;
378out: 378out:
379 PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret); 379 PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
380 return ret;
380} 381}
381 382
382static void sd_stopN(struct gspca_dev *gspca_dev) 383static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 1cfcc6c49558..bd9288665a80 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -961,7 +961,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
961 return 0; 961 return 0;
962} 962}
963 963
964static void sd_start(struct gspca_dev *gspca_dev) 964static int sd_start(struct gspca_dev *gspca_dev)
965{ 965{
966 struct sd *sd = (struct sd *) gspca_dev; 966 struct sd *sd = (struct sd *) gspca_dev;
967 struct usb_device *dev = gspca_dev->dev; 967 struct usb_device *dev = gspca_dev->dev;
@@ -1042,6 +1042,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
1042 break; 1042 break;
1043 } 1043 }
1044 sp5xx_initContBrigHueRegisters(gspca_dev); 1044 sp5xx_initContBrigHueRegisters(gspca_dev);
1045 return 0;
1045} 1046}
1046 1047
1047static void sd_stopN(struct gspca_dev *gspca_dev) 1048static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index f034c748fc7e..b561f7c4f066 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -28,8 +28,6 @@
28 28
29#include "gspca.h" 29#include "gspca.h"
30 30
31#define MAX_GAMMA 0x10 /* 0 to 15 */
32
33#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0) 31#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
34 32
35MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); 33MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
@@ -49,6 +47,10 @@ struct sd {
49 unsigned char whitebalance; 47 unsigned char whitebalance;
50 unsigned char mirror; 48 unsigned char mirror;
51 unsigned char effect; 49 unsigned char effect;
50
51 __u8 sensor;
52#define SENSOR_TAS5130A 0
53#define SENSOR_OTHER 1
52}; 54};
53 55
54/* V4L2 controls supported by the driver */ 56/* V4L2 controls supported by the driver */
@@ -83,9 +85,9 @@ static struct ctrl sd_ctrls[] = {
83 .type = V4L2_CTRL_TYPE_INTEGER, 85 .type = V4L2_CTRL_TYPE_INTEGER,
84 .name = "Brightness", 86 .name = "Brightness",
85 .minimum = 0, 87 .minimum = 0,
86 .maximum = 0x0f, 88 .maximum = 14,
87 .step = 1, 89 .step = 1,
88 .default_value = 0x09, 90 .default_value = 8,
89 }, 91 },
90 .set = sd_setbrightness, 92 .set = sd_setbrightness,
91 .get = sd_getbrightness, 93 .get = sd_getbrightness,
@@ -118,16 +120,17 @@ static struct ctrl sd_ctrls[] = {
118 .set = sd_setcolors, 120 .set = sd_setcolors,
119 .get = sd_getcolors, 121 .get = sd_getcolors,
120 }, 122 },
121#define SD_GAMMA 3 123#define GAMMA_MAX 16
124#define GAMMA_DEF 10
122 { 125 {
123 { 126 {
124 .id = V4L2_CID_GAMMA, /* (gamma on win) */ 127 .id = V4L2_CID_GAMMA, /* (gamma on win) */
125 .type = V4L2_CTRL_TYPE_INTEGER, 128 .type = V4L2_CTRL_TYPE_INTEGER,
126 .name = "Gamma (Untested)", 129 .name = "Gamma",
127 .minimum = 0, 130 .minimum = 0,
128 .maximum = MAX_GAMMA, 131 .maximum = GAMMA_MAX - 1,
129 .step = 1, 132 .step = 1,
130 .default_value = 0x09, 133 .default_value = GAMMA_DEF,
131 }, 134 },
132 .set = sd_setgamma, 135 .set = sd_setgamma,
133 .get = sd_getgamma, 136 .get = sd_getgamma,
@@ -197,7 +200,7 @@ static struct ctrl sd_ctrls[] = {
197 .type = V4L2_CTRL_TYPE_INTEGER, 200 .type = V4L2_CTRL_TYPE_INTEGER,
198 .name = "Sharpness", 201 .name = "Sharpness",
199 .minimum = 0, 202 .minimum = 0,
200 .maximum = MAX_GAMMA, /* 0 to 16 */ 203 .maximum = 15,
201 .step = 1, 204 .step = 1,
202 .default_value = 0x06, 205 .default_value = 0x06,
203 }, 206 },
@@ -258,7 +261,6 @@ static struct v4l2_pix_format vga_mode_t16[] = {
258 .priv = 0}, 261 .priv = 0},
259}; 262};
260 263
261#define T16_OFFSET_DATA 631
262#define MAX_EFFECTS 7 264#define MAX_EFFECTS 7
263/* easily done by soft, this table could be removed, 265/* easily done by soft, this table could be removed,
264 * i keep it here just in case */ 266 * i keep it here just in case */
@@ -272,87 +274,87 @@ static const __u8 effects_table[MAX_EFFECTS][6] = {
272 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ 274 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
273}; 275};
274 276
275static const __u8 gamma_table[MAX_GAMMA][34] = { 277static const __u8 gamma_table[GAMMA_MAX][34] = {
276 {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, 278 {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */
277 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9, 279 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
278 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb, 280 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
279 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8, 281 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
280 0xa0, 0xff}, 282 0xa0, 0xff},
281 {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75, 283 {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */
282 0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD, 284 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
283 0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4, 285 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
284 0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7, 286 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
285 0xa0, 0xff}, 287 0xa0, 0xff},
286 {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B, 288 {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */
287 0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6, 289 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
288 0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0, 290 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
289 0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6, 291 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
290 0xa0, 0xff}, 292 0xa0, 0xff},
291 {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, 293 {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */
292 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E, 294 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
293 0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB, 295 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
294 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, 296 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
295 0xa0, 0xff}, 297 0xa0, 0xff},
296 {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55, 298 {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */
297 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95, 299 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
298 0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6, 300 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
299 0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4, 301 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
300 0xa0, 0xff}, 302 0xa0, 0xff},
301 {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48, 303 {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */
302 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87, 304 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
303 0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE, 305 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
304 0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3, 306 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
305 0xa0, 0xff}, 307 0xa0, 0xff},
306 {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, 308 {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */
307 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67, 309 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
308 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa, 310 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
309 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee, 311 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
310 0xa0, 0xff}, 312 0xa0, 0xff},
311 {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, 313 {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */
312 0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70, 314 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
313 0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0, 315 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
314 0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0, 316 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
315 0xa0, 0xff}, 317 0xa0, 0xff},
316 {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, 318 {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */
317 0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79, 319 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
318 0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6, 320 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
319 0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0, 321 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
320 0xa0, 0xff}, 322 0xa0, 0xff},
321 {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, 323 {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */
322 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, 324 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
323 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 325 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
324 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0, 326 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
325 0xa0, 0xff}, 327 0xa0, 0xff},
326 {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44, 328 {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */
327 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E, 329 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
328 0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4, 330 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
329 0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0, 331 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
330 0xa0, 0xff}, 332 0xa0, 0xff},
331 {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52, 333 {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */
332 0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B, 334 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
333 0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB, 335 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
334 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, 336 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
335 0xa0, 0xff}, 337 0xa0, 0xff},
336 {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E, 338 {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */
337 0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8, 339 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
338 0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3, 340 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
339 0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6, 341 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
340 0xA0, 0xFF},
341 {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83,
342 0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7,
343 0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC,
344 0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9,
345 0xa0, 0xff}, 342 0xa0, 0xff},
346 {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A, 343 {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */
347 0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6, 344 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
348 0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3, 345 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
349 0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA, 346 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
350 0xa0, 0xff}, 347 0xa0, 0xff},
351 {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7, 348 {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */
352 0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8, 349 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
353 0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED, 350 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
354 0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC, 351 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
355 0xA0, 0xFF} 352 0xa0, 0xff},
353 {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */
354 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
355 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
356 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
357 0xa0, 0xff}
356}; 358};
357 359
358static const __u8 tas5130a_sensor_init[][8] = { 360static const __u8 tas5130a_sensor_init[][8] = {
@@ -364,7 +366,7 @@ static const __u8 tas5130a_sensor_init[][8] = {
364}; 366};
365 367
366/* read 1 byte */ 368/* read 1 byte */
367static int reg_r_1(struct gspca_dev *gspca_dev, 369static int reg_r(struct gspca_dev *gspca_dev,
368 __u16 index) 370 __u16 index)
369{ 371{
370 usb_control_msg(gspca_dev->dev, 372 usb_control_msg(gspca_dev->dev,
@@ -378,26 +380,26 @@ static int reg_r_1(struct gspca_dev *gspca_dev,
378} 380}
379 381
380static void reg_w(struct gspca_dev *gspca_dev, 382static void reg_w(struct gspca_dev *gspca_dev,
381 __u16 value, 383 __u16 index)
382 __u16 index, 384{
383 const __u8 *buffer, __u16 len) 385 usb_control_msg(gspca_dev->dev,
386 usb_sndctrlpipe(gspca_dev->dev, 0),
387 0,
388 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
389 0, index,
390 NULL, 0, 500);
391}
392
393static void i2c_w(struct gspca_dev *gspca_dev,
394 const __u8 *buffer, __u16 len)
384{ 395{
385 if (buffer == NULL) {
386 usb_control_msg(gspca_dev->dev,
387 usb_sndctrlpipe(gspca_dev->dev, 0),
388 0,
389 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
390 value, index,
391 NULL, 0, 500);
392 return;
393 }
394 if (len <= USB_BUF_SZ) { 396 if (len <= USB_BUF_SZ) {
395 memcpy(gspca_dev->usb_buf, buffer, len); 397 memcpy(gspca_dev->usb_buf, buffer, len);
396 usb_control_msg(gspca_dev->dev, 398 usb_control_msg(gspca_dev->dev,
397 usb_sndctrlpipe(gspca_dev->dev, 0), 399 usb_sndctrlpipe(gspca_dev->dev, 0),
398 0, 400 0,
399 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 401 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
400 value, index, 402 0x01, 0,
401 gspca_dev->usb_buf, len, 500); 403 gspca_dev->usb_buf, len, 500);
402 } else { 404 } else {
403 __u8 *tmpbuf; 405 __u8 *tmpbuf;
@@ -408,12 +410,56 @@ static void reg_w(struct gspca_dev *gspca_dev,
408 usb_sndctrlpipe(gspca_dev->dev, 0), 410 usb_sndctrlpipe(gspca_dev->dev, 0),
409 0, 411 0,
410 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 412 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
411 value, index, 413 0x01, 0,
412 tmpbuf, len, 500); 414 tmpbuf, len, 500);
413 kfree(tmpbuf); 415 kfree(tmpbuf);
414 } 416 }
415} 417}
416 418
419static void other_sensor_init(struct gspca_dev *gspca_dev)
420{
421 int i;
422 const __u8 *p;
423 __u8 byte;
424 __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
425 static const __u8 sensor_init[] = {
426 0xdf, 0x6d,
427 0xdd, 0x18,
428 0x5a, 0xe0,
429 0x5c, 0x07,
430 0x5d, 0xb0,
431 0x5e, 0x1e,
432 0x60, 0x71,
433 0xef, 0x00,
434 0xe9, 0x00,
435 0xea, 0x00,
436 0x90, 0x24,
437 0x91, 0xb2,
438 0x82, 0x32,
439 0xfd, 0x00,
440 0xfd, 0x01,
441 0xfd, 0x41,
442 0x00 /* table end */
443 };
444
445 p = sensor_init;
446 while (*p != 0) {
447 val[1] = *p++;
448 val[3] = *p++;
449 if (*p == 0)
450 reg_w(gspca_dev, 0x3c80);
451 i2c_w(gspca_dev, val, sizeof val);
452 i = 4;
453 while (--i >= 0) {
454 msleep(15);
455 byte = reg_r(gspca_dev, 0x60);
456 if (!(byte & 0x01))
457 break;
458 }
459 }
460 reg_w(gspca_dev, 0x3c80);
461}
462
417/* this function is called at probe time */ 463/* this function is called at probe time */
418static int sd_config(struct gspca_dev *gspca_dev, 464static int sd_config(struct gspca_dev *gspca_dev,
419 const struct usb_device_id *id) 465 const struct usb_device_id *id)
@@ -430,7 +476,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
430 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 476 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
431 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 477 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
432 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; 478 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
433 sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value; 479 sd->gamma = GAMMA_DEF;
434 sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value; 480 sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
435 sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value; 481 sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
436 sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value; 482 sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
@@ -439,27 +485,37 @@ static int sd_config(struct gspca_dev *gspca_dev,
439 return 0; 485 return 0;
440} 486}
441 487
442static int init_default_parameters(struct gspca_dev *gspca_dev) 488static void setgamma(struct gspca_dev *gspca_dev)
489{
490 struct sd *sd = (struct sd *) gspca_dev;
491
492 PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
493 i2c_w(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
494}
495
496/* this function is called at probe and resume time */
497static int sd_init(struct gspca_dev *gspca_dev)
443{ 498{
444 /* some of this registers are not really neded, because 499 /* some of this registers are not really neded, because
445 * they are overriden by setbrigthness, setcontrast, etc, 500 * they are overriden by setbrigthness, setcontrast, etc,
446 * but wont hurt anyway, and can help someone with similar webcam 501 * but wont hurt anyway, and can help someone with similar webcam
447 * to see the initial parameters.*/ 502 * to see the initial parameters.*/
448 int i = 0; 503 struct sd *sd = (struct sd *) gspca_dev;
449 __u8 test_byte; 504 int i;
505 __u8 byte, test_byte;
450 506
451 static const __u8 read_indexs[] = 507 static const __u8 read_indexs[] =
452 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, 508 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
453 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 }; 509 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
454 static const __u8 n1[6] = 510 static const __u8 n1[] =
455 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; 511 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
456 static const __u8 n2[2] = 512 static const __u8 n2[] =
457 {0x08, 0x00}; 513 {0x08, 0x00};
458 static const __u8 nset[6] = 514 static const __u8 nset[] =
459 { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 }; 515 { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
460 static const __u8 n3[6] = 516 static const __u8 n3[] =
461 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; 517 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
462 static const __u8 n4[0x46] = 518 static const __u8 n4[] =
463 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, 519 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
464 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, 520 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
465 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, 521 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
@@ -469,33 +525,26 @@ static int init_default_parameters(struct gspca_dev *gspca_dev)
469 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, 525 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
470 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, 526 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
471 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; 527 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
472 static const __u8 nset4[18] = { 528 static const __u8 nset4[] = {
473 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8, 529 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
474 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, 530 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
475 0xe8, 0xe0 531 0xe8, 0xe0
476 }; 532 };
477 /* ojo puede ser 0xe6 en vez de 0xe9 */ 533 /* ojo puede ser 0xe6 en vez de 0xe9 */
478 static const __u8 nset2[20] = { 534 static const __u8 nset2[] = {
479 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb, 535 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
480 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, 536 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
481 0xd8, 0xc8, 0xd9, 0xfc 537 0xd8, 0xc8, 0xd9, 0xfc
482 }; 538 };
483 static const __u8 missing[8] = 539 static const __u8 missing[] =
484 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; 540 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
485 static const __u8 nset3[18] = { 541 static const __u8 nset3[] = {
486 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8, 542 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
487 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, 543 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
488 0xcf, 0xe0 544 0xcf, 0xe0
489 }; 545 };
490 static const __u8 nset5[4] = 546 static const __u8 nset5[] =
491 { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */ 547 { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */
492 static const __u8 nset6[34] = {
493 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54,
494 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
495 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca,
496 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2,
497 0xa0, 0xff
498 }; /* Gamma */
499 static const __u8 nset7[4] = 548 static const __u8 nset7[4] =
500 { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */ 549 { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */
501 static const __u8 nset9[4] = 550 static const __u8 nset9[4] =
@@ -505,95 +554,111 @@ static int init_default_parameters(struct gspca_dev *gspca_dev)
505 static const __u8 nset10[6] = 554 static const __u8 nset10[6] =
506 { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; 555 { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
507 556
508 reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06); 557 byte = reg_r(gspca_dev, 0x06);
509 reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06); 558 test_byte = reg_r(gspca_dev, 0x07);
510 reg_r_1(gspca_dev, 0x0063); 559 if (byte == 0x08 && test_byte == 0x07) {
511 reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02); 560 PDEBUG(D_CONF, "other sensor");
561 sd->sensor = SENSOR_OTHER;
562 } else {
563 PDEBUG(D_CONF, "sensor %02x %02x", byte, test_byte);
564 sd->sensor = SENSOR_TAS5130A;
565 }
566
567 i2c_w(gspca_dev, n1, sizeof n1);
568 test_byte = 0;
569 i = 5;
570 while (--i >= 0) {
571 i2c_w(gspca_dev, nset, sizeof nset);
572 msleep(5);
573 test_byte = reg_r(gspca_dev, 0x0063);
574 msleep(100);
575 if (test_byte == 0x17)
576 break; /* OK */
577 }
578 if (i < 0) {
579 err("Bad sensor reset %02x", test_byte);
580/* return -EIO; */
581/*fixme: test - continue */
582 }
583 i2c_w(gspca_dev, n2, sizeof n2);
512 584
585 i = 0;
513 while (read_indexs[i] != 0x00) { 586 while (read_indexs[i] != 0x00) {
514 test_byte = reg_r_1(gspca_dev, read_indexs[i]); 587 test_byte = reg_r(gspca_dev, read_indexs[i]);
515 PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i], 588 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
516 test_byte); 589 test_byte);
517 i++; 590 i++;
518 } 591 }
519 592
520 reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06); 593 i2c_w(gspca_dev, n3, sizeof n3);
521 reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46); 594 i2c_w(gspca_dev, n4, sizeof n4);
522 reg_r_1(gspca_dev, 0x0080); 595 reg_r(gspca_dev, 0x0080);
523 reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0); 596 reg_w(gspca_dev, 0x2c80);
524 reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14); 597 i2c_w(gspca_dev, nset2, sizeof nset2);
525 reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12); 598 i2c_w(gspca_dev, nset3, sizeof nset3);
526 reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12); 599 i2c_w(gspca_dev, nset4, sizeof nset4);
527 reg_w(gspca_dev, 0x00, 0x3880, NULL, 0); 600 reg_w(gspca_dev, 0x3880);
528 reg_w(gspca_dev, 0x00, 0x3880, NULL, 0); 601 reg_w(gspca_dev, 0x3880);
529 reg_w(gspca_dev, 0x00, 0x338e, NULL, 0); 602 reg_w(gspca_dev, 0x338e);
530 reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04); 603 i2c_w(gspca_dev, nset5, sizeof nset5);
531 reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0); 604 reg_w(gspca_dev, 0x00a9);
532 reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22); 605 setgamma(gspca_dev);
533 reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0); 606 reg_w(gspca_dev, 0x86bb);
534 reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0); 607 reg_w(gspca_dev, 0x4aa6);
535 608
536 reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08); 609 i2c_w(gspca_dev, missing, sizeof missing);
537 610
538 reg_w(gspca_dev, 0x00, 0x2087, NULL, 0); 611 reg_w(gspca_dev, 0x2087);
539 reg_w(gspca_dev, 0x00, 0x2088, NULL, 0); 612 reg_w(gspca_dev, 0x2088);
540 reg_w(gspca_dev, 0x00, 0x2089, NULL, 0); 613 reg_w(gspca_dev, 0x2089);
541 614
542 reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04); 615 i2c_w(gspca_dev, nset7, sizeof nset7);
543 reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06); 616 i2c_w(gspca_dev, nset10, sizeof nset10);
544 reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06); 617 i2c_w(gspca_dev, nset8, sizeof nset8);
545 reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04); 618 i2c_w(gspca_dev, nset9, sizeof nset9);
546 619
547 reg_w(gspca_dev, 0x00, 0x2880, NULL, 0); 620 reg_w(gspca_dev, 0x2880);
548 reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14); 621 i2c_w(gspca_dev, nset2, sizeof nset2);
549 reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12); 622 i2c_w(gspca_dev, nset3, sizeof nset3);
550 reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12); 623 i2c_w(gspca_dev, nset4, sizeof nset4);
551 624
552 return 0; 625 return 0;
553} 626}
554 627
555/* this function is called at probe and resume time */
556static int sd_init(struct gspca_dev *gspca_dev)
557{
558 init_default_parameters(gspca_dev);
559 return 0;
560}
561
562static void setbrightness(struct gspca_dev *gspca_dev) 628static void setbrightness(struct gspca_dev *gspca_dev)
563{ 629{
564 struct sd *sd = (struct sd *) gspca_dev; 630 struct sd *sd = (struct sd *) gspca_dev;
565 unsigned int brightness; 631 unsigned int brightness;
566 __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 }; 632 __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x00 };
567 brightness = sd->brightness;
568 633
634 brightness = sd->brightness;
569 if (brightness < 7) { 635 if (brightness < 7) {
570 set6[3] = 0x70 - (brightness * 0xa); 636 set6[3] = 0x70 - brightness * 0x10;
571 } else { 637 } else {
572 set6[1] = 0x24; 638 set6[1] = 0x24;
573 set6[3] = 0x00 + ((brightness - 7) * 0xa); 639 set6[3] = 0x00 + ((brightness - 7) * 0x10);
574 } 640 }
575 641
576 reg_w(gspca_dev, 0x01, 0x0000, set6, 4); 642 i2c_w(gspca_dev, set6, sizeof set6);
577} 643}
578 644
579static void setflip(struct gspca_dev *gspca_dev) 645static void setflip(struct gspca_dev *gspca_dev)
580{ 646{
581 struct sd *sd = (struct sd *) gspca_dev; 647 struct sd *sd = (struct sd *) gspca_dev;
582
583 __u8 flipcmd[8] = 648 __u8 flipcmd[8] =
584 { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 }; 649 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
585 650
586 if (sd->mirror == 1) 651 if (sd->mirror)
587 flipcmd[3] = 0x01; 652 flipcmd[3] = 0x01;
588 653
589 reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8); 654 i2c_w(gspca_dev, flipcmd, sizeof flipcmd);
590} 655}
591 656
592static void seteffect(struct gspca_dev *gspca_dev) 657static void seteffect(struct gspca_dev *gspca_dev)
593{ 658{
594 struct sd *sd = (struct sd *) gspca_dev; 659 struct sd *sd = (struct sd *) gspca_dev;
595 660
596 reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06); 661 i2c_w(gspca_dev, effects_table[sd->effect], sizeof effects_table[0]);
597 if (sd->effect == 1 || sd->effect == 5) { 662 if (sd->effect == 1 || sd->effect == 5) {
598 PDEBUG(D_CONF, 663 PDEBUG(D_CONF,
599 "This effect have been disabled for webcam \"safety\""); 664 "This effect have been disabled for webcam \"safety\"");
@@ -601,9 +666,9 @@ static void seteffect(struct gspca_dev *gspca_dev)
601 } 666 }
602 667
603 if (sd->effect == 1 || sd->effect == 4) 668 if (sd->effect == 1 || sd->effect == 4)
604 reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0); 669 reg_w(gspca_dev, 0x4aa6);
605 else 670 else
606 reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0); 671 reg_w(gspca_dev, 0xfaa6);
607} 672}
608 673
609static void setwhitebalance(struct gspca_dev *gspca_dev) 674static void setwhitebalance(struct gspca_dev *gspca_dev)
@@ -616,7 +681,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev)
616 if (sd->whitebalance == 1) 681 if (sd->whitebalance == 1)
617 white_balance[7] = 0x3c; 682 white_balance[7] = 0x3c;
618 683
619 reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8); 684 i2c_w(gspca_dev, white_balance, sizeof white_balance);
620} 685}
621 686
622static void setlightfreq(struct gspca_dev *gspca_dev) 687static void setlightfreq(struct gspca_dev *gspca_dev)
@@ -627,21 +692,21 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
627 if (sd->freq == 2) /* 60hz */ 692 if (sd->freq == 2) /* 60hz */
628 freq[1] = 0x00; 693 freq[1] = 0x00;
629 694
630 reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4); 695 i2c_w(gspca_dev, freq, sizeof freq);
631} 696}
632 697
633static void setcontrast(struct gspca_dev *gspca_dev) 698static void setcontrast(struct gspca_dev *gspca_dev)
634{ 699{
635 struct sd *sd = (struct sd *) gspca_dev; 700 struct sd *sd = (struct sd *) gspca_dev;
636 unsigned int contrast = sd->contrast; 701 unsigned int contrast = sd->contrast;
637 __u16 reg_to_write = 0x00; 702 __u16 reg_to_write;
638 703
639 if (contrast < 7) 704 if (contrast < 7)
640 reg_to_write = 0x8ea9 - (0x200 * contrast); 705 reg_to_write = 0x8ea9 - (0x200 * contrast);
641 else 706 else
642 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); 707 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
643 708
644 reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); 709 reg_w(gspca_dev, reg_to_write);
645} 710}
646 711
647static void setcolors(struct gspca_dev *gspca_dev) 712static void setcolors(struct gspca_dev *gspca_dev)
@@ -650,11 +715,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
650 __u16 reg_to_write; 715 __u16 reg_to_write;
651 716
652 reg_to_write = 0xc0bb + sd->colors * 0x100; 717 reg_to_write = 0xc0bb + sd->colors * 0x100;
653 reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); 718 reg_w(gspca_dev, reg_to_write);
654}
655
656static void setgamma(struct gspca_dev *gspca_dev)
657{
658} 719}
659 720
660static void setsharpness(struct gspca_dev *gspca_dev) 721static void setsharpness(struct gspca_dev *gspca_dev)
@@ -664,7 +725,99 @@ static void setsharpness(struct gspca_dev *gspca_dev)
664 725
665 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; 726 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
666 727
667 reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); 728 reg_w(gspca_dev, reg_to_write);
729}
730
731static int sd_start(struct gspca_dev *gspca_dev)
732{
733 struct sd *sd = (struct sd *) gspca_dev;
734 int i, mode;
735 static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
736 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
737 static const __u8 t3[] =
738 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
739 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
740 static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
741
742 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
743 switch (mode) {
744 case 1: /* 352x288 */
745 t2[1] = 0x40;
746 break;
747 case 2: /* 320x240 */
748 t2[1] = 0x10;
749 break;
750 case 3: /* 176x144 */
751 t2[1] = 0x50;
752 break;
753 case 4: /* 160x120 */
754 t2[1] = 0x20;
755 break;
756 default: /* 640x480 (0x00) */
757 break;
758 }
759
760 if (sd->sensor == SENSOR_TAS5130A) {
761 i = 0;
762 while (tas5130a_sensor_init[i][0] != 0) {
763 i2c_w(gspca_dev, tas5130a_sensor_init[i],
764 sizeof tas5130a_sensor_init[0]);
765 i++;
766 }
767 reg_w(gspca_dev, 0x3c80);
768 /* just in case and to keep sync with logs (for mine) */
769 i2c_w(gspca_dev, tas5130a_sensor_init[3],
770 sizeof tas5130a_sensor_init[0]);
771 reg_w(gspca_dev, 0x3c80);
772 } else {
773 other_sensor_init(gspca_dev);
774 }
775 /* just in case and to keep sync with logs (for mine) */
776 i2c_w(gspca_dev, t1, sizeof t1);
777 i2c_w(gspca_dev, t2, sizeof t2);
778 reg_r(gspca_dev, 0x0012);
779 i2c_w(gspca_dev, t3, sizeof t3);
780 reg_w(gspca_dev, 0x0013);
781 i2c_w(gspca_dev, t4, sizeof t4);
782 /* restart on each start, just in case, sometimes regs goes wrong
783 * when using controls from app */
784 setbrightness(gspca_dev);
785 setcontrast(gspca_dev);
786 setcolors(gspca_dev);
787 return 0;
788}
789
790static void sd_pkt_scan(struct gspca_dev *gspca_dev,
791 struct gspca_frame *frame, /* target */
792 __u8 *data, /* isoc packet */
793 int len) /* iso packet length */
794{
795 static __u8 ffd9[] = { 0xff, 0xd9 };
796
797 if (data[0] == 0x5a) {
798 /* Control Packet, after this came the header again,
799 * but extra bytes came in the packet before this,
800 * sometimes an EOF arrives, sometimes not... */
801 return;
802 }
803 data += 2;
804 len -= 2;
805 if (data[0] == 0xff && data[1] == 0xd8) {
806 /* extra bytes....., could be processed too but would be
807 * a waste of time, right now leave the application and
808 * libjpeg do it for ourserlves.. */
809 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
810 ffd9, 2);
811 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
812 return;
813 }
814
815 if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
816 /* Just in case, i have seen packets with the marker,
817 * other's do not include it... */
818 len -= 2;
819 }
820 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
668} 821}
669 822
670static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 823static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -788,6 +941,7 @@ static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
788static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) 941static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
789{ 942{
790 struct sd *sd = (struct sd *) gspca_dev; 943 struct sd *sd = (struct sd *) gspca_dev;
944
791 *val = sd->gamma; 945 *val = sd->gamma;
792 return 0; 946 return 0;
793} 947}
@@ -835,9 +989,9 @@ static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
835 989
836 sd->autogain = val; 990 sd->autogain = val;
837 if (val != 0) 991 if (val != 0)
838 reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0); 992 reg_w(gspca_dev, 0xf48e);
839 else 993 else
840 reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0); 994 reg_w(gspca_dev, 0xb48e);
841 return 0; 995 return 0;
842} 996}
843 997
@@ -849,99 +1003,6 @@ static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
849 return 0; 1003 return 0;
850} 1004}
851 1005
852static void sd_start(struct gspca_dev *gspca_dev)
853{
854 int mode;
855
856 static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
857 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
858 static const __u8 t3[] =
859 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
860 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
861 static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
862
863 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
864 switch (mode) {
865 case 1: /* 352x288 */
866 t2[1] = 0x40;
867 break;
868 case 2: /* 320x240 */
869 t2[1] = 0x10;
870 break;
871 case 3: /* 176x144 */
872 t2[1] = 0x50;
873 break;
874 case 4: /* 160x120 */
875 t2[1] = 0x20;
876 break;
877 default: /* 640x480 (0x00) */
878 break;
879 }
880
881 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
882 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
883 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
884 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
885 reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
886 /* just in case and to keep sync with logs (for mine) */
887 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
888 reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
889 /* just in case and to keep sync with logs (for mine) */
890 reg_w(gspca_dev, 0x01, 0x0000, t1, 4);
891 reg_w(gspca_dev, 0x01, 0x0000, t2, 6);
892 reg_r_1(gspca_dev, 0x0012);
893 reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10);
894 reg_w(gspca_dev, 0x00, 0x0013, NULL, 0);
895 reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4);
896 /* restart on each start, just in case, sometimes regs goes wrong
897 * when using controls from app */
898 setbrightness(gspca_dev);
899 setcontrast(gspca_dev);
900 setcolors(gspca_dev);
901}
902
903static void sd_pkt_scan(struct gspca_dev *gspca_dev,
904 struct gspca_frame *frame, /* target */
905 __u8 *data, /* isoc packet */
906 int len) /* iso packet length */
907{
908 int sof = 0;
909 static __u8 ffd9[] = { 0xff, 0xd9 };
910
911 if (data[0] == 0x5a) {
912 /* Control Packet, after this came the header again,
913 * but extra bytes came in the packet before this,
914 * sometimes an EOF arrives, sometimes not... */
915 return;
916 }
917
918 if (data[len - 1] == 0xff && data[len] == 0xd9) {
919 /* Just in case, i have seen packets with the marker,
920 * other's do not include it... */
921 data += 2;
922 len -= 4;
923 } else if (data[2] == 0xff && data[3] == 0xd8) {
924 sof = 1;
925 data += 2;
926 len -= 2;
927 } else {
928 data += 2;
929 len -= 2;
930 }
931
932 if (sof) {
933 /* extra bytes....., could be processed too but would be
934 * a waste of time, right now leave the application and
935 * libjpeg do it for ourserlves.. */
936 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
937 ffd9, 2);
938 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
939 return;
940 }
941
942 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
943}
944
945static int sd_querymenu(struct gspca_dev *gspca_dev, 1006static int sd_querymenu(struct gspca_dev *gspca_dev,
946 struct v4l2_querymenu *menu) 1007 struct v4l2_querymenu *menu)
947{ 1008{
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 084af05302a0..968a5911704f 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -390,7 +390,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
390} 390}
391 391
392/* -- start the camera -- */ 392/* -- start the camera -- */
393static void sd_start(struct gspca_dev *gspca_dev) 393static int sd_start(struct gspca_dev *gspca_dev)
394{ 394{
395 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); 395 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
396 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); 396 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
@@ -443,6 +443,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
443 /************************************************/ 443 /************************************************/
444 tv_8532_PollReg(gspca_dev); 444 tv_8532_PollReg(gspca_dev);
445 reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ 445 reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
446 return 0;
446} 447}
447 448
448static void sd_stopN(struct gspca_dev *gspca_dev) 449static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index bd4c226c9a07..be46d9232540 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -80,7 +80,6 @@ static struct ctrl sd_ctrls[] = {
80 .step = 1, 80 .step = 1,
81#define FREQ_DEF 1 81#define FREQ_DEF 1
82 .default_value = FREQ_DEF, 82 .default_value = FREQ_DEF,
83 .default_value = 1,
84 }, 83 },
85 .set = sd_setfreq, 84 .set = sd_setfreq,
86 .get = sd_getfreq, 85 .get = sd_getfreq,
@@ -1502,7 +1501,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
1502 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); 1501 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]);
1503} 1502}
1504 1503
1505static void sd_start(struct gspca_dev *gspca_dev) 1504static int sd_start(struct gspca_dev *gspca_dev)
1506{ 1505{
1507 struct sd *sd = (struct sd *) gspca_dev; 1506 struct sd *sd = (struct sd *) gspca_dev;
1508 const __u8 *GammaT = NULL; 1507 const __u8 *GammaT = NULL;
@@ -1586,7 +1585,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
1586 break; 1585 break;
1587 default: 1586 default:
1588 PDEBUG(D_PROBE, "Damned !! no sensor found Bye"); 1587 PDEBUG(D_PROBE, "Damned !! no sensor found Bye");
1589 return; 1588 return -EMEDIUMTYPE;
1590 } 1589 }
1591 if (GammaT && MatrixT) { 1590 if (GammaT && MatrixT) {
1592 put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a); 1591 put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a);
@@ -1622,6 +1621,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
1622 setautogain(gspca_dev); 1621 setautogain(gspca_dev);
1623 setlightfreq(gspca_dev); 1622 setlightfreq(gspca_dev);
1624 } 1623 }
1624 return 0;
1625} 1625}
1626 1626
1627static void sd_stopN(struct gspca_dev *gspca_dev) 1627static void sd_stopN(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index d61ef727e0c2..d0a4451dc46f 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -7178,7 +7178,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
7178 return 0; 7178 return 0;
7179} 7179}
7180 7180
7181static void sd_start(struct gspca_dev *gspca_dev) 7181static int sd_start(struct gspca_dev *gspca_dev)
7182{ 7182{
7183 struct sd *sd = (struct sd *) gspca_dev; 7183 struct sd *sd = (struct sd *) gspca_dev;
7184 struct usb_device *dev = gspca_dev->dev; 7184 struct usb_device *dev = gspca_dev->dev;
@@ -7331,6 +7331,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
7331 reg_w(dev, 0x02, 0x0008); 7331 reg_w(dev, 0x02, 0x0008);
7332 break; 7332 break;
7333 } 7333 }
7334 return 0;
7334} 7335}
7335 7336
7336static void sd_stop0(struct gspca_dev *gspca_dev) 7337static void sd_stop0(struct gspca_dev *gspca_dev)