5 * @brief Common control functions for Omnivision Image Sensors.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "omnivision.h"
28 static __u8 ov7660_init
[][2] = {
29 /* System CLK selection, to get a higher Frame Rate */
30 {OV7660_CTL_COM5
, 0x80},
32 /* COM4 is Reserved : using default value 0x40 OR windows driver value 0x08 */
33 {OV7660_CTL_COM4
, 0x08},
34 /* Enable HREF at optical black, Use optical black line as BLC signal
35 Reset all timing when format changes, Enable ADBLC option */
36 {OV7660_CTL_COM6
, 0xc3},
37 /* windows 0x00, default 0x00, trying 0x60 to enable CCIR656 format */
38 {OV7660_CTL_COM1
, 0xc3},
39 /* default is 0x40, windows sets it to 0x00 */
40 {OV7660_CTL_AECH
, 0x40},
41 /* default is 0x00, windows sets it to 0x40 */
42 {OV7660_CTL_CLKRC
, 0x40},
43 /* Set O/P format - RGB Selection, Set O/P format Raw RGB */
44 {OV7660_CTL_COM7
, 0x05},
45 /* default is 0x8f, windows used 0xf8 */
46 /* Enable fast AGC/AEC algorithm, AEC - Step size limit = 1/16 x AEC */
47 /* Banding & Reserved are disabled. AGC, AEC enabled, 0x85 */
48 {OV7660_CTL_COM8
, 0xb8},
49 /* video appears jagged w/o these ADC writes */
50 {OV7660_CTL_ADC
, 0x0f},
51 {OV7660_CTL_ACOM
, 0x02},
52 {OV7660_CTL_OFON
, 0x43},
53 /* video appears jagged w/o this write */
54 /* Default 0x0c sets format to uYvY, Windows driver 0x00 sets format to YuYv */
55 {OV7660_CTL_TSLB
, 0x00},
56 /* Not doing this write makes the video look green */
57 /* Manual Banding Filter MSB , set B & R channel pre-gain */
58 {OV7660_CTL_HV
, 0x90},
59 /* No video stream w/o these ADVFL/ADVFH write totally black */
60 {OV7660_CTL_ADVFL
, 0xf6},
61 {OV7660_CTL_ADVFH
, 0x0b},
62 /* Setting BLUE to 0x78; RED to 0x78 to get natural colors in artificial light */
63 {OV7660_CTL_BLUE
, 0x78},
64 /* Setting RED to 0x50 to get natural colors in natural light */
65 {OV7660_CTL_RED
, 0x50},
68 static __u8 ov7670_init
[][2] = {
70 {OV7670_CTL_COM7
, 0x80},
71 {OV7670_CTL_CLKRC
, 0x80},
72 {OV7670_CTL_TSLB
, 0x04},
73 {OV7670_CTL_COM7
, 0x00},
74 {OV7670_CTL_HREF
, 0xb6},
75 {OV7670_CTL_VREF
, 0x0a},
76 {OV7670_CTL_COM3
, 0x00},
77 {OV7670_CTL_COM14
, 0x00},
78 {OV7670_CTL_SCALING_XSC
, 0x3a},
79 {OV7670_CTL_SCALING_YSC
, 0x35},
80 {OV7670_CTL_SCALING_DCWCTR
, 0x11},
81 {OV7670_CTL_SCALING_PCLK_DIV
, 0xf0},
82 {OV7670_CTL_SCALING_PCLK_DELAY
, 0x02},
83 {OV7670_CTL_COM8
, 0xe0},
84 {OV7670_CTL_GAIN
, 0x00},
85 {OV7670_CTL_AECH
, 0x00},
86 {OV7670_CTL_COM4
, 0x40},
87 {OV7670_CTL_COM9
, 0x08},
88 {OV7670_CTL_BD50MAX
, 0x05},
89 {OV7670_CTL_BD60MAX
, 0x07},
90 {OV7670_CTL_AEW
, 0x95},
91 {OV7670_CTL_AEB
, 0x33},
92 {OV7670_CTL_VPT
, 0xe3},
93 {OV7670_CTL_HAECC1
, 0x75},
94 {OV7670_CTL_HAECC2
, 0x65},
96 {OV7670_CTL_HAECC3
, 0xd8},
97 {OV7670_CTL_HAECC4
, 0xd8},
98 {OV7670_CTL_HAECC5
, 0xf0},
99 {OV7670_CTL_HAECC6
, 0x90},
100 {OV7670_CTL_HAECC7
, 0x94},
101 {OV7670_CTL_COM8
, 0xe5},
102 {OV7670_CTL_COM5
, 0x61},
103 {OV7670_CTL_COM6
, 0x4b},
105 {OV7670_CTL_MVFP
, 0x27},
106 {OV7670_CTL_ADCCTR1
, 0x02},
107 {OV7670_CTL_ADCCTR2
, 0x91},
109 {OV7670_CTL_CHLF
, 0x0b},
111 {OV7670_CTL_ADC
, 0x1d},
112 {OV7670_CTL_ACOM
, 0x71},
113 {OV7670_CTL_OFON
, 0x2a},
114 {OV7670_CTL_COM12
, 0x78},
117 {OV7670_CTL_GFIX
, 0x00},
118 {OV7670_CTL_REG74
, 0x19},
127 {OV7670_CTL_ABLC1
, 0x0c},
129 {OV7670_CTL_THL_ST
, 0x82},
131 {OV7670_CTL_AWBC1
, 0x0a},
132 {OV7670_CTL_AWBC2
, 0xf0},
133 {OV7670_CTL_AWBC3
, 0x20},
134 {OV7670_CTL_AWBC4
, 0x7d},
135 {OV7670_CTL_AWBC5
, 0x29},
136 {OV7670_CTL_AWBC6
, 0x4a},
143 {OV7670_CTL_AWBCTR3
, 0x0a},
144 {OV7670_CTL_AWBCTR2
, 0x55},
145 {OV7670_CTL_AWBCTR1
, 0x11},
146 {OV7670_CTL_AWBCTR0
, 0x9e},
147 {OV7670_CTL_GGAIN
, 0x40},
148 {OV7670_CTL_BLUE
, 0x40},
149 {OV7670_CTL_RED
, 0x40},
150 {OV7670_CTL_COM8
, 0xe7},
151 {OV7670_CTL_MTX1
, 0x6e},
152 {OV7670_CTL_MTX2
, 0x70},
153 {OV7670_CTL_MTX3
, 0x02},
154 {OV7670_CTL_MTX4
, 0x1d},
155 {OV7670_CTL_MTX5
, 0x56},
156 {OV7670_CTL_MTX6
, 0x73},
157 {OV7670_CTL_BRIGHT
, 0x0a},
158 {OV7670_CTL_CONTRAS
, 0x55},
159 {OV7670_CTL_CONTRAS_CENTER
, 0x80},
160 {OV7670_CTL_MTXS
, 0x9e},
161 {OV7670_CTL_COM16
, 0x08},
162 {OV7670_CTL_EDGE
, 0x02},
163 {OV7670_CTL_REG75
, 0x03},
164 {OV7670_CTL_REG76
, 0x63},
165 {OV7670_CTL_DNSTH
, 0x04},
166 {OV7670_CTL_REG77
, 0x06},
167 {OV7670_CTL_COM13
, 0xc2},
168 {OV7670_CTL_REG4B
, 0x09},
169 {OV7670_CTL_SATCTR
, 0x30},
170 {OV7670_CTL_COM16
, 0x08},
171 {OV7670_CTL_CONTRAS
, 0x48},
172 {OV7670_CTL_ARBLM
, 0x11},
173 {OV7670_CTL_COM11
, 0xc2},
174 {OV7670_CTL_NT_CTRL
, 0x88},
182 {OV7670_CTL_BD50ST
, 0x99},
183 {OV7670_CTL_BD60ST
, 0x7f},
208 {OV7670_CTL_LCC1
, 0x20},
209 {OV7670_CTL_LCC2
, 0x00},
210 {OV7670_CTL_LCC3
, 0x06},
211 {OV7670_CTL_LCC4
, 0x00},
212 {OV7670_CTL_LCC5
, 0x05},
213 {OV7670_CTL_LCC6
, 0x05},
214 {OV7670_CTL_LCC7
, 0x0a},
215 {OV7670_CTL_HSTART
, 0x13},
216 {OV7670_CTL_HSTOP
, 0x01},
217 {OV7670_CTL_VSTRT
, 0x02},
218 {OV7670_CTL_VSTOP
, 0x7a},
219 {OV7670_CTL_AWBC4
, 0x59},
220 {OV7670_CTL_AWBC5
, 0x30},
221 {OV7670_CTL_MTXS
, 0x9a},
228 {OV7670_CTL_LCC3
, 0x07},
229 {OV7670_CTL_LCC6
, 0x07},
230 {OV7670_CTL_LCC7
, 0x0d},
231 {OV7670_CTL_HAECC3
, 0xdf},
232 {OV7670_CTL_HAECC4
, 0xdf},
233 {OV7670_CTL_AWBC6
, 0x4d},
234 {OV7670_CTL_MTX3
, 0x00},
236 {OV7670_CTL_DBLV
, 0x0a},
237 {OV7670_CTL_CLKRC
, 0x80},
238 {OV7670_CTL_EXHCH
, 0x00},
239 {OV7670_CTL_EXHCL
, 0x00},
240 {OV7670_CTL_DM_LNL
, 0x00},
241 {OV7670_CTL_DM_LNH
, 0x00},
242 {OV7670_CTL_COM11
, 0xc2},
243 {OV7670_CTL_BRIGHT
, 0x0a},
244 {OV7670_CTL_CONTRAS
, 0x60},
245 {OV7670_CTL_MTX1
, 0x6e},
246 {OV7670_CTL_MTX1
+ 1, 0x70},
247 {OV7670_CTL_MTX1
+ 2, 0x00},
248 {OV7670_CTL_MTX1
+ 3, 0x1d},
249 {OV7670_CTL_MTX5
, 0x56},
250 {OV7670_CTL_MTX5
+ 1, 0x73},
251 {OV7670_CTL_MTXS
, 0x9a},
252 {OV7670_CTL_MTX1
, 0x6e},
253 {OV7670_CTL_MTX1
+ 1, 0x70},
254 {OV7670_CTL_MTX1
+ 2, 0x00},
255 {OV7670_CTL_MTX1
+ 3, 0x1d},
256 {OV7670_CTL_MTX5
, 0x56},
257 {OV7670_CTL_MTX5
+ 1, 0x73},
258 {OV7670_CTL_MTXS
, 0x9a},
259 {OV7670_CTL_EDGE
, 0x01},
260 {OV7670_CTL_GAM1
, 0x03},
261 {OV7670_CTL_GAM1
+ 1, 0x09},
262 {OV7670_CTL_GAM1
+ 2, 0x16},
263 {OV7670_CTL_GAM1
+ 3, 0x38},
264 {OV7670_CTL_GAM5
, 0x47},
265 {OV7670_CTL_GAM5
+ 1, 0x53},
266 {OV7670_CTL_GAM5
+ 2, 0x5e},
267 {OV7670_CTL_GAM5
+ 3, 0x6a},
268 {OV7670_CTL_GAM9
, 0x74},
269 {OV7670_CTL_GAM9
+ 1, 0x80},
270 {OV7670_CTL_GAM9
+ 2, 0x8c},
271 {OV7670_CTL_GAM9
+ 3, 0x9b},
272 {OV7670_CTL_GAM13
, 0xb2},
273 {OV7670_CTL_GAM13
+ 1, 0xcc},
274 {OV7670_CTL_GAM13
+ 2, 0xe5},
275 {OV7670_CTL_SLOP
, 0x24},
276 {OV7670_CTL_COM11
, 0xc0},
277 {OV7670_CTL_COM11
, 0xc0},
278 {OV7670_CTL_HAECC1
, 0x76},
279 {OV7670_CTL_HAECC1
+ 1, 0x65},
280 {OV7670_CTL_COM8
, 0xe7},
282 {OV7670_CTL_DBLV
, 0x0a},
283 {OV7670_CTL_CLKRC
, 0x80},
284 {OV7670_CTL_EXHCH
, 0x00},
285 {OV7670_CTL_EXHCL
, 0x00},
286 {OV7670_CTL_DM_LNL
, 0x00},
287 {OV7670_CTL_DM_LNH
, 0x00},
292 * @brief Addresses and values for the initialization of ov965x sensors
295 static __u8 ov9650_init
[][2] = {
296 {OV965X_CTL_COM7
, OV965X_COM7_SCCB_RESET
},
297 {OV965X_CTL_GAIN
, 0x00},
298 {OV965X_CTL_BLUE
, 0x78},
299 {OV965X_CTL_RED
, 0x78},
300 {OV965X_CTL_VREF
, OV965X_VREF_VSTOP_LOW3(0x06) |
301 OV965X_VREF_VSTART_LOW3(0x06)},
302 {OV965X_CTL_COM1
, 0x03},
303 {OV965X_CTL_BAVE
, 0x00}, /* default */
304 {OV965X_CTL_GEAVE
, 0x00}, /* default */
305 {OV965X_CTL_RAVE
, 0x00}, /* default */
306 {OV965X_CTL_COM2
, OV965X_COM2_OUTPUT_DRIVE_CAP_2X
},
307 {OV965X_CTL_COM3
, 0x00},
308 {OV965X_CTL_COM4
, 0x00},
309 {OV965X_CTL_COM5
, OV965X_COM5_15FPS_48MHZ_RGB
| 0x20},
310 {OV965X_CTL_COM6
, OV965X_COM6_TIMING_RESET_ON_FMT_CHANGE
| 0x50},
311 {OV965X_CTL_AECH
, 0x7c},
312 {OV965X_CTL_CLKRC
, OV965X_CLKRC_DBL_CLK_ENABLE
},
313 {OV965X_CTL_COM7
, OV965X_COM7_OUTPUT_VGA
| OV965X_COM7_OUTPUT_RAW_RGB
},
314 {OV965X_CTL_COM8
, OV965X_COM8_FAST_AGC_AEC
|
315 OV965X_COM8_AEC_STEP_SIZE_NOLIMIT
|
316 OV965X_COM8_AWB_ENABLE
},
317 {OV965X_CTL_COM9
, OV965X_COM9_MAX_AGC_4X
|
318 OV965X_COM9_RELAX_EXPOSURE_TIMING
|
319 OV965X_COM9_DROP_VSYNC_ON_FRAME_DROP
|
320 OV965X_COM9_DROP_FRAME_ON_BIG_AEC
},
321 {OV965X_CTL_COM10
, 0x00},
322 {0x16, 0x07}, /* reserved */
323 {OV965X_CTL_HSTART
, 0x24},
324 {OV965X_CTL_HSTOP
, 0xc5},
325 {OV965X_CTL_VSTRT
, 0x00},
326 {OV965X_CTL_VSTOP
, 0x3c},
327 {OV965X_CTL_PSHIFT
, 0x00}, /* default */
328 {OV965X_CTL_MVFP
, 0x04},
329 {OV965X_CTL_LAEC
, 0x00}, /* reserved */
330 {OV965X_CTL_AEW
, 0x78}, /* default */
331 {OV965X_CTL_AEB
, 0x68}, /* default */
332 {OV965X_CTL_VPT
, 0xd4}, /* default */
333 {OV965X_CTL_BBIAS
, OV965X_BIAS_SUBTRACT
}, /* default */
334 {OV965X_CTL_GbBIAS
, OV965X_BIAS_SUBTRACT
}, /* default */
335 {OV965X_CTL_Gr_COM
, OV965X_Gr_COM_BYPASS_ANALOG_BLC
|
336 OV965X_Gr_COM_BYPASS_REGULATOR
},
337 {OV965X_CTL_EXHCH
, 0x00}, /* default */
338 {OV965X_CTL_EXHCL
, 0x00}, /* default */
339 {OV965X_CTL_RBIAS
, OV965X_BIAS_SUBTRACT
}, /* default */
340 {OV965X_CTL_ADVFL
, 0x00}, /* default */
341 {OV965X_CTL_ADVFH
, 0x00}, /* default */
342 {OV965X_CTL_YAVE
, 0x00}, /* default */
343 {OV965X_CTL_HSYST
, 0x08}, /* default */
344 {OV965X_CTL_HSYEN
, 0x30}, /* default */
345 {OV965X_CTL_HREF
, OV965X_HREF_EDGE_OFT_TO_DATA_OUT(2) |
346 OV965X_HREF_HSTOP_LOW3(0) |
347 OV965X_HREF_HSTART_LOW3(4)},
348 {OV965X_CTL_CHLF
, 0xe2}, /* reserved */
349 {OV965X_CTL_ARBLM
, 0xbf}, /* reserved */
350 {0x35, 0x81}, /* reserved */
351 {0x36, 0xf9}, /* reserved */
352 {OV965X_CTL_ADC
, 0x00}, /* reserved */
353 {OV965X_CTL_ACOM
, 0x93}, /* reserved */
354 {OV965X_CTL_OFON
, 0x50},
355 {OV965X_CTL_TSLB
, OV965X_TSLB_OUTPUT_SEQ_UYVY
|
356 OV965X_TSLB_DIGITAL_BLC_ENABLE
},
357 {OV965X_CTL_COM11
, OV965X_COM11_MANUAL_BANDING_FILTER
},
358 {OV965X_CTL_COM12
, 0x73},
359 {OV965X_CTL_COM13
, OV965X_COM13_ENABLE_COLOR_MATRIX
|
360 OV965X_COM13_DELAY_Y_CHANNEL
|
361 OV965X_COM13_OUTPUT_DELAY(1)},
362 {OV965X_CTL_COM14
, OV965X_COM14_YUV_EDGE_ENHANCE
|
363 OV965X_COM14_EDGE_ENHANCE_FACTOR_DBL
| 0x0b},
364 {OV965X_CTL_EDGE
, OV965X_EDGE_EDGE_ENHANCE_LOW4(8) |
365 OV965X_EDGE_EDGE_ENHANCE_FACTOR(8)},
366 {OV965X_CTL_COM15
, OV965X_COM15_OUTPUT_RANGE_O0_TO_FF
| 0x01},
367 {OV965X_CTL_COM16
, 0x00},
368 {OV965X_CTL_COM17
, 0x08},
369 {OV965X_CTL_MANU
, 0x80}, /* default */
370 {OV965X_CTL_MANV
, 0x80}, /* default */
371 {OV965X_CTL_HV
, 0x40},
372 {OV965X_CTL_MBD
, 0x00}, /* default */
373 {OV965X_CTL_DBLV
, 0x0a}, /* reserved */
374 {OV965X_CTL_COM21
, 0x06}, /* reserved */
375 {OV965X_CTL_COM22
, 0x20},
376 {OV965X_CTL_COM23
, 0x00}, /* default */
377 {OV965X_CTL_COM24
, 0x00}, /* reserved */
378 {OV965X_CTL_DBLC1
, 0xdf},
379 {OV965X_CTL_DM_LNL
, 0x00}, /* default */
380 {OV965X_CTL_DM_LNH
, 0x00}, /* default */
381 {0x94, 0x88}, /* reserved */
382 {0x95, 0x88}, /* reserved */
383 {0x96, 0x04}, /* reserved */
384 {OV965X_CTL_AECHM
, 0x00},
385 {OV965X_CTL_COM26
, 0x80}, /* reserved */
386 {0xa8, 0x80}, /* reserved */
387 {0xa9, 0xb8}, /* reserved */
388 {0xaa, 0x92}, /* reserved */
389 {0xab, 0x0a}, /* reserved */
394 * @brief Addresses and values for the initialization of SOI968 sensors
398 static __u8 soi968_init
[][2] = {
399 /* reset all registers */
403 /* snapshot mode: off */
405 /* enable offset adjustment,
407 * analogue2digital control black-level calibration
410 /* Clock: internal PLL on */
412 /* Analoge Black-level calibration off , no anaolgue gain */
416 /* special system settings (voltage, analogue2digital, ...) */
421 /* next 7 are unknown/reserved */
429 /* disable banding filter in dark environment,
430 * VSYNC is dropped when framerate is dropped,
431 * drop frmaes when exposure out of tolerance,
432 * unfreeze exposure and gain values
435 /* AEC, AGC, AWB disabled; fast AEC */
437 /* output: VGA, master mode */
439 /* set HSTART, HSTOP, VSTART and VSTOP */
444 {0x32, 0x24}, /* LSB for all four */
445 /* AWB update threshold,
446 * blue and red gain LSB
449 /* CLock: internal PLL off */
451 /* Line interval adjustment */
458 /* blue and red gain - default*/
463 static __u8 ov9655_init
[][2] = {
464 {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61},
465 {0x11, 0x80}, {0x13, 0xb8}, {0x14, 0x3e}, {0x16, 0x24},
466 {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08},
467 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x32, 0xbf},
468 {0x34, 0x3d}, {0x35, 0x00}, {0x36, 0xf8}, {0x38, 0x12},
469 {0x39, 0x57}, {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c},
470 {0x3d, 0x19}, {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40},
471 {0x42, 0x80}, {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a},
472 {0x48, 0x3c}, {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc},
473 {0x4d, 0xdc}, {0x4e, 0xdc}, {0x69, 0x02}, {0x6c, 0x04},
474 {0x6f, 0x9e}, {0x70, 0x05}, {0x71, 0x78}, {0x77, 0x02},
475 {0x8a, 0x23}, {0x8c, 0x0d}, {0x90, 0x7e}, {0x91, 0x7c},
476 {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, {0xa6, 0x60},
477 {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, {0xab, 0x04},
478 {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, {0xaf, 0x80},
479 {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, {0xb6, 0xaf},
480 {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, {0xbe, 0x3b},
481 {0xbf, 0x3a}, {0xc0, 0xe2}, {0xc1, 0xc8}, {0xc2, 0x01},
482 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
483 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x12, 0x61},
484 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
485 {0x03, 0x12}, {0x17, 0x14}, {0x18, 0x00}, {0x19, 0x01},
486 {0x1a, 0x3d}, {0x32, 0xbf}, {0x11, 0x80}, {0x2a, 0x10},
487 {0x2b, 0x0a}, {0x92, 0x00}, {0x93, 0x00}, {0x1e, 0x04},
488 {0x1e, 0x04}, {0x10, 0x7c}, {0x04, 0x03}, {0xa1, 0x00},
489 {0x2d, 0x00}, {0x2e, 0x00}, {0x00, 0x00}, {0x01, 0x80},
490 {0x02, 0x80}, {0x12, 0x61}, {0x36, 0xfa}, {0x8c, 0x8d},
491 {0xc0, 0xaa}, {0x69, 0x0a}, {0x03, 0x12}, {0x17, 0x14},
492 {0x18, 0x00}, {0x19, 0x01}, {0x1a, 0x3d}, {0x32, 0xbf},
493 {0x11, 0x80}, {0x2a, 0x10}, {0x2b, 0x0a}, {0x92, 0x00},
494 {0x93, 0x00}, {0x04, 0x01}, {0x10, 0x1f}, {0xa1, 0x00},
495 {0x00, 0x0a}, {0xa1, 0x00}, {0x10, 0x5d}, {0x04, 0x03},
496 {0x00, 0x01}, {0xa1, 0x00}, {0x10, 0x7c}, {0x04, 0x03},
497 {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
501 * @brief Initialize ov sensors
503 * @param dev Pointer to device structure
505 * @return 0 or negative error code
508 int ov_initialize(struct usb_microdia
*dev
)
513 switch (dev
->camera
.sensor
->id
) {
515 for (i
= 0; i
< ARRAY_SIZE(soi968_init
); i
++) {
516 ret
= sn9c20x_write_i2c_data(dev
, 1,
517 soi968_init
[i
][0], &soi968_init
[i
][1]);
523 for (i
= 0; i
< ARRAY_SIZE(ov9650_init
); i
++) {
524 ret
= sn9c20x_write_i2c_data(dev
, 1,
525 ov9650_init
[i
][0], &ov9650_init
[i
][1]);
531 for (i
= 0; i
< ARRAY_SIZE(ov9655_init
); i
++) {
532 ret
= sn9c20x_write_i2c_data(dev
, 1,
533 ov9655_init
[i
][0], &ov9655_init
[i
][1]);
539 for (i
= 0; i
< ARRAY_SIZE(ov7670_init
); i
++) {
540 ret
= sn9c20x_write_i2c_data(dev
, 1,
541 ov7670_init
[i
][0], &ov7670_init
[i
][1]);
547 for (i
= 0; i
< ARRAY_SIZE(ov7660_init
); i
++) {
548 ret
= sn9c20x_write_i2c_data(dev
, 1,
549 ov7660_init
[i
][0], &ov7660_init
[i
][1]);
561 UDIA_ERROR("Sensor Init failed (%d)! - line %d\n", ret
, i
);
566 * @brief Set exposure for ov7660 sensors
570 * @return 0 or negative error value
574 int ov7660_set_exposure(struct usb_microdia
*dev
)
577 __u8 val
[2] = {(dev
->vsettings
.exposure
>> 4) & 0xff,
578 dev
->vsettings
.exposure
>> 12};
580 ret
= sn9c20x_write_i2c_data_ext(dev
, 2, 0x2d, val
, 0x1e);
586 * @brief Set ov7660 sensors to soft-sleep mode
588 * @return 0 or negative error value
591 int ov7660_sleep(struct usb_microdia
*dev
)
596 /* Set the sensor to Soft Sleep mode, Set O/P drive capability to 4X*/
598 ret
= sn9c20x_write_i2c_data(dev
, 1, OV7660_CTL_COM2
, buf
);
605 UDIA_ERROR("Setting Image Sensor to soft sleep failed(%d)!\n", ret
);
610 * @brief Get ov7660 sensors to wake up from soft-sleep mode
612 * @return 0 or negative error value
615 int ov7660_wakeup(struct usb_microdia
*dev
)
620 /* Wake the sensor from Soft Sleep mode, Set O/P drive capability to 4X */
622 ret
= sn9c20x_write_i2c_data(dev
, 1, OV7660_CTL_COM2
, buf
);
629 UDIA_ERROR("Image Sensor failed to wake-up from soft sleep (%d)!\n", ret
);
634 * @brief Resets all the registers on ov7660 sensor
636 * @return 0 or negative error value
639 int ov7660_reset(struct usb_microdia
*dev
)
644 /* Reset all registers to default value */
645 /* Set O/P format - RGB Selection, Set O/P format Raw RGB */
647 ret
= sn9c20x_write_i2c_data(dev
, 1, OV7660_CTL_COM7
, buf
);
654 UDIA_ERROR("Failed to reset the Image Sensor (%d)!\n", ret
);
659 * @brief OV7670 Auto-Flip
661 * @param dev Pointer to the device
662 * @param vflip Flag to indicate whether or not Camera is currently flipped
664 * @return Zero (success) or negative (USB-error value)
667 int ov7670_auto_flip(struct usb_microdia
*dev
, __u8 vflip
)
672 ret
= sn9c20x_read_i2c_data(dev
, 1,
673 OV7670_CTL_MVFP
, buf
);
678 buf
[0] = buf
[0] & (0xff ^ OV7670_VFLIP_BIT
);
680 buf
[0] = buf
[0] | OV7670_VFLIP_BIT
;
681 ret
= sn9c20x_write_i2c_data(dev
, 1,
682 OV7670_CTL_MVFP
, buf
);
688 * @brief Set hflip and vflip in ov965x sensors
690 * @param dev Pointer to device structure
692 * @returns 0 or negative error code
695 int ov965x_set_hvflip(struct usb_microdia
*dev
)
700 * Changing hstop value seems to be necessary to keep correct
701 * colors during a vflip. The values don't seem to make much
702 * sense since to keep the correct color value i'm setting hstop
703 * to the same value as hstart is set for.
706 ret
= sn9c20x_read_i2c_data(dev
, 1, OV965X_CTL_MVFP
, &value
);
710 if (dev
->vsettings
.hflip
)
711 value
|= OV965X_MVFP_MIRROR
;
713 value
&= ~OV965X_MVFP_MIRROR
;
715 if (dev
->vsettings
.vflip
) {
717 value
|= OV965X_MVFP_VFLIP
;
719 value
&= ~OV965X_MVFP_VFLIP
;
722 ret
= sn9c20x_write_i2c_data(dev
, 1, OV965X_CTL_HSTOP
, &hstop
);
724 ret
= sn9c20x_write_i2c_data(dev
, 1, OV965X_CTL_MVFP
, &value
);
730 * @brief Set exposure for ov965x sensors
734 * @returns 0 or negative error value
736 * The used registers do not show up the datasheets.
739 int ov965x_set_exposure(struct usb_microdia
*dev
)
742 __u8 val
[2] = {(dev
->vsettings
.exposure
>> 4) & 0xff,
743 dev
->vsettings
.exposure
>> 12};
745 ret
= sn9c20x_write_i2c_data_ext(dev
, 2, 0x2d, val
, 0x1e);
751 * @brief Get average Y value for ov965x sensors
755 * @returns Y value or negative error value
757 * @author Vasily Khoruzhick
760 int ov965x_get_yavg(struct usb_microdia
*dev
)
765 ret
|= sn9c20x_read_i2c_data(dev
, 1, 0x2f, &yavg
);
772 * @brief Set autoexposure for omnivision sensors
776 * @returns 0 or negative error value
780 * For all Omnivision sensors and SOI968.
782 int ov_set_autoexposure(struct usb_microdia
*dev
)
787 ret
= sn9c20x_read_i2c_data(dev
, 1, 0x13, buf
);
791 switch (dev
->vsettings
.auto_exposure
) {
792 case V4L2_EXPOSURE_AUTO
:
795 case V4L2_EXPOSURE_MANUAL
:
798 case V4L2_EXPOSURE_SHUTTER_PRIORITY
:
801 case V4L2_EXPOSURE_APERTURE_PRIORITY
:
808 ret
= sn9c20x_write_i2c_data(dev
, 1, 0x13, buf
);
814 * @brief Set autogain for omnivision sensors
818 * @returns 0 or negative error value
822 * For all Omnivision sensors and SOI968.
824 int ov_set_autogain(struct usb_microdia
*dev
)
829 ret
= sn9c20x_read_i2c_data(dev
, 1, 0x13, buf
);
833 if (dev
->vsettings
.auto_gain
== 1)
835 else if (dev
->vsettings
.auto_gain
== 0)
840 ret
= sn9c20x_write_i2c_data(dev
, 1, 0x13, buf
);
846 * @brief Set exposure for SOI968 sensors
850 * @returns 0 or negative error value
854 * For SOI968 sensors.
856 int soi968_set_exposure(struct usb_microdia
*dev
)
859 int exposure
= dev
->vsettings
.exposure
;
860 __u8 buf1
, buf2
, buf3
;
862 /* Read current value of the I2C-register
863 * containing exposure LSB:
865 ret
= sn9c20x_read_i2c_data(dev
, 1, 0x04, &buf1
);
867 UDIA_ERROR("Error: setting exposure failed: "
868 "error while reading from I2C-register 0x04\n");
872 value
= (exposure
* 0x07ff / 0xffff) & 0x07ff;
873 buf2
= ((__u8
) (value
& 0x07)) | (buf1
& ~0x07);
874 buf3
= (__u8
) (value
>> 3) & 0xff;
876 /* Write new value to I2C-register 0x04: */
877 ret
= sn9c20x_write_i2c_data(dev
, 1, 0x04, &buf2
);
879 UDIA_ERROR("Error: setting exposure failed: "
880 "error while writing to I2C-register 0x04\n");
884 /* Write new value to I2C-register 0x10: */
885 ret
= sn9c20x_write_i2c_data(dev
, 1, 0x10, &buf3
);
887 UDIA_ERROR("Error: setting exposure failed: "
888 "error while writing to I2C-register 0x10\n");
895 int soi968_set_gain(struct usb_microdia
*dev
)
898 __u8 buf
= (dev
->vsettings
.gain
>> 10) & 0x3f;
900 ret
= sn9c20x_write_i2c_data(dev
, 1, 0x00, &buf
);
907 * @brief Detect whether the image for 6260 has to be flipped
909 * @param dev Pointer to device structure
911 * @returns 0 or negative error code
914 int ov7670_flip_detect(struct usb_microdia
*dev
)
916 const __u8 flip_bit
= 0x01;
919 static __u8 flip_reg
= flip_bit
;
922 ret
= usb_microdia_control_read(dev
, 0x1009, &val
, 1);
925 if (flip_reg
!= (val
& flip_bit
)) {
930 ret
= ov7670_auto_flip(dev
, vflip
);
931 flip_reg
= (val
& flip_bit
);
938 * @brief Detect whether the image for 624f has to be flipped
940 * @param dev Pointer to device structure
942 * @returns 0 or negative error code
945 int ov965x_flip_detect(struct usb_microdia
*dev
)
950 ret
= usb_microdia_control_read(dev
, 0x1009, &val
, 1);
954 dev
->vsettings
.vflip
= 1;
956 dev
->vsettings
.vflip
= 0;
960 int soi968_button_detect(struct usb_microdia
*dev
)
964 usb_microdia_control_read(dev
, 0x1005, &buf
, 1);
968 if (dev
->vsettings
.auto_gain
== 0)
969 dev
->vsettings
.auto_gain
= 1;
971 dev
->vsettings
.auto_gain
= 0;
972 ov_set_autogain(dev
);