don't manage version it's boring.
[syntekdriver.git] / driver / stk11xx-dev-0408.c
blob80a0e40a8a925030fca958020c2d9eb56941b184
1 /**
2 * @file stk11xx-dev-0408.c
3 * @author Ivor Hewitt
4 * @date 2009-01-01
5 * @version v2.2.x
7 * @brief Driver for Syntek USB video camera
9 * @note Copyright (C) Nicolas VIVIEN
10 * Copyright (C) Ivor Hewitt
12 * @par Licences
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * @par SubVersion
29 * $Date$
30 * $Revision$
31 * $Author$
32 * $HeadURL$
36 * note currently only supporting 720x576, 704x576 and 640x480 PAL
37 * other resolutions should work but aren't
40 #include <linux/module.h>
41 #include <linux/init.h>
42 #include <linux/kernel.h>
43 #include <linux/version.h>
44 #include <linux/errno.h>
45 #include <linux/slab.h>
46 #include <linux/kref.h>
48 #include <linux/usb.h>
49 #include <media/v4l2-common.h>
50 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
51 #include <media/v4l2-ioctl.h>
52 #endif
54 #include "stk11xx.h"
55 #include "stk11xx-dev.h"
57 int dev_stk0408_check_device(struct usb_stk11xx *dev);
58 int dev_stk0408_select_input(struct usb_stk11xx *dev, int input);
59 int dev_stk0408_write0(struct usb_stk11xx *dev, int mask, int val);
61 /**
62 * @param dev Device structure
64 * @returns 0 if all is OK
66 * @brief This function initializes the device.
68 * This function must be called at first. It's the start of the
69 * initialization process. After this process, the device is
70 * completly initalized and it's ready.
72 * This function is written from the USB log.
74 int dev_stk0408_initialize_device(struct usb_stk11xx *dev)
76 int i;
77 int value;
79 STK_INFO("Initialize USB2.0 Syntek Capture device\n");
81 //what is all this writing to register 2 doing?
82 usb_stk11xx_write_registry(dev, 0x0002, 0x0000);
83 usb_stk11xx_write_registry(dev, 0x0000, 0x0000);
84 usb_stk11xx_write_registry(dev, 0x0002, 0x0000);
85 usb_stk11xx_write_registry(dev, 0x0003, 0x0000);
86 usb_stk11xx_write_registry(dev, 0x0002, 0x0007);
88 usb_stk11xx_read_registry(dev, 0x0002, &value);
89 usb_stk11xx_read_registry(dev, 0x0000, &value);
91 dev_stk0408_write0(dev, 7, 4);
92 dev_stk0408_write0(dev, 7, 4);
93 dev_stk0408_write0(dev, 7, 6);
94 dev_stk0408_write0(dev, 7, 7);
95 dev_stk0408_write0(dev, 7, 6);
96 dev_stk0408_write0(dev, 7, 4);
97 dev_stk0408_write0(dev, 7, 5);
99 for (i=0;i<7;i++)
101 dev_stk0408_write0(dev, 7, 4);
102 dev_stk0408_write0(dev, 7, 4);
103 dev_stk0408_write0(dev, 7, 5);
106 /* start set */
107 usb_stk11xx_write_registry(dev, 0x0002, 0x0007);
108 usb_stk11xx_write_registry(dev, 0x0000, 0x0001);
110 dev_stk0408_configure_device(dev,1);
111 dev_stk0408_configure_device(dev,2);
113 usb_stk11xx_write_registry(dev, 0x0500, 0x0094);
114 msleep(10);
116 dev_stk0408_camera_asleep(dev);
118 usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
119 usb_stk11xx_write_registry(dev, 0x0000, 0x0000);
120 usb_stk11xx_write_registry(dev, 0x0203, 0x00a0);
121 usb_stk11xx_read_registry(dev, 0x0003, &value);
122 usb_stk11xx_write_registry(dev, 0x0003, 0x0000);
124 usb_stk11xx_read_registry(dev, 0x0002, &value); //78?
125 usb_stk11xx_write_registry(dev, 0x0002, 0x007f);
127 usb_stk11xx_read_registry(dev, 0x0002, &value); //7f?
128 usb_stk11xx_read_registry(dev, 0x0000, &value); //0?
130 dev_stk0408_write0(dev, 0x07f, 0x004);
131 dev_stk0408_write0(dev, 0x07f, 0x004);
132 dev_stk0408_write0(dev, 0x07f, 0x006);
133 dev_stk0408_write0(dev, 0x07f, 0x007);
134 dev_stk0408_write0(dev, 0x07f, 0x006);
135 dev_stk0408_write0(dev, 0x07f, 0x004);
136 dev_stk0408_write0(dev, 0x07f, 0x005);
137 dev_stk0408_write0(dev, 0x07f, 0x004);
138 dev_stk0408_write0(dev, 0x07f, 0x004);
139 dev_stk0408_write0(dev, 0x07f, 0x005);
140 dev_stk0408_write0(dev, 0x07f, 0x004);
141 dev_stk0408_write0(dev, 0x07f, 0x006);
142 dev_stk0408_write0(dev, 0x07f, 0x007);
143 dev_stk0408_write0(dev, 0x07f, 0x006);
144 dev_stk0408_write0(dev, 0x07f, 0x006);
145 dev_stk0408_write0(dev, 0x07f, 0x007);
146 dev_stk0408_write0(dev, 0x07f, 0x006);
147 dev_stk0408_write0(dev, 0x07f, 0x004);
148 dev_stk0408_write0(dev, 0x07f, 0x005);
149 dev_stk0408_write0(dev, 0x07f, 0x004);
150 dev_stk0408_write0(dev, 0x07f, 0x004);
151 dev_stk0408_write0(dev, 0x07f, 0x005);
152 dev_stk0408_write0(dev, 0x07f, 0x004);
153 dev_stk0408_write0(dev, 0x07f, 0x004);
154 dev_stk0408_write0(dev, 0x07f, 0x005);
155 dev_stk0408_write0(dev, 0x07f, 0x004);
156 dev_stk0408_write0(dev, 0x07f, 0x004);
157 dev_stk0408_write0(dev, 0x07f, 0x005);
159 usb_stk11xx_write_registry(dev, 0x0002, 0x007f);
160 usb_stk11xx_write_registry(dev, 0x0000, 0x0001);
162 dev_stk11xx_check_device(dev, 500);
164 usb_stk11xx_set_feature(dev, 1);
166 // Device is initialized and is ready !!!
167 STK_INFO("Syntek USB2.0 Capture device is ready\n");
169 return 0;
172 int dev_stk0408_write0(struct usb_stk11xx *dev, int mask, int val)
174 int value;
176 usb_stk11xx_write_registry(dev, 0x0002, mask);
177 usb_stk11xx_write_registry(dev, 0x0000, val);
178 usb_stk11xx_read_registry(dev, 0x0002, &value);
179 usb_stk11xx_read_registry(dev, 0x0000, &value);
181 return 0;
184 int dev_stk0408_write_208(struct usb_stk11xx *dev, int val)
186 int value;
187 int retok;
189 usb_stk11xx_read_registry(dev, 0x02ff, &value);
190 usb_stk11xx_write_registry(dev, 0x02ff, 0x0000);
192 usb_stk11xx_write_registry(dev, 0x0208, val);
193 usb_stk11xx_write_registry(dev, 0x0200, 0x0020);
195 retok = dev_stk0408_check_device(dev);
197 if (retok != 1) {
198 return -1;
201 usb_stk11xx_read_registry(dev, 0x0209, &value);
202 usb_stk11xx_write_registry(dev, 0x02ff, 0x0000);
204 return 1;
207 int dev_stk0408_write_saa(struct usb_stk11xx *dev, int reg, int val)
209 int value;
210 int retok;
212 usb_stk11xx_read_registry(dev, 0x02ff, &value);
213 usb_stk11xx_write_registry(dev, 0x02ff, 0x0000);
215 usb_stk11xx_write_registry(dev, 0x0204, reg);
216 usb_stk11xx_write_registry(dev, 0x0205, val);
217 usb_stk11xx_write_registry(dev, 0x0200, 0x0001);
219 retok = dev_stk0408_check_device(dev);
221 if (retok != 1) {
222 return -1;
225 usb_stk11xx_write_registry(dev, 0x02ff, 0x0000);
227 return 1;
230 int dev_stk0408_set_resolution(struct usb_stk11xx *dev)
233 * These registers control the resolution of the capture buffer.
235 * xres = (X - xsub) / 2
236 * yres = (Y - ysub)
239 int x,y,xsub,ysub;
241 // RRK, need to return for NTSC ?
242 if (dev->vsettings.norm == 0)
243 return 0;
245 switch (stk11xx_image_sizes[dev->resolution].x)
247 case 720:
248 x = 0x5a0;
249 xsub = 0;
250 break;
252 case 704:
253 case 352:
254 case 176:
255 x = 0x584;
256 xsub = 4;
257 break;
259 case 640:
260 case 320:
261 case 160:
262 x = 0x508;
263 xsub = 0x08;
264 break;
266 default:
267 return -1;
270 switch (stk11xx_image_sizes[dev->resolution].y)
272 case 576:
273 case 288:
274 case 144:
275 y = 0x121;
276 ysub = 0x1;
277 break;
279 case 480:
280 y = 0x110;
281 ysub= 0x20;
282 break;
284 case 120:
285 case 240:
286 y = 0x103;
287 ysub = 0x13;
288 break;
290 default:
291 return -1;
294 usb_stk11xx_write_registry(dev, 0x0110, xsub ); // xsub
295 usb_stk11xx_write_registry(dev, 0x0111, 0 );
296 usb_stk11xx_write_registry(dev, 0x0112, ysub ); // ysub
297 usb_stk11xx_write_registry(dev, 0x0113, 0 );
298 usb_stk11xx_write_registry(dev, 0x0114, x ); // X
299 usb_stk11xx_write_registry(dev, 0x0115, 5 );
300 usb_stk11xx_write_registry(dev, 0x0116, y ); // Y
301 usb_stk11xx_write_registry(dev, 0x0117, 1 );
303 return 0;
307 /**
308 * @param dev Device structure
309 * @param step The step of configuration [0-6]
311 * @returns 0 if all is OK
313 * @brief This function configures the device.
315 * This is called multiple times through intitialisation and configuration
316 * there appear to be six distinct steps
319 int dev_stk0408_configure_device(struct usb_stk11xx *dev, int step)
321 int value;
322 int asize;
323 int i;
326 static const int ids[] = {
327 0x203,0x00d,0x00f,0x103,0x018,0x01b,0x01c,0x01a,0x019,
328 0x300,0x350,0x351,0x352,0x353,0x300,0x018,0x202,0x110,
329 0x111,0x112,0x113,0x114,0x115,0x116,0x117
332 const int values[] = {
333 0x04a,0x000,0x002,0x000,0x000,0x00e,0x046,0x014,0x000,
334 0x012,0x02d,0x001,0x000,0x000,0x080,0x010,0x00f,
335 (dev->vsettings.norm ? 0x008 : 0x038),
336 0x000,
337 (dev->vsettings.norm ? 0x013 : 0x003),
338 0x000,
339 (dev->vsettings.norm ? 0x008 : 0x038),
340 0x005,
341 (dev->vsettings.norm ? 0x003 : 0x0f3),
342 (dev->vsettings.norm ? 0x001 : 0x000)
345 if (step != 1)
347 usb_stk11xx_read_registry(dev, 0x0003, &value);
348 usb_stk11xx_read_registry(dev, 0x0001, &value);
349 usb_stk11xx_read_registry(dev, 0x0002, &value);
350 usb_stk11xx_read_registry(dev, 0x0000, &value);
351 usb_stk11xx_read_registry(dev, 0x0003, &value);
352 usb_stk11xx_read_registry(dev, 0x0001, &value);
353 usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
354 usb_stk11xx_write_registry(dev, 0x0000, 0x0000);
355 usb_stk11xx_write_registry(dev, 0x0003, 0x0080);
356 usb_stk11xx_write_registry(dev, 0x0001, 0x0003);
358 usb_stk11xx_read_registry(dev, 0x0002, &value);
359 usb_stk11xx_read_registry(dev, 0x0000, &value);
360 usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
361 usb_stk11xx_read_registry(dev, 0x0000, &value);
362 usb_stk11xx_read_registry(dev, 0x0002, &value);
363 usb_stk11xx_read_registry(dev, 0x0000, &value);
364 usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
365 usb_stk11xx_write_registry(dev, 0x0000, 0x0030);
366 usb_stk11xx_read_registry(dev, 0x0002, &value);
367 usb_stk11xx_read_registry(dev, 0x0002, &value);
368 usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
371 asize = ARRAY_SIZE(values);
373 for(i=0; i<asize; i++) {
374 usb_stk11xx_write_registry(dev, ids[i], values[i]);
377 if (step == 1)
379 usb_stk11xx_read_registry(dev, 0x0100, &value);
380 usb_stk11xx_write_registry(dev, 0x0100, 0x0000);
382 else
384 usb_stk11xx_read_registry(dev, 0x0100, &value);
385 usb_stk11xx_write_registry(dev, 0x0100, 0x0033);
388 if (step <=2 )
390 return 0;
393 if (step==3)
395 dev_stk0408_sensor_settings(dev);
398 usb_stk11xx_read_registry(dev, 0x0100, &value);
399 usb_stk11xx_write_registry(dev, 0x0100, 0x0033);
400 usb_stk11xx_write_registry(dev, 0x0103, 0x0000);
401 usb_stk11xx_write_registry(dev, 0x0100, 0x0033);
404 switch (step)
406 case 3: /* all fine */
407 usb_stk11xx_write_registry(dev, 0x0104, 0x0000);
408 usb_stk11xx_write_registry(dev, 0x0105, 0x0000);
409 usb_stk11xx_write_registry(dev, 0x0106, 0x0000);
411 dev_stk11xx_camera_off(dev);
413 usb_stk11xx_write_registry(dev, 0x0500, 0x0094);
414 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
415 usb_stk11xx_write_registry(dev, 0x0506, 0x0001);
416 usb_stk11xx_write_registry(dev, 0x0507, 0x0000);
418 break;
420 case 5:
421 /* if ((dev->resolution == STK11XX_320x240)||
422 (dev->resolution == STK11XX_352x288))
424 usb_stk11xx_write_registry(dev, 0x0104, 0x0000);
425 usb_stk11xx_write_registry(dev, 0x0105, 0x0000);
426 } */
428 usb_stk11xx_write_registry(dev, 0x0106, 0x0000);
430 dev_stk0408_write_saa(dev, 0x02, 0x80);
431 dev_stk0408_write_208(dev,0x09);
432 dev_stk0408_write_saa(dev, 0x09, 0x00);
434 break;
437 if (step == 3)
439 dev_stk0408_write_saa(dev, 0x02, 0x80);
440 dev_stk0408_write_208(dev,0x09);
441 dev_stk0408_write_saa(dev, 0x09, 0x00);
443 //test and set?
444 usb_stk11xx_write_registry(dev, 0x0504, 0x0012);
445 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
446 usb_stk11xx_write_registry(dev, 0x0504, 0x0012);
447 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
448 usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
449 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
451 usb_stk11xx_write_registry(dev, 0x0504, 0x0010);
452 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
453 usb_stk11xx_write_registry(dev, 0x0504, 0x0010);
454 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
455 usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
456 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
458 usb_stk11xx_write_registry(dev, 0x0504, 0x000e);
459 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
460 usb_stk11xx_write_registry(dev, 0x0504, 0x000e);
461 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
462 usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
463 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
465 usb_stk11xx_write_registry(dev, 0x0504, 0x0016);
466 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
467 usb_stk11xx_write_registry(dev, 0x0504, 0x0016);
468 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
469 usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
470 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
472 usb_stk11xx_write_registry(dev, 0x0504, 0x001a);
473 usb_stk11xx_write_registry(dev, 0x0502, 0x0004);
474 usb_stk11xx_write_registry(dev, 0x0503, 0x0004);
475 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
477 usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
478 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
479 usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
480 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
481 usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
482 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
484 usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
485 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
486 usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
487 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
488 usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
489 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
491 dev_stk0408_write_saa(dev, 0x02, 0x80);
492 dev_stk0408_write_208(dev,0x09);
493 dev_stk0408_write_saa(dev, 0x09, 0x00);
497 if ((step == 4 )|| (step == 6))
499 dev_stk0408_write_saa(dev, 0x02, 0x80);
500 dev_stk0408_write_208(dev,0x09);
501 dev_stk0408_write_saa(dev, 0x09, 0x00);
502 dev_stk0408_write_208(dev,0x0e);
503 dev_stk0408_write_saa(dev, 0x0e, 0x01);
505 dev_stk0408_set_resolution(dev);
507 usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
508 dev_stk0408_set_camera_quality(dev);
511 if (step == 6)
513 usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
515 dev_stk0408_write_208(dev,0x0e);
516 dev_stk0408_write_saa(dev, 0x0e, 0x01);
518 dev_stk0408_set_resolution( dev);
520 usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
522 dev_stk0408_select_input(dev, dev->vsettings.input);
524 dev_stk0408_start_stream(dev);
526 usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
527 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
528 usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
529 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
530 usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
531 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
533 usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
534 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
535 usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
536 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
537 usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
538 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
540 usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
541 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
542 usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
543 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
544 usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
545 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
547 usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
548 usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
549 usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
550 usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
551 usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
552 usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
554 dev_stk0408_start_stream(dev);
558 if (step==4)
560 dev_stk11xx_camera_on(dev);
563 return 0;
567 int dev_stk0408_select_input(struct usb_stk11xx *dev, int input)
569 switch (input)
571 case 1:
572 usb_stk11xx_write_registry(dev, 0x0000, 0x0098);
573 break;
574 case 2:
575 usb_stk11xx_write_registry(dev, 0x0000, 0x0090);
576 break;
577 case 3:
578 usb_stk11xx_write_registry(dev, 0x0000, 0x0088);
579 break;
580 case 4:
581 usb_stk11xx_write_registry(dev, 0x0000, 0x0080);
582 break;
584 usb_stk11xx_write_registry(dev, 0x0002, 0x0093);
586 return 0;
591 /**
592 * @param dev Device structure
594 * @returns 0 if all is OK
596 * @brief Wake-up the camera.
598 * This function permits to wake-up the device.
600 int dev_stk0408_camera_asleep(struct usb_stk11xx *dev)
602 int value;
603 int value0;
605 usb_stk11xx_read_registry(dev, 0x0104, &value);
606 usb_stk11xx_read_registry(dev, 0x0105, &value);
607 usb_stk11xx_read_registry(dev, 0x0106, &value);
609 usb_stk11xx_read_registry(dev, 0x0100, &value);
611 value = value & 0x7f;
612 usb_stk11xx_write_registry(dev, 0x0100, value);
614 usb_stk11xx_write_registry(dev, 0x0116, 0x0000);
615 usb_stk11xx_write_registry(dev, 0x0117, 0x0000);
616 usb_stk11xx_write_registry(dev, 0x0018, 0x0000);
618 usb_stk11xx_read_registry(dev, 0x0002, &value);
619 usb_stk11xx_read_registry(dev, 0x0000, &value0);
620 usb_stk11xx_write_registry(dev, 0x0002, value);
621 usb_stk11xx_read_registry(dev, 0x0000, &value0);
623 return 0;
627 /**
628 * @param dev Device structure
630 * @returns 0 if all is OK
632 * @brief This function initializes the device for the stream.
634 * It's the start. This function has to be called at first, before
635 * enabling the video stream.
637 int dev_stk0408_init_camera(struct usb_stk11xx *dev)
639 dev_stk0408_camera_asleep(dev);
641 dev_stk0408_configure_device(dev, 3);
642 dev_stk0408_configure_device(dev, 4);
643 dev_stk0408_configure_device(dev, 5);
645 dev_stk0408_configure_device(dev, 6);
647 return 0;
650 int dev_stk0408_check_device(struct usb_stk11xx *dev)
652 int i;
653 int value;
654 const int retry=2;
656 for (i=0; i < retry; i++) {
657 usb_stk11xx_read_registry(dev, 0x201, &value);
659 //writes to 204/204 return 4 on success
660 //writes to 208 return 1 on success
662 if (value == 0x04 || value == 0x01)
663 return 1;
665 if (value != 0x00)
667 STK_ERROR("Check device return error (0x0201 = %02X) !\n", value);
668 return -1;
670 // msleep(10);
673 return 0;
677 /**
678 * @param dev Device structure
680 * @returns 0 if all is OK
682 * @brief This function sets the default sensor settings
684 * We set some registers in using a I2C bus.
685 * WARNING, the sensor settings can be different following the situation.
687 int dev_stk0408_sensor_settings(struct usb_stk11xx *dev)
689 int i;
690 int retok;
691 int asize;
693 // PAL registers
694 static const int registers[] = {
695 0x01,0x03,0x04,0x05,0x06,0x07,0x08,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
696 0x13,0x15,0x16,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,
697 0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b };
699 const int values[] = {
700 0x08,0x33,0x00,0x00,0xe9,0x0d,
701 (dev->vsettings.norm ? 0x38 : 0x78),
702 0x80,0x47,0x40,0x00,0x01,0x2a,0x00,0x0c,0xe7,
703 0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
704 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0xff,0xff,0xff,0x40,0x54,
705 (dev->vsettings.norm ? 0x07 : 0x0a),
706 0x83 };
708 asize = ARRAY_SIZE(values);
710 for(i=0; i<asize; i++) {
711 retok = dev_stk0408_write_saa(dev, registers[i], values[i]);
713 if (retok != 1) {
714 STK_ERROR("Load default sensor settings fail !\n");
715 return -1;
719 return 0;
723 /**
724 * @param dev Device structure
726 * @returns 0 if all is OK
728 ' * @brief This function permits to modify the settings of the camera.
730 * This functions permits to modify the settings :
731 * - brightness
732 * - contrast
733 * - white balance
734 * - ...
736 int dev_stk0408_camera_settings(struct usb_stk11xx *dev)
738 dev_stk0408_set_camera_quality(dev);
740 return 0;
744 /**
745 * @param dev Device structure
747 * @returns 0 if all is OK
749 * @brief This function permits to modify the settings of the camera.
752 int dev_stk0408_set_camera_quality(struct usb_stk11xx *dev)
754 usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
756 //brightness
757 dev_stk0408_write_saa(dev, 0x0a, dev->vsettings.brightness >> 8); //80
758 //contrast
759 dev_stk0408_write_saa(dev, 0x0b, dev->vsettings.contrast >> 9); //40
760 //hue
761 dev_stk0408_write_saa(dev, 0x0d, (dev->vsettings.colour - 32768) >> 8); //00
762 //saturation
763 dev_stk0408_write_saa(dev, 0x0c, (dev->vsettings.hue) >> 9); //40
765 STK_DEBUG("Set colour : %d\n", dev->vsettings.colour);
766 STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast);
767 STK_DEBUG("Set hue : %d\n", dev->vsettings.hue);
768 STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness);
770 return 1;
774 /**
775 * @param dev Device structure
777 * @returns 0 if all is OK
779 * @brief This function permits to modify the settings of the camera.
781 * This functions permits to modify the frame rate per second.
784 int dev_stk0408_set_camera_fps(struct usb_stk11xx *dev)
786 //Unknown, setting FPS seems to have no effect
787 return 0;
791 /**
792 * @param dev Device structure
794 * @returns 0 if all is OK
796 * @brief This function sets the device to start the stream.
798 * After the initialization of the device and the initialization of the video stream,
799 * this function permits to enable the stream.
801 int dev_stk0408_start_stream(struct usb_stk11xx *dev)
803 int value;
804 int value_116, value_117;
806 usb_stk11xx_read_registry(dev, 0x0116, &value_116);
807 usb_stk11xx_read_registry(dev, 0x0117, &value_117);
809 usb_stk11xx_write_registry(dev, 0x0116, 0x0000);
810 usb_stk11xx_write_registry(dev, 0x0117, 0x0000);
812 usb_stk11xx_read_registry(dev, 0x0100, &value);
813 value |= 0x80;
815 // msleep(0x1f4);
816 usb_stk11xx_write_registry(dev, 0x0100, value);
817 // msleep(0x64);
819 usb_stk11xx_write_registry(dev, 0x0116, value_116);
820 usb_stk11xx_write_registry(dev, 0x0117, value_117);
822 return 0;
826 /**
827 * @param dev Device structure
829 * @returns 0 if all is OK
831 * @brief Reconfigure the camera before the stream.
833 * Before enabling the video stream, you have to reconfigure the device.
835 int dev_stk0408_reconf_camera(struct usb_stk11xx *dev)
838 dev_stk0408_configure_device(dev, 6);
840 dev_stk11xx_camera_settings(dev);
842 return 0;
846 /**
847 * @param dev Device structure
849 * @returns 0 if all is OK
851 * @brief This function sets the device to stop the stream.
853 * You use the function start_stream to enable the video stream. So you
854 * have to use the function stop_strem to disable the video stream.
856 int dev_stk0408_stop_stream(struct usb_stk11xx *dev)
858 int value;
860 usb_stk11xx_read_registry(dev, 0x0100, &value);
861 value &= 0x7f;
862 usb_stk11xx_write_registry(dev, 0x0100, value);
863 msleep(5);
865 return 0;
869 * Needs some more work and optimisation!
871 void stk11xx_copy_uvyv(uint8_t *src, uint8_t *rgb,
872 struct stk11xx_coord *image,
873 struct stk11xx_coord *view,
874 const int hflip, const int vflip,
875 const int hfactor, const int vfactor,
876 bool order, bool field)
878 int width = image->x;
879 int height = image->y;
880 int x;
881 int y;
883 uint8_t *line1 = NULL;
884 uint8_t *line2 = NULL;
886 static uint8_t *prev=0;
887 if (!prev)
888 prev = rgb;
890 // printk("copy image %d - %d %d,%d,%d\n", width, height, hfactor, vfactor, field);
892 // vfactor=1 interlace rows
893 // vfactor=2 full frame copy, duplicate rows
894 // vfactor=4 half frame, copy rows
896 if (field == false) // odd frame
898 prev += width * 2;
901 for ( y=0; y < height/2; y++)
903 if (vfactor == 1)
905 if (field == false) // odd frame
907 line1 = rgb + (y*width*4);
908 line2 = rgb + (y*width*4) + width*2;
910 else
912 line1 = rgb + (y*width*4) + width*2;
913 line2 = rgb + (y*width*4);
916 else
918 line1 = rgb + (y*width*2);
922 if (order && hfactor == 1) //fast line copy with memcpy
924 memcpy(line1,src,width*2);
925 src += width*2;
927 else //slow line copy with hscaling or YUV reorder
929 for ( x = 0; x < width*2; x+=4)
931 if (order) //yuv order
933 line1[x] = src[0];
934 line1[x+1] = src[1];
935 line1[x+2] = src[2];
936 line1[x+3] = src[3];
938 else
940 line1[x] = src[1];
941 line1[x+1] = src[0];
942 line1[x+2] = src[3];
943 line1[x+3] = src[2];
945 src += (4 * hfactor);
949 if (vfactor == 1) //interlaced copy from previous frame
951 memcpy(line2,prev,width*2);
952 prev += width*4;
954 else if (vfactor == 2) //1 : 1
957 else if (vfactor == 4) // 2 : 1
959 src += (width*2)*2;
963 prev = rgb;
967 * needs more work and optimisation!
969 * rgb is horribly slow but just written to check the image is working
970 * replace with a proper yuv to rgb conversion
972 #define CLAMP(x) x < 0 ? 0 : x > 255 ? 255 : x
974 void stk11xx_copy_rgb(uint8_t *src, uint8_t *rgb,
975 struct stk11xx_coord *image,
976 struct stk11xx_coord *view,
977 const int hflip, const int vflip,
978 const int hfactor, const int vfactor,
979 bool order, bool four, bool field)
982 int width = image->x;
983 int height = image->y;
984 int x;
985 int y;
986 int step;
988 bool off = false;
990 uint8_t *line1 = NULL;
991 uint8_t *line2 = NULL;
993 static uint8_t *prev=0;
994 if (!prev)
995 prev = rgb;
997 step = four?4:3;
999 if (field==false)
1001 prev += width * step;
1004 //uvyv
1005 for ( y=0; y < height/2; y++)
1007 if (vfactor == 1)
1009 if (field == false) // odd frame
1011 line1 = rgb + (y * width * step * 2);
1012 line2 = rgb + (y * width * step * 2) + width * step;
1014 else
1016 line1 = rgb + (y * width * step * 2) + width * step;
1017 line2 = rgb + (y * width * step * 2);
1020 else
1022 line1 = rgb + (y * width * step);
1025 off=false;
1026 for ( x = 0; x < width*step; x+=step)
1029 C = Y - 16
1030 D = U - 128
1031 E = V - 128
1033 R = clip(( 298 * C + 409 * E + 128) >> 8)
1034 G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
1035 B = clip(( 298 * C + 516 * D + 128) >> 8)
1037 int c = src[off ? 3 : 1];
1038 int d = src[0] - 128;
1039 int e = src[2] - 128;
1041 int R = ((298*c + 409 * e + 128) >>8);
1042 int G = ((298*c - 100 * d - 208 * e + 128)>>8);
1043 int B = ((298*c + 516 * d + 128)>>8);
1045 R = CLAMP(R);
1046 G = CLAMP(G);
1047 B = CLAMP(B);
1049 if (order)
1051 line1[x] = B;
1052 line1[x+1] = G;
1053 line1[x+2] = R;
1055 else
1057 line1[x] = R;
1058 line1[x+1] = G;
1059 line1[x+2] = B;
1061 if (four)
1062 line1[x+3] = 0;
1064 if (off)
1066 src += (4 * hfactor);
1067 off = false;
1069 else
1071 off = true;
1077 if (vfactor == 1) //interlaced copy from previous frame
1079 for ( x = 0; x < width * step; x++ )
1081 line2[x] = (*prev++); //line1[x];
1083 prev += width * step;
1087 prev = rgb;
1091 int dev_stk0408_decode(struct usb_stk11xx *dev)
1093 void *data;
1094 void *image;
1096 int vfactor;
1097 int hfactor;
1098 bool odd;
1100 struct stk11xx_frame_buf *framebuf;
1102 if (dev == NULL)
1103 return -EFAULT;
1105 framebuf = dev->read_frame;
1107 if (framebuf == NULL)
1108 return -EFAULT;
1110 image = dev->image_data;
1111 STK_DEBUG("fill image %d\n", dev->fill_image);
1113 image += dev->images[dev->fill_image].offset;
1115 data = framebuf->data;
1116 odd = framebuf->odd;
1118 switch (dev->resolution) {
1121 //Currently only 1:1 resolutions are working
1122 case STK11XX_160x120:
1123 case STK11XX_176x144:
1124 hfactor = 4;
1125 vfactor = 4;
1126 break;
1128 case STK11XX_320x240:
1129 case STK11XX_352x240:
1130 case STK11XX_352x288:
1131 hfactor = 2;
1132 vfactor = 2;
1133 break;
1135 case STK11XX_640x480:
1136 /* case STK11XX_720x480:*/
1137 case STK11XX_720x576:
1138 hfactor = 1;
1139 vfactor = 1;
1140 break;
1142 default:
1143 return -EFAULT;
1146 switch (dev->vsettings.palette) {
1147 case STK11XX_PALETTE_RGB24:
1148 stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, false,false,odd);
1149 break;
1150 case STK11XX_PALETTE_RGB32:
1151 stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, false,true,odd);
1152 break;
1153 case STK11XX_PALETTE_BGR24:
1154 stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, true,false,odd);
1155 break;
1156 case STK11XX_PALETTE_BGR32:
1157 stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, true,true,odd);
1158 break;
1160 case STK11XX_PALETTE_UYVY:
1161 stk11xx_copy_uvyv(data, image, &dev->image, &dev->view,dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, true,odd);
1162 break;
1163 case STK11XX_PALETTE_YUYV:
1164 stk11xx_copy_uvyv(data, image, &dev->image, &dev->view,dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, false,odd);
1165 break;
1168 return 0;