1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48#include "stk-webcam.h"
49
50#define STK_IIC_BASE (0x0200)
51# define STK_IIC_OP (STK_IIC_BASE)
52# define STK_IIC_OP_TX (0x05)
53# define STK_IIC_OP_RX (0x70)
54# define STK_IIC_STAT (STK_IIC_BASE+1)
55# define STK_IIC_STAT_TX_OK (0x04)
56# define STK_IIC_STAT_RX_OK (0x01)
57
58
59
60# define STK_IIC_ENABLE (STK_IIC_BASE+2)
61# define STK_IIC_ENABLE_NO (0x00)
62
63# define STK_IIC_ENABLE_YES (0x1e)
64
65
66
67
68
69# define STK_IIC_ADDR (STK_IIC_BASE+3)
70# define STK_IIC_TX_INDEX (STK_IIC_BASE+4)
71# define STK_IIC_TX_VALUE (STK_IIC_BASE+5)
72# define STK_IIC_RX_INDEX (STK_IIC_BASE+8)
73# define STK_IIC_RX_VALUE (STK_IIC_BASE+9)
74
75#define MAX_RETRIES (50)
76
77#define SENSOR_ADDRESS (0x60)
78
79
80
81
82#define REG_GAIN 0x00
83#define REG_BLUE 0x01
84#define REG_RED 0x02
85#define REG_VREF 0x03
86#define REG_COM1 0x04
87#define COM1_CCIR656 0x40
88#define COM1_QFMT 0x20
89#define COM1_SKIP_0 0x00
90#define COM1_SKIP_2 0x04
91#define COM1_SKIP_3 0x08
92#define REG_BAVE 0x05
93#define REG_GbAVE 0x06
94#define REG_AECHH 0x07
95#define REG_RAVE 0x08
96#define REG_COM2 0x09
97#define COM2_SSLEEP 0x10
98#define REG_PID 0x0a
99#define REG_VER 0x0b
100#define REG_COM3 0x0c
101#define COM3_SWAP 0x40
102#define COM3_SCALEEN 0x08
103#define COM3_DCWEN 0x04
104#define REG_COM4 0x0d
105#define REG_COM5 0x0e
106#define REG_COM6 0x0f
107#define REG_AECH 0x10
108#define REG_CLKRC 0x11
109#define CLK_PLL 0x80
110#define CLK_EXT 0x40
111#define CLK_SCALE 0x3f
112#define REG_COM7 0x12
113#define COM7_RESET 0x80
114#define COM7_FMT_MASK 0x38
115#define COM7_FMT_SXGA 0x00
116#define COM7_FMT_VGA 0x40
117#define COM7_FMT_CIF 0x20
118#define COM7_FMT_QVGA 0x10
119#define COM7_FMT_QCIF 0x08
120#define COM7_RGB 0x04
121#define COM7_YUV 0x00
122#define COM7_BAYER 0x01
123#define COM7_PBAYER 0x05
124#define REG_COM8 0x13
125#define COM8_FASTAEC 0x80
126#define COM8_AECSTEP 0x40
127#define COM8_BFILT 0x20
128#define COM8_AGC 0x04
129#define COM8_AWB 0x02
130#define COM8_AEC 0x01
131#define REG_COM9 0x14
132#define REG_COM10 0x15
133#define COM10_HSYNC 0x40
134#define COM10_PCLK_HB 0x20
135#define COM10_HREF_REV 0x08
136#define COM10_VS_LEAD 0x04
137#define COM10_VS_NEG 0x02
138#define COM10_HS_NEG 0x01
139#define REG_HSTART 0x17
140#define REG_HSTOP 0x18
141#define REG_VSTART 0x19
142#define REG_VSTOP 0x1a
143#define REG_PSHFT 0x1b
144#define REG_MIDH 0x1c
145#define REG_MIDL 0x1d
146#define REG_MVFP 0x1e
147#define MVFP_MIRROR 0x20
148#define MVFP_FLIP 0x10
149
150#define REG_AEW 0x24
151#define REG_AEB 0x25
152#define REG_VPT 0x26
153#define REG_ADVFL 0x2d
154#define REG_ADVFH 0x2e
155#define REG_HSYST 0x30
156#define REG_HSYEN 0x31
157#define REG_HREF 0x32
158#define REG_TSLB 0x3a
159#define TSLB_YLAST 0x04
160#define TSLB_BYTEORD 0x08
161#define REG_COM11 0x3b
162#define COM11_NIGHT 0x80
163#define COM11_NMFR 0x60
164#define COM11_HZAUTO 0x10
165#define COM11_50HZ 0x08
166#define COM11_EXP 0x02
167#define REG_COM12 0x3c
168#define COM12_HREF 0x80
169#define REG_COM13 0x3d
170#define COM13_GAMMA 0x80
171#define COM13_UVSAT 0x40
172#define COM13_CMATRIX 0x10
173#define COM13_UVSWAP 0x01
174#define REG_COM14 0x3e
175#define COM14_DCWEN 0x10
176#define REG_EDGE 0x3f
177#define REG_COM15 0x40
178#define COM15_R10F0 0x00
179#define COM15_R01FE 0x80
180#define COM15_R00FF 0xc0
181#define COM15_RGB565 0x10
182#define COM15_RGBFIXME 0x20
183#define COM15_RGB555 0x30
184#define REG_COM16 0x41
185#define COM16_AWBGAIN 0x08
186#define REG_COM17 0x42
187#define COM17_AECWIN 0xc0
188#define COM17_CBAR 0x08
189
190
191
192
193
194
195
196
197
198
199#define REG_CMATRIX_BASE 0x4f
200#define CMATRIX_LEN 6
201#define REG_CMATRIX_SIGN 0x58
202
203
204#define REG_BRIGHT 0x55
205#define REG_CONTRAS 0x56
206
207#define REG_GFIX 0x69
208
209#define REG_RGB444 0x8c
210#define R444_ENABLE 0x02
211#define R444_RGBX 0x01
212
213#define REG_HAECC1 0x9f
214#define REG_HAECC2 0xa0
215
216#define REG_BD50MAX 0xa5
217#define REG_HAECC3 0xa6
218#define REG_HAECC4 0xa7
219#define REG_HAECC5 0xa8
220#define REG_HAECC6 0xa9
221#define REG_HAECC7 0xaa
222#define REG_BD60MAX 0xab
223
224
225
226
227
228static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
229{
230 int i = 0;
231 int tmpval = 0;
232
233 if (stk_camera_write_reg(dev, STK_IIC_TX_INDEX, reg))
234 return 1;
235 if (stk_camera_write_reg(dev, STK_IIC_TX_VALUE, val))
236 return 1;
237 if (stk_camera_write_reg(dev, STK_IIC_OP, STK_IIC_OP_TX))
238 return 1;
239 do {
240 if (stk_camera_read_reg(dev, STK_IIC_STAT, &tmpval))
241 return 1;
242 i++;
243 } while (tmpval == 0 && i < MAX_RETRIES);
244 if (tmpval != STK_IIC_STAT_TX_OK) {
245 if (tmpval)
246 STK_ERROR("stk_sensor_outb failed, status=0x%02x\n",
247 tmpval);
248 return 1;
249 } else
250 return 0;
251}
252
253static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
254{
255 int i = 0;
256 int tmpval = 0;
257
258 if (stk_camera_write_reg(dev, STK_IIC_RX_INDEX, reg))
259 return 1;
260 if (stk_camera_write_reg(dev, STK_IIC_OP, STK_IIC_OP_RX))
261 return 1;
262 do {
263 if (stk_camera_read_reg(dev, STK_IIC_STAT, &tmpval))
264 return 1;
265 i++;
266 } while (tmpval == 0 && i < MAX_RETRIES);
267 if (tmpval != STK_IIC_STAT_RX_OK) {
268 if (tmpval)
269 STK_ERROR("stk_sensor_inb failed, status=0x%02x\n",
270 tmpval);
271 return 1;
272 }
273
274 if (stk_camera_read_reg(dev, STK_IIC_RX_VALUE, &tmpval))
275 return 1;
276
277 *val = (u8) tmpval;
278 return 0;
279}
280
281static int stk_sensor_write_regvals(struct stk_camera *dev,
282 struct regval *rv)
283{
284 int ret;
285 if (rv == NULL)
286 return 0;
287 while (rv->reg != 0xff || rv->val != 0xff) {
288 ret = stk_sensor_outb(dev, rv->reg, rv->val);
289 if (ret != 0)
290 return ret;
291 rv++;
292 }
293 return 0;
294}
295
296int stk_sensor_sleep(struct stk_camera *dev)
297{
298 u8 tmp;
299 return stk_sensor_inb(dev, REG_COM2, &tmp)
300 || stk_sensor_outb(dev, REG_COM2, tmp|COM2_SSLEEP);
301}
302
303int stk_sensor_wakeup(struct stk_camera *dev)
304{
305 u8 tmp;
306 return stk_sensor_inb(dev, REG_COM2, &tmp)
307 || stk_sensor_outb(dev, REG_COM2, tmp&~COM2_SSLEEP);
308}
309
310static struct regval ov_initvals[] = {
311 {REG_CLKRC, CLK_PLL},
312 {REG_COM11, 0x01},
313 {0x6a, 0x7d},
314 {REG_AECH, 0x40},
315 {REG_GAIN, 0x00},
316 {REG_BLUE, 0x80},
317 {REG_RED, 0x80},
318
319
320 {REG_COM8, COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC},
321 {0x39, 0x50}, {0x38, 0x93},
322 {0x37, 0x00}, {0x35, 0x81},
323 {REG_COM5, 0x20},
324 {REG_COM1, 0x00},
325 {REG_COM3, 0x00},
326 {REG_COM4, 0x00},
327 {REG_PSHFT, 0x00},
328 {0x16, 0x07},
329 {0x33, 0xe2}, {0x34, 0xbf},
330 {REG_COM16, 0x00},
331 {0x96, 0x04},
332
333
334
335
336
337
338
339
340
341
342 {REG_GFIX, 0x40},
343 {0x8e, 0x00},
344 {REG_COM12, 0x73},
345 {0x8f, 0xdf}, {0x8b, 0x06},
346 {0x8c, 0x20},
347 {0x94, 0x88}, {0x95, 0x88},
348
349 {0x29, 0x3f},
350 {REG_COM6, 0x42},
351 {REG_BD50MAX, 0x80},
352 {REG_HAECC6, 0xb8}, {REG_HAECC7, 0x92},
353 {REG_BD60MAX, 0x0a},
354 {0x90, 0x00}, {0x91, 0x00},
355 {REG_HAECC1, 0x00}, {REG_HAECC2, 0x00},
356 {REG_AEW, 0x68}, {REG_AEB, 0x5c},
357 {REG_VPT, 0xc3},
358 {REG_COM9, 0x2e},
359 {0x2a, 0x00}, {0x2b, 0x00},
360
361 {0xff, 0xff},
362};
363
364
365int stk_sensor_init(struct stk_camera *dev)
366{
367 u8 idl = 0;
368 u8 idh = 0;
369
370 if (stk_camera_write_reg(dev, STK_IIC_ENABLE, STK_IIC_ENABLE_YES)
371 || stk_camera_write_reg(dev, STK_IIC_ADDR, SENSOR_ADDRESS)
372 || stk_sensor_outb(dev, REG_COM7, COM7_RESET)) {
373 STK_ERROR("Sensor resetting failed\n");
374 return -ENODEV;
375 }
376 msleep(10);
377
378 if (stk_sensor_inb(dev, REG_MIDH, &idh)
379 || stk_sensor_inb(dev, REG_MIDL, &idl)) {
380 STK_ERROR("Strange error reading sensor ID\n");
381 return -ENODEV;
382 }
383 if (idh != 0x7f || idl != 0xa2) {
384 STK_ERROR("Huh? you don't have a sensor from ovt\n");
385 return -ENODEV;
386 }
387 if (stk_sensor_inb(dev, REG_PID, &idh)
388 || stk_sensor_inb(dev, REG_VER, &idl)) {
389 STK_ERROR("Could not read sensor model\n");
390 return -ENODEV;
391 }
392 stk_sensor_write_regvals(dev, ov_initvals);
393 msleep(10);
394 STK_INFO("OmniVision sensor detected, id %02X%02X"
395 " at address %x\n", idh, idl, SENSOR_ADDRESS);
396 return 0;
397}
398
399
400static struct regval ov_fmt_uyvy[] = {
401 {REG_TSLB, TSLB_YLAST|0x08 },
402 { 0x4f, 0x80 },
403 { 0x50, 0x80 },
404 { 0x51, 0 },
405 { 0x52, 0x22 },
406 { 0x53, 0x5e },
407 { 0x54, 0x80 },
408 {REG_COM13, COM13_UVSAT|COM13_CMATRIX},
409 {REG_COM15, COM15_R00FF },
410 {0xff, 0xff},
411};
412
413static struct regval ov_fmt_yuyv[] = {
414 {REG_TSLB, 0 },
415 { 0x4f, 0x80 },
416 { 0x50, 0x80 },
417 { 0x51, 0 },
418 { 0x52, 0x22 },
419 { 0x53, 0x5e },
420 { 0x54, 0x80 },
421 {REG_COM13, COM13_UVSAT|COM13_CMATRIX},
422 {REG_COM15, COM15_R00FF },
423 {0xff, 0xff},
424};
425
426
427static struct regval ov_fmt_rgbr[] = {
428 { REG_RGB444, 0 },
429 {REG_TSLB, 0x00},
430 { REG_COM1, 0x0 },
431 { REG_COM9, 0x38 },
432 { 0x4f, 0xb3 },
433 { 0x50, 0xb3 },
434 { 0x51, 0 },
435 { 0x52, 0x3d },
436 { 0x53, 0xa7 },
437 { 0x54, 0xe4 },
438 { REG_COM13, COM13_GAMMA },
439 { REG_COM15, COM15_RGB565|COM15_R00FF },
440 { 0xff, 0xff },
441};
442
443
444static struct regval ov_fmt_rgbp[] = {
445 { REG_RGB444, 0 },
446 {REG_TSLB, TSLB_BYTEORD },
447 { REG_COM1, 0x0 },
448 { REG_COM9, 0x38 },
449 { 0x4f, 0xb3 },
450 { 0x50, 0xb3 },
451 { 0x51, 0 },
452 { 0x52, 0x3d },
453 { 0x53, 0xa7 },
454 { 0x54, 0xe4 },
455 { REG_COM13, COM13_GAMMA },
456 { REG_COM15, COM15_RGB565|COM15_R00FF },
457 { 0xff, 0xff },
458};
459
460
461static struct regval ov_fmt_bayer[] = {
462
463 {REG_TSLB, 0x40},
464
465 {REG_COM15, COM15_R00FF },
466 {0xff, 0xff},
467};
468
469
470
471static int stk_sensor_set_hw(struct stk_camera *dev,
472 int hstart, int hstop, int vstart, int vstop)
473{
474 int ret;
475 unsigned char v;
476
477
478
479
480
481 ret = stk_sensor_outb(dev, REG_HSTART, (hstart >> 3) & 0xff);
482 ret += stk_sensor_outb(dev, REG_HSTOP, (hstop >> 3) & 0xff);
483 ret += stk_sensor_inb(dev, REG_HREF, &v);
484 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7);
485 msleep(10);
486 ret += stk_sensor_outb(dev, REG_HREF, v);
487
488
489
490 ret += stk_sensor_outb(dev, REG_VSTART, (vstart >> 3) & 0xff);
491 ret += stk_sensor_outb(dev, REG_VSTOP, (vstop >> 3) & 0xff);
492 ret += stk_sensor_inb(dev, REG_VREF, &v);
493 v = (v & 0xc0) | ((vstop & 0x7) << 3) | (vstart & 0x7);
494 msleep(10);
495 ret += stk_sensor_outb(dev, REG_VREF, v);
496 return ret;
497}
498
499
500int stk_sensor_configure(struct stk_camera *dev)
501{
502 int com7;
503
504
505
506
507 unsigned dummylines;
508 int flip;
509 struct regval *rv;
510
511 switch (dev->vsettings.mode) {
512 case MODE_QCIF: com7 = COM7_FMT_QCIF;
513 dummylines = 604;
514 break;
515 case MODE_QVGA: com7 = COM7_FMT_QVGA;
516 dummylines = 267;
517 break;
518 case MODE_CIF: com7 = COM7_FMT_CIF;
519 dummylines = 412;
520 break;
521 case MODE_VGA: com7 = COM7_FMT_VGA;
522 dummylines = 11;
523 break;
524 case MODE_SXGA: com7 = COM7_FMT_SXGA;
525 dummylines = 0;
526 break;
527 default: STK_ERROR("Unsupported mode %d\n", dev->vsettings.mode);
528 return -EFAULT;
529 }
530 switch (dev->vsettings.palette) {
531 case V4L2_PIX_FMT_UYVY:
532 com7 |= COM7_YUV;
533 rv = ov_fmt_uyvy;
534 break;
535 case V4L2_PIX_FMT_YUYV:
536 com7 |= COM7_YUV;
537 rv = ov_fmt_yuyv;
538 break;
539 case V4L2_PIX_FMT_RGB565:
540 com7 |= COM7_RGB;
541 rv = ov_fmt_rgbp;
542 break;
543 case V4L2_PIX_FMT_RGB565X:
544 com7 |= COM7_RGB;
545 rv = ov_fmt_rgbr;
546 break;
547 case V4L2_PIX_FMT_SBGGR8:
548 com7 |= COM7_PBAYER;
549 rv = ov_fmt_bayer;
550 break;
551 default: STK_ERROR("Unsupported colorspace\n");
552 return -EFAULT;
553 }
554
555
556 stk_sensor_outb(dev, REG_COM7, com7);
557 msleep(50);
558 stk_sensor_write_regvals(dev, rv);
559 flip = (dev->vsettings.vflip?MVFP_FLIP:0)
560 | (dev->vsettings.hflip?MVFP_MIRROR:0);
561 stk_sensor_outb(dev, REG_MVFP, flip);
562 if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8
563 && !dev->vsettings.vflip)
564 stk_sensor_outb(dev, REG_TSLB, 0x08);
565 stk_sensor_outb(dev, REG_ADVFH, dummylines >> 8);
566 stk_sensor_outb(dev, REG_ADVFL, dummylines & 0xff);
567 msleep(50);
568 switch (dev->vsettings.mode) {
569 case MODE_VGA:
570 if (stk_sensor_set_hw(dev, 302, 1582, 6, 486))
571 STK_ERROR("stk_sensor_set_hw failed (VGA)\n");
572 break;
573 case MODE_SXGA:
574 case MODE_CIF:
575 case MODE_QVGA:
576 case MODE_QCIF:
577
578
579
580
581 break;
582 }
583 msleep(10);
584 return 0;
585}
586
587int stk_sensor_set_brightness(struct stk_camera *dev, int br)
588{
589 if (br < 0 || br > 0xff)
590 return -EINVAL;
591 stk_sensor_outb(dev, REG_AEB, max(0x00, br - 6));
592 stk_sensor_outb(dev, REG_AEW, min(0xff, br + 6));
593 return 0;
594}
595
596