SyntekUSBVideoCamera

stk11xx-dev-0408.c

Go to the documentation of this file.
00001 
00035 /*
00036  * note currently only supporting 720x576, 704x576 and 640x480 PAL
00037  * other resolutions should work but aren't
00038  */
00039 
00040 #include <linux/module.h>
00041 #include <linux/init.h>
00042 #include <linux/kernel.h>
00043 #include <linux/version.h>
00044 #include <linux/errno.h>
00045 #include <linux/slab.h>
00046 #include <linux/kref.h>
00047 
00048 #include <linux/usb.h>
00049 #include <media/v4l2-common.h>
00050 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
00051 #include <media/v4l2-ioctl.h>
00052 #endif
00053 
00054 #include "stk11xx.h"
00055 #include "stk11xx-dev.h"
00056 
00057 int dev_stk0408_check_device(struct usb_stk11xx *dev);
00058 int dev_stk0408_select_input(struct usb_stk11xx *dev, int input);
00059 int dev_stk0408_write0(struct usb_stk11xx *dev, int mask, int val);
00060 
00074 int dev_stk0408_initialize_device(struct usb_stk11xx *dev)
00075 {
00076     int i;
00077     int value;
00078 
00079     STK_INFO("Initialize USB2.0 Syntek Capture device\n");
00080 
00081 //what is all this writing to register 2 doing?
00082     usb_stk11xx_write_registry(dev, 0x0002, 0x0000);
00083     usb_stk11xx_write_registry(dev, 0x0000, 0x0000);
00084     usb_stk11xx_write_registry(dev, 0x0002, 0x0000);
00085     usb_stk11xx_write_registry(dev, 0x0003, 0x0000);
00086     usb_stk11xx_write_registry(dev, 0x0002, 0x0007);
00087 
00088     usb_stk11xx_read_registry(dev, 0x0002, &value);
00089     usb_stk11xx_read_registry(dev, 0x0000, &value);
00090 
00091     dev_stk0408_write0(dev, 7, 4);
00092     dev_stk0408_write0(dev, 7, 4);
00093     dev_stk0408_write0(dev, 7, 6);
00094     dev_stk0408_write0(dev, 7, 7);
00095     dev_stk0408_write0(dev, 7, 6);
00096     dev_stk0408_write0(dev, 7, 4);
00097     dev_stk0408_write0(dev, 7, 5);
00098 
00099     for (i=0;i<7;i++)
00100     {
00101         dev_stk0408_write0(dev, 7, 4);
00102         dev_stk0408_write0(dev, 7, 4);
00103         dev_stk0408_write0(dev, 7, 5);
00104     }
00105 
00106 /* start set */
00107     usb_stk11xx_write_registry(dev, 0x0002, 0x0007);
00108     usb_stk11xx_write_registry(dev, 0x0000, 0x0001);
00109     
00110     dev_stk0408_configure_device(dev,1);
00111     dev_stk0408_configure_device(dev,2);
00112     
00113     usb_stk11xx_write_registry(dev, 0x0500, 0x0094); 
00114     msleep(10);
00115     
00116     dev_stk0408_camera_asleep(dev);
00117 
00118     usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
00119     usb_stk11xx_write_registry(dev, 0x0000, 0x0000);
00120     usb_stk11xx_write_registry(dev, 0x0203, 0x00a0);
00121     usb_stk11xx_read_registry(dev, 0x0003, &value);
00122     usb_stk11xx_write_registry(dev, 0x0003, 0x0000);
00123 
00124     usb_stk11xx_read_registry(dev, 0x0002, &value); //78?
00125     usb_stk11xx_write_registry(dev, 0x0002, 0x007f);
00126 
00127     usb_stk11xx_read_registry(dev, 0x0002, &value); //7f?
00128     usb_stk11xx_read_registry(dev, 0x0000, &value); //0?
00129 
00130     dev_stk0408_write0(dev, 0x07f, 0x004);
00131     dev_stk0408_write0(dev, 0x07f, 0x004);
00132     dev_stk0408_write0(dev, 0x07f, 0x006);
00133     dev_stk0408_write0(dev, 0x07f, 0x007);
00134     dev_stk0408_write0(dev, 0x07f, 0x006);
00135     dev_stk0408_write0(dev, 0x07f, 0x004);
00136     dev_stk0408_write0(dev, 0x07f, 0x005);
00137     dev_stk0408_write0(dev, 0x07f, 0x004);
00138     dev_stk0408_write0(dev, 0x07f, 0x004);
00139     dev_stk0408_write0(dev, 0x07f, 0x005);
00140     dev_stk0408_write0(dev, 0x07f, 0x004);
00141     dev_stk0408_write0(dev, 0x07f, 0x006);
00142     dev_stk0408_write0(dev, 0x07f, 0x007);
00143     dev_stk0408_write0(dev, 0x07f, 0x006);
00144     dev_stk0408_write0(dev, 0x07f, 0x006);
00145     dev_stk0408_write0(dev, 0x07f, 0x007);
00146     dev_stk0408_write0(dev, 0x07f, 0x006);
00147     dev_stk0408_write0(dev, 0x07f, 0x004);
00148     dev_stk0408_write0(dev, 0x07f, 0x005);
00149     dev_stk0408_write0(dev, 0x07f, 0x004);
00150     dev_stk0408_write0(dev, 0x07f, 0x004);
00151     dev_stk0408_write0(dev, 0x07f, 0x005);
00152     dev_stk0408_write0(dev, 0x07f, 0x004);
00153     dev_stk0408_write0(dev, 0x07f, 0x004);
00154     dev_stk0408_write0(dev, 0x07f, 0x005);
00155     dev_stk0408_write0(dev, 0x07f, 0x004);
00156     dev_stk0408_write0(dev, 0x07f, 0x004);
00157     dev_stk0408_write0(dev, 0x07f, 0x005);
00158 
00159     usb_stk11xx_write_registry(dev, 0x0002, 0x007f);
00160     usb_stk11xx_write_registry(dev, 0x0000, 0x0001);
00161 
00162     dev_stk11xx_check_device(dev, 500);
00163 
00164     usb_stk11xx_set_feature(dev, 1); 
00165 
00166     // Device is initialized and is ready !!!
00167     STK_INFO("Syntek USB2.0 Capture device is ready\n");
00168 
00169     return 0;
00170 }
00171 
00172 int dev_stk0408_write0(struct usb_stk11xx *dev, int mask, int val)
00173 {
00174     int value;
00175 
00176     usb_stk11xx_write_registry(dev, 0x0002, mask);
00177     usb_stk11xx_write_registry(dev, 0x0000, val);
00178     usb_stk11xx_read_registry(dev, 0x0002, &value);
00179     usb_stk11xx_read_registry(dev, 0x0000, &value);
00180 
00181     return 0;
00182 }
00183 
00184 int dev_stk0408_write_208(struct usb_stk11xx *dev, int val)
00185 {
00186     int value;
00187     int retok;
00188     
00189     usb_stk11xx_read_registry(dev, 0x02ff, &value);
00190     usb_stk11xx_write_registry(dev, 0x02ff, 0x0000);
00191 
00192     usb_stk11xx_write_registry(dev, 0x0208, val);
00193     usb_stk11xx_write_registry(dev, 0x0200, 0x0020);
00194 
00195     retok = dev_stk0408_check_device(dev);
00196 
00197     if (retok != 1) {
00198         return -1;
00199     }
00200 
00201     usb_stk11xx_read_registry(dev, 0x0209, &value);
00202     usb_stk11xx_write_registry(dev, 0x02ff, 0x0000);
00203 
00204     return 1;
00205 }
00206 
00207 int dev_stk0408_write_saa(struct usb_stk11xx *dev, int reg, int val)
00208 {
00209     int value;
00210     int retok;
00211     
00212     usb_stk11xx_read_registry(dev, 0x02ff, &value);
00213     usb_stk11xx_write_registry(dev, 0x02ff, 0x0000);
00214 
00215     usb_stk11xx_write_registry(dev, 0x0204, reg);
00216     usb_stk11xx_write_registry(dev, 0x0205, val);
00217     usb_stk11xx_write_registry(dev, 0x0200, 0x0001);
00218 
00219     retok = dev_stk0408_check_device(dev);
00220 
00221     if (retok != 1) {
00222         return -1;
00223     }
00224 
00225     usb_stk11xx_write_registry(dev, 0x02ff, 0x0000);
00226 
00227     return 1;
00228 }
00229 
00230 int dev_stk0408_set_resolution(struct usb_stk11xx *dev)
00231 {
00232 /*
00233  * These registers control the resolution of the capture buffer.
00234  * 
00235  * xres = (X - xsub) / 2
00236  * yres = (Y - ysub)
00237  *
00238  */
00239     int x,y,xsub,ysub;
00240     
00241     // RRK, need to return for NTSC ?
00242     if (dev->vsettings.norm == 0)
00243         return 0;
00244 
00245     switch (stk11xx_image_sizes[dev->resolution].x)
00246     {
00247         case 720:
00248             x = 0x5a0;
00249             xsub = 0;
00250             break;
00251             
00252         case 704:
00253         case 352:
00254         case 176:
00255             x = 0x584;
00256             xsub = 4;
00257             break;
00258 
00259         case 640:
00260         case 320:
00261         case 160:
00262             x = 0x508;
00263             xsub = 0x08;
00264             break;
00265 
00266         default:
00267             return -1;
00268     }
00269 
00270     switch (stk11xx_image_sizes[dev->resolution].y)
00271     {
00272         case 576:
00273         case 288:
00274         case 144:
00275             y = 0x121;
00276             ysub = 0x1;
00277             break;
00278 
00279         case 480:
00280             y = 0x110;
00281             ysub= 0x20;
00282             break;
00283         
00284         case 120:
00285         case 240:   
00286             y = 0x103;
00287             ysub = 0x13;
00288             break;
00289 
00290         default:
00291             return -1;
00292     }
00293 
00294     usb_stk11xx_write_registry(dev, 0x0110, xsub ); // xsub
00295     usb_stk11xx_write_registry(dev, 0x0111, 0    );
00296     usb_stk11xx_write_registry(dev, 0x0112, ysub ); // ysub
00297     usb_stk11xx_write_registry(dev, 0x0113, 0    );
00298     usb_stk11xx_write_registry(dev, 0x0114, x    ); // X
00299     usb_stk11xx_write_registry(dev, 0x0115, 5    );
00300     usb_stk11xx_write_registry(dev, 0x0116, y    ); // Y
00301     usb_stk11xx_write_registry(dev, 0x0117, 1    );
00302     
00303     return 0;
00304 }
00305 
00306 
00319 int dev_stk0408_configure_device(struct usb_stk11xx *dev, int step)
00320 {
00321     int value;
00322     int asize;
00323     int i;
00324     
00325 
00326     static const int ids[] = {
00327         0x203,0x00d,0x00f,0x103,0x018,0x01b,0x01c,0x01a,0x019,
00328         0x300,0x350,0x351,0x352,0x353,0x300,0x018,0x202,0x110,
00329         0x111,0x112,0x113,0x114,0x115,0x116,0x117
00330     };
00331     
00332     const int values[] = {
00333         0x04a,0x000,0x002,0x000,0x000,0x00e,0x046,0x014,0x000,
00334         0x012,0x02d,0x001,0x000,0x000,0x080,0x010,0x00f,
00335         (dev->vsettings.norm ? 0x008 : 0x038),
00336         0x000,
00337         (dev->vsettings.norm ? 0x013 : 0x003),
00338         0x000,
00339         (dev->vsettings.norm ? 0x008 : 0x038),
00340         0x005,
00341         (dev->vsettings.norm ? 0x003 : 0x0f3),
00342         (dev->vsettings.norm ? 0x001 : 0x000)
00343     };
00344 
00345     if (step != 1)
00346     {
00347         usb_stk11xx_read_registry(dev, 0x0003, &value);
00348         usb_stk11xx_read_registry(dev, 0x0001, &value);
00349         usb_stk11xx_read_registry(dev, 0x0002, &value);
00350         usb_stk11xx_read_registry(dev, 0x0000, &value);
00351         usb_stk11xx_read_registry(dev, 0x0003, &value);
00352         usb_stk11xx_read_registry(dev, 0x0001, &value);
00353         usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
00354         usb_stk11xx_write_registry(dev, 0x0000, 0x0000);
00355         usb_stk11xx_write_registry(dev, 0x0003, 0x0080);
00356         usb_stk11xx_write_registry(dev, 0x0001, 0x0003);
00357 
00358         usb_stk11xx_read_registry(dev, 0x0002, &value);
00359         usb_stk11xx_read_registry(dev, 0x0000, &value);
00360         usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
00361         usb_stk11xx_read_registry(dev, 0x0000, &value);
00362         usb_stk11xx_read_registry(dev, 0x0002, &value);
00363         usb_stk11xx_read_registry(dev, 0x0000, &value);
00364         usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
00365         usb_stk11xx_write_registry(dev, 0x0000, 0x0030);
00366         usb_stk11xx_read_registry(dev, 0x0002, &value);
00367         usb_stk11xx_read_registry(dev, 0x0002, &value);
00368         usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
00369     }
00370     
00371     asize = ARRAY_SIZE(values);
00372     
00373     for(i=0; i<asize; i++) {
00374         usb_stk11xx_write_registry(dev, ids[i], values[i]);
00375     }
00376 
00377     if (step == 1)
00378     {
00379         usb_stk11xx_read_registry(dev, 0x0100, &value);
00380         usb_stk11xx_write_registry(dev, 0x0100, 0x0000);
00381     }
00382     else
00383     {
00384         usb_stk11xx_read_registry(dev, 0x0100, &value);
00385         usb_stk11xx_write_registry(dev, 0x0100, 0x0033);
00386     }
00387 
00388     if (step <=2 )
00389     {
00390         return 0;
00391     }
00392     
00393     if (step==3)
00394     {
00395         dev_stk0408_sensor_settings(dev);
00396     }
00397 
00398     usb_stk11xx_read_registry(dev, 0x0100, &value);
00399     usb_stk11xx_write_registry(dev, 0x0100, 0x0033);
00400     usb_stk11xx_write_registry(dev, 0x0103, 0x0000);
00401     usb_stk11xx_write_registry(dev, 0x0100, 0x0033);
00402 
00403     
00404     switch (step)
00405     {       
00406         case 3: /* all fine */
00407             usb_stk11xx_write_registry(dev, 0x0104, 0x0000);
00408             usb_stk11xx_write_registry(dev, 0x0105, 0x0000);
00409             usb_stk11xx_write_registry(dev, 0x0106, 0x0000);
00410 
00411             dev_stk11xx_camera_off(dev);
00412 
00413             usb_stk11xx_write_registry(dev, 0x0500, 0x0094);
00414             usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00415             usb_stk11xx_write_registry(dev, 0x0506, 0x0001);
00416             usb_stk11xx_write_registry(dev, 0x0507, 0x0000);
00417 
00418             break;
00419             
00420         case 5:
00421 /*          if ((dev->resolution == STK11XX_320x240)||
00422                 (dev->resolution == STK11XX_352x288))
00423             {
00424                 usb_stk11xx_write_registry(dev, 0x0104, 0x0000);
00425                 usb_stk11xx_write_registry(dev, 0x0105, 0x0000);
00426                 } */
00427         
00428             usb_stk11xx_write_registry(dev, 0x0106, 0x0000);
00429 
00430             dev_stk0408_write_saa(dev, 0x02, 0x80);
00431             dev_stk0408_write_208(dev,0x09);
00432             dev_stk0408_write_saa(dev, 0x09, 0x00);
00433 
00434             break;
00435     }
00436 
00437     if (step == 3)
00438     {
00439         dev_stk0408_write_saa(dev, 0x02, 0x80);
00440         dev_stk0408_write_208(dev,0x09);
00441         dev_stk0408_write_saa(dev, 0x09, 0x00);
00442 
00443         //test and set?
00444         usb_stk11xx_write_registry(dev, 0x0504, 0x0012);
00445         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00446         usb_stk11xx_write_registry(dev, 0x0504, 0x0012);
00447         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00448         usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
00449         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00450             
00451         usb_stk11xx_write_registry(dev, 0x0504, 0x0010);
00452         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00453         usb_stk11xx_write_registry(dev, 0x0504, 0x0010);
00454         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00455         usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
00456         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00457             
00458         usb_stk11xx_write_registry(dev, 0x0504, 0x000e);
00459         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00460         usb_stk11xx_write_registry(dev, 0x0504, 0x000e);
00461         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00462         usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
00463         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00464             
00465         usb_stk11xx_write_registry(dev, 0x0504, 0x0016);
00466         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00467         usb_stk11xx_write_registry(dev, 0x0504, 0x0016);
00468         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00469         usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
00470         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00471 
00472         usb_stk11xx_write_registry(dev, 0x0504, 0x001a);
00473         usb_stk11xx_write_registry(dev, 0x0502, 0x0004);
00474         usb_stk11xx_write_registry(dev, 0x0503, 0x0004);
00475         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00476 
00477         usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
00478         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00479         usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
00480         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00481         usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
00482         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00483     
00484         usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
00485         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00486         usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
00487         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00488         usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
00489         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);        
00490 
00491         dev_stk0408_write_saa(dev, 0x02, 0x80);
00492         dev_stk0408_write_208(dev,0x09);
00493         dev_stk0408_write_saa(dev, 0x09, 0x00);
00494 
00495     }
00496 
00497     if ((step == 4 )|| (step == 6))
00498     {
00499         dev_stk0408_write_saa(dev, 0x02, 0x80);
00500         dev_stk0408_write_208(dev,0x09);
00501         dev_stk0408_write_saa(dev, 0x09, 0x00);
00502         dev_stk0408_write_208(dev,0x0e);
00503         dev_stk0408_write_saa(dev, 0x0e, 0x01);
00504 
00505         dev_stk0408_set_resolution(dev);
00506             
00507         usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
00508         dev_stk0408_set_camera_quality(dev);
00509     }
00510 
00511     if (step == 6)
00512     {
00513         usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
00514 
00515         dev_stk0408_write_208(dev,0x0e);
00516         dev_stk0408_write_saa(dev, 0x0e, 0x01);
00517 
00518         dev_stk0408_set_resolution( dev);
00519 
00520         usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
00521 
00522         dev_stk0408_select_input(dev, dev->vsettings.input);
00523 
00524         dev_stk0408_start_stream(dev);
00525 
00526         usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
00527         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00528         usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
00529         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00530         usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
00531         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00532     
00533         usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
00534         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00535         usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
00536         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00537         usb_stk11xx_write_registry(dev, 0x0503, 0x0080);
00538         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);        
00539 
00540         usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
00541         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00542         usb_stk11xx_write_registry(dev, 0x0504, 0x0002);
00543         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00544         usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
00545         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00546     
00547         usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
00548         usb_stk11xx_write_registry(dev, 0x0500, 0x008b);
00549         usb_stk11xx_write_registry(dev, 0x0504, 0x001c);
00550         usb_stk11xx_write_registry(dev, 0x0502, 0x0000);
00551         usb_stk11xx_write_registry(dev, 0x0503, 0x0000);
00552         usb_stk11xx_write_registry(dev, 0x0500, 0x008c);
00553 
00554         dev_stk0408_start_stream(dev);
00555 
00556     }
00557 
00558     if (step==4)
00559     {   
00560         dev_stk11xx_camera_on(dev);
00561     }
00562     
00563     return 0;
00564 }
00565 
00566 
00567 int dev_stk0408_select_input(struct usb_stk11xx *dev, int input)
00568 {
00569     switch (input)
00570     {
00571         case 1:
00572             usb_stk11xx_write_registry(dev, 0x0000, 0x0098);
00573             break;
00574         case 2:
00575             usb_stk11xx_write_registry(dev, 0x0000, 0x0090);
00576             break;
00577         case 3:
00578             usb_stk11xx_write_registry(dev, 0x0000, 0x0088);
00579             break;
00580         case 4:
00581             usb_stk11xx_write_registry(dev, 0x0000, 0x0080);
00582             break;
00583     }
00584     usb_stk11xx_write_registry(dev, 0x0002, 0x0093);
00585 
00586     return 0;
00587     
00588 }
00589 
00590 
00600 int dev_stk0408_camera_asleep(struct usb_stk11xx *dev)
00601 {
00602     int value;
00603     int value0;
00604 
00605     usb_stk11xx_read_registry(dev, 0x0104, &value);
00606     usb_stk11xx_read_registry(dev, 0x0105, &value);
00607     usb_stk11xx_read_registry(dev, 0x0106, &value);
00608 
00609     usb_stk11xx_read_registry(dev, 0x0100, &value);
00610     
00611     value = value & 0x7f;
00612     usb_stk11xx_write_registry(dev, 0x0100, value);
00613 
00614     usb_stk11xx_write_registry(dev, 0x0116, 0x0000);
00615     usb_stk11xx_write_registry(dev, 0x0117, 0x0000);
00616     usb_stk11xx_write_registry(dev, 0x0018, 0x0000);
00617 
00618     usb_stk11xx_read_registry(dev, 0x0002, &value);
00619     usb_stk11xx_read_registry(dev, 0x0000, &value0);
00620     usb_stk11xx_write_registry(dev, 0x0002, value);
00621     usb_stk11xx_read_registry(dev, 0x0000, &value0);
00622 
00623     return 0;
00624 }
00625 
00626 
00637 int dev_stk0408_init_camera(struct usb_stk11xx *dev)
00638 {
00639     dev_stk0408_camera_asleep(dev);
00640 
00641     dev_stk0408_configure_device(dev, 3);
00642     dev_stk0408_configure_device(dev, 4);
00643     dev_stk0408_configure_device(dev, 5);
00644 
00645     dev_stk0408_configure_device(dev, 6);
00646     
00647     return 0;
00648 }
00649 
00650 int dev_stk0408_check_device(struct usb_stk11xx *dev)
00651 {
00652     int i;
00653     int value;
00654     const int retry=2;
00655     
00656     for (i=0; i < retry; i++) {
00657         usb_stk11xx_read_registry(dev, 0x201, &value);
00658 
00659 //writes to 204/204 return 4 on success
00660 //writes to 208 return 1 on success
00661 
00662         if (value == 0x04 || value == 0x01) 
00663             return 1;
00664 
00665         if (value != 0x00)
00666         {
00667             STK_ERROR("Check device return error (0x0201 = %02X) !\n", value);
00668             return -1;
00669         }
00670 //      msleep(10);
00671     }
00672     
00673     return 0;
00674 }           
00675 
00676 
00687 int dev_stk0408_sensor_settings(struct usb_stk11xx *dev)
00688 {
00689     int i;
00690     int retok;
00691     int asize;
00692     
00693 // PAL registers
00694     static const int registers[] = {
00695         0x01,0x03,0x04,0x05,0x06,0x07,0x08,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
00696         0x13,0x15,0x16,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,
00697         0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b };
00698 
00699     const int values[] = {
00700         0x08,0x33,0x00,0x00,0xe9,0x0d,
00701         (dev->vsettings.norm ? 0x38 : 0x78),
00702         0x80,0x47,0x40,0x00,0x01,0x2a,0x00,0x0c,0xe7,
00703         0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
00704         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0xff,0xff,0xff,0x40,0x54,
00705         (dev->vsettings.norm ? 0x07 : 0x0a),
00706         0x83 };
00707 
00708     asize = ARRAY_SIZE(values);
00709 
00710     for(i=0; i<asize; i++) {
00711         retok = dev_stk0408_write_saa(dev, registers[i], values[i]);
00712         
00713         if (retok != 1) {
00714             STK_ERROR("Load default sensor settings fail !\n");
00715             return -1;
00716         }
00717     }
00718     
00719     return 0;
00720 }
00721 
00722 
00736 int dev_stk0408_camera_settings(struct usb_stk11xx *dev)
00737 {
00738     dev_stk0408_set_camera_quality(dev);
00739 
00740     return 0;
00741 }
00742 
00743 
00752 int dev_stk0408_set_camera_quality(struct usb_stk11xx *dev)
00753 {
00754     usb_stk11xx_write_registry(dev, 0x0002, 0x0078);
00755 
00756 //brightness
00757     dev_stk0408_write_saa(dev, 0x0a, dev->vsettings.brightness >> 8); //80
00758 //contrast
00759     dev_stk0408_write_saa(dev, 0x0b, dev->vsettings.contrast >> 9); //40
00760 //hue
00761     dev_stk0408_write_saa(dev, 0x0d, (dev->vsettings.colour - 32768) >> 8); //00
00762 //saturation
00763     dev_stk0408_write_saa(dev, 0x0c, (dev->vsettings.hue) >> 9); //40
00764     
00765     STK_DEBUG("Set colour : %d\n", dev->vsettings.colour);
00766     STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast);
00767     STK_DEBUG("Set hue : %d\n", dev->vsettings.hue);
00768     STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness);
00769 
00770     return 1;
00771 }
00772 
00773 
00784 int dev_stk0408_set_camera_fps(struct usb_stk11xx *dev)
00785 {
00786     //Unknown, setting FPS seems to have no effect
00787     return 0;
00788 }
00789 
00790 
00801 int dev_stk0408_start_stream(struct usb_stk11xx *dev)
00802 {
00803     int value;
00804     int value_116, value_117;
00805 
00806     usb_stk11xx_read_registry(dev, 0x0116, &value_116);
00807     usb_stk11xx_read_registry(dev, 0x0117, &value_117);
00808 
00809     usb_stk11xx_write_registry(dev, 0x0116, 0x0000);
00810     usb_stk11xx_write_registry(dev, 0x0117, 0x0000);
00811 
00812     usb_stk11xx_read_registry(dev, 0x0100, &value);
00813     value |= 0x80;
00814     
00815 //  msleep(0x1f4);
00816     usb_stk11xx_write_registry(dev, 0x0100, value);
00817 //  msleep(0x64);
00818     
00819     usb_stk11xx_write_registry(dev, 0x0116, value_116);
00820     usb_stk11xx_write_registry(dev, 0x0117, value_117);
00821 
00822     return 0;
00823 }
00824 
00825 
00835 int dev_stk0408_reconf_camera(struct usb_stk11xx *dev)
00836 {
00837 
00838     dev_stk0408_configure_device(dev, 6);
00839 
00840     dev_stk11xx_camera_settings(dev);
00841 
00842     return 0;
00843 }
00844 
00845 
00856 int dev_stk0408_stop_stream(struct usb_stk11xx *dev)
00857 {
00858     int value;
00859 
00860     usb_stk11xx_read_registry(dev, 0x0100, &value);
00861     value &= 0x7f;
00862     usb_stk11xx_write_registry(dev, 0x0100, value);
00863     msleep(5);
00864     
00865     return 0;
00866 }
00867 
00868 /*
00869  * Needs some more work and optimisation!
00870  */
00871 void stk11xx_copy_uvyv(uint8_t *src, uint8_t *rgb,
00872                        struct stk11xx_coord *image,
00873                        struct stk11xx_coord *view,
00874                        const int hflip, const int vflip,
00875                        const int hfactor, const int vfactor,
00876                        bool order, bool field)
00877 {
00878     int width = image->x;
00879     int height = image->y;
00880     int x;
00881     int y;
00882 
00883     uint8_t *line1 = NULL;
00884     uint8_t *line2 = NULL;
00885     
00886     static uint8_t *prev=0;
00887     if (!prev)
00888         prev = rgb;
00889 
00890 //  printk("copy image %d - %d  %d,%d,%d\n", width, height, hfactor, vfactor, field);
00891         
00892 // vfactor=1 interlace rows
00893 // vfactor=2 full frame copy, duplicate rows
00894 // vfactor=4 half frame, copy rows
00895 
00896     if (field == false) // odd frame
00897     {
00898         prev += width * 2;
00899     }
00900             
00901     for ( y=0; y < height/2; y++)
00902     {
00903         if (vfactor == 1)
00904         {
00905             if (field == false) // odd frame
00906             {
00907                 line1 = rgb + (y*width*4);
00908                 line2 = rgb + (y*width*4) + width*2;
00909             }
00910             else
00911             {
00912                 line1 = rgb + (y*width*4) + width*2;
00913                 line2 = rgb + (y*width*4);
00914             }
00915         }
00916         else
00917         {
00918             line1 = rgb + (y*width*2);
00919         }
00920 
00921     
00922         if (order && hfactor == 1) //fast line copy with memcpy
00923         {
00924             memcpy(line1,src,width*2);
00925             src += width*2;
00926         }
00927         else //slow line copy with hscaling or YUV reorder
00928         {
00929             for ( x = 0; x < width*2; x+=4)
00930             {
00931                 if (order) //yuv order
00932                 {
00933                     line1[x] = src[0];
00934                     line1[x+1] = src[1];
00935                     line1[x+2] = src[2];
00936                     line1[x+3] = src[3];
00937                 }
00938                 else 
00939                 {
00940                     line1[x] = src[1];
00941                     line1[x+1] = src[0];
00942                     line1[x+2] = src[3];
00943                     line1[x+3] = src[2];
00944                 }
00945                 src += (4 * hfactor);
00946             }
00947         }
00948 
00949         if (vfactor == 1) //interlaced copy from previous frame
00950         {
00951             memcpy(line2,prev,width*2);
00952             prev += width*4;
00953         }
00954         else if (vfactor ==  2) //1 : 1
00955         {
00956         }
00957         else if (vfactor == 4) // 2 : 1
00958         {
00959             src += (width*2)*2;
00960         }
00961     }
00962     
00963     prev = rgb;
00964 }
00965 
00966 /*
00967  * needs more work and optimisation!
00968  * 
00969  * rgb is horribly slow but just written to check the image is working
00970  * replace with a proper yuv to rgb conversion
00971  */
00972 #define CLAMP(x) x < 0 ? 0 : x > 255 ? 255 : x
00973 
00974 void stk11xx_copy_rgb(uint8_t *src, uint8_t *rgb,
00975                       struct stk11xx_coord *image,
00976                       struct stk11xx_coord *view,
00977                       const int hflip, const int vflip,
00978                       const int hfactor, const int vfactor,
00979                       bool order, bool four, bool field)
00980 {
00981 
00982     int width = image->x;
00983     int height = image->y;
00984     int x;
00985     int y;
00986     int step;
00987 
00988     bool off = false;
00989     
00990     uint8_t *line1 = NULL;
00991     uint8_t *line2 = NULL;
00992 
00993     static uint8_t *prev=0;
00994     if (!prev)
00995         prev = rgb;
00996 
00997     step = four?4:3;
00998     
00999     if (field==false)
01000     {
01001         prev += width * step;
01002     }
01003     
01004     //uvyv
01005     for ( y=0; y < height/2; y++)
01006     {
01007         if (vfactor == 1)
01008         {
01009             if (field == false) // odd frame
01010             {//
01011                 line1 = rgb + (y * width * step * 2);
01012                 line2 = rgb + (y * width * step * 2) + width * step;
01013             }
01014             else
01015             {
01016                 line1 = rgb + (y * width * step * 2) + width * step;
01017                 line2 = rgb + (y * width * step * 2);
01018             }
01019         }
01020         else
01021         {
01022             line1 = rgb + (y * width * step);
01023         }
01024 
01025         off=false;
01026         for ( x = 0; x < width*step; x+=step)
01027         {
01028 /*
01029   C = Y - 16
01030   D = U - 128
01031   E = V - 128
01032 
01033   R = clip(( 298 * C           + 409 * E + 128) >> 8)
01034   G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
01035   B = clip(( 298 * C + 516 * D           + 128) >> 8)
01036 */
01037             int c = src[off ? 3 : 1];
01038             int d = src[0] - 128;
01039             int e = src[2] - 128;
01040             
01041             int R = ((298*c + 409 * e + 128) >>8);
01042             int G = ((298*c - 100 * d - 208 * e + 128)>>8);
01043             int B = ((298*c + 516 * d + 128)>>8);
01044             
01045             R = CLAMP(R);
01046             G = CLAMP(G);
01047             B = CLAMP(B);
01048             
01049             if (order)
01050             {
01051                 line1[x] = B;
01052                 line1[x+1] = G;
01053                 line1[x+2] = R;
01054             }
01055             else
01056             {
01057                 line1[x] = R;
01058                 line1[x+1] = G;
01059                 line1[x+2] = B;
01060             }
01061             if (four)
01062                 line1[x+3] = 0;
01063 
01064             if (off)
01065             {
01066                 src += (4 * hfactor);
01067                 off = false;
01068             }
01069             else
01070             {
01071                 off = true;
01072             }
01073             
01074         }   
01075         
01076         
01077         if (vfactor == 1) //interlaced copy from previous frame
01078         {
01079             for ( x = 0; x < width * step; x++ )
01080             {
01081                 line2[x] = (*prev++); //line1[x];
01082             }
01083             prev += width * step;
01084         }
01085     }
01086     
01087     prev = rgb;
01088 }
01089 
01090 
01091 int dev_stk0408_decode(struct usb_stk11xx *dev)
01092 {
01093     void *data;
01094     void *image;
01095 
01096     int vfactor;
01097     int hfactor;
01098     bool odd;
01099     
01100     struct stk11xx_frame_buf *framebuf;
01101     
01102     if (dev == NULL)
01103         return -EFAULT;
01104     
01105     framebuf = dev->read_frame;
01106 
01107     if (framebuf == NULL)
01108         return -EFAULT;
01109     
01110     image  = dev->image_data;
01111     STK_DEBUG("fill image %d\n", dev->fill_image);
01112     
01113     image += dev->images[dev->fill_image].offset;
01114 
01115     data = framebuf->data;
01116     odd = framebuf->odd;
01117     
01118     switch (dev->resolution) {
01119 
01120 /* 
01121 //Currently only 1:1 resolutions are working
01122         case STK11XX_160x120:
01123         case STK11XX_176x144:
01124             hfactor = 4;
01125             vfactor = 4;
01126             break;
01127             
01128         case STK11XX_320x240:
01129         case STK11XX_352x240:
01130         case STK11XX_352x288:
01131             hfactor = 2;
01132             vfactor = 2;
01133             break;
01134 */      
01135         case STK11XX_640x480:
01136 /*      case STK11XX_720x480:*/
01137         case STK11XX_720x576:
01138             hfactor = 1;
01139             vfactor = 1;
01140             break;
01141 
01142         default:
01143             return -EFAULT;
01144     }
01145 
01146     switch (dev->vsettings.palette) {
01147         case STK11XX_PALETTE_RGB24:
01148             stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, false,false,odd);
01149             break;
01150         case STK11XX_PALETTE_RGB32:
01151             stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, false,true,odd);
01152             break;
01153         case STK11XX_PALETTE_BGR24:
01154             stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, true,false,odd);
01155             break;
01156         case STK11XX_PALETTE_BGR32:
01157             stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, true,true,odd);
01158             break;
01159 
01160         case STK11XX_PALETTE_UYVY:
01161             stk11xx_copy_uvyv(data, image, &dev->image, &dev->view,dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, true,odd);
01162             break;
01163         case STK11XX_PALETTE_YUYV:
01164             stk11xx_copy_uvyv(data, image, &dev->image, &dev->view,dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, false,odd);
01165             break;
01166     }
01167 
01168     return 0;
01169     
01170 }
01171