Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / easycap / easycap_low.c
1 /*****************************************************************************
2 *                                                                            *
3 *                                                                            *
4 *  easycap_low.c                                                             *
5 *                                                                            *
6 *                                                                            *
7 *****************************************************************************/
8 /*
9  *
10  *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
11  *
12  *
13  *  This is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  The software is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this software; if not, write to the Free Software
25  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27 */
28 /*****************************************************************************/
29 /*
30  *  ACKNOWLEGEMENTS AND REFERENCES
31  *  ------------------------------
32  *  This driver makes use of register information contained in the Syntek
33  *  Semicon DC-1125 driver hosted at
34  *               http://sourceforge.net/projects/syntekdriver/.
35  *  Particularly useful has been a patch to the latter driver provided by
36  *  Ivor Hewitt in January 2009.  The NTSC implementation is taken from the
37  *  work of Ben Trask.
38 */
39 /****************************************************************************/
40
41 #include "easycap.h"
42 #include "easycap_debug.h"
43
44 /*--------------------------------------------------------------------------*/
45 const struct stk1160config { int reg; int set; } stk1160configPAL[256] = {
46                 {0x000, 0x0098},
47                 {0x002, 0x0093},
48
49                 {0x001, 0x0003},
50                 {0x003, 0x0080},
51                 {0x00D, 0x0000},
52                 {0x00F, 0x0002},
53                 {0x018, 0x0010},
54                 {0x019, 0x0000},
55                 {0x01A, 0x0014},
56                 {0x01B, 0x000E},
57                 {0x01C, 0x0046},
58
59                 {0x100, 0x0033},
60                 {0x103, 0x0000},
61                 {0x104, 0x0000},
62                 {0x105, 0x0000},
63                 {0x106, 0x0000},
64
65 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
66 /*
67  *  RESOLUTION 640x480
68 */
69 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
70                 {0x110, 0x0008},
71                 {0x111, 0x0000},
72                 {0x112, 0x0020},
73                 {0x113, 0x0000},
74                 {0x114, 0x0508},
75                 {0x115, 0x0005},
76                 {0x116, 0x0110},
77                 {0x117, 0x0001},
78 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
79
80                 {0x202, 0x000F},
81                 {0x203, 0x004A},
82                 {0x2FF, 0x0000},
83
84                 {0xFFF, 0xFFFF}
85 };
86 /*--------------------------------------------------------------------------*/
87 const struct stk1160config stk1160configNTSC[256] = {
88                 {0x000, 0x0098},
89                 {0x002, 0x0093},
90
91                 {0x001, 0x0003},
92                 {0x003, 0x0080},
93                 {0x00D, 0x0000},
94                 {0x00F, 0x0002},
95                 {0x018, 0x0010},
96                 {0x019, 0x0000},
97                 {0x01A, 0x0014},
98                 {0x01B, 0x000E},
99                 {0x01C, 0x0046},
100
101                 {0x100, 0x0033},
102                 {0x103, 0x0000},
103                 {0x104, 0x0000},
104                 {0x105, 0x0000},
105                 {0x106, 0x0000},
106
107 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
108 /*
109  *  RESOLUTION 640x480
110 */
111 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
112                 {0x110, 0x0008},
113                 {0x111, 0x0000},
114                 {0x112, 0x0003},
115                 {0x113, 0x0000},
116                 {0x114, 0x0508},
117                 {0x115, 0x0005},
118                 {0x116, 0x00F3},
119                 {0x117, 0x0000},
120 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
121
122                 {0x202, 0x000F},
123                 {0x203, 0x004A},
124                 {0x2FF, 0x0000},
125
126                 {0xFFF, 0xFFFF}
127 };
128 /*--------------------------------------------------------------------------*/
129 const struct saa7113config { int reg; int set; } saa7113configPAL[256] = {
130                 {0x01, 0x08},
131 #if defined(ANTIALIAS)
132                 {0x02, 0xC0},
133 #else
134                 {0x02, 0x80},
135 #endif /*ANTIALIAS*/
136                 {0x03, 0x33},
137                 {0x04, 0x00},
138                 {0x05, 0x00},
139                 {0x06, 0xE9},
140                 {0x07, 0x0D},
141                 {0x08, 0x38},
142                 {0x09, 0x00},
143                 {0x0A, SAA_0A_DEFAULT},
144                 {0x0B, SAA_0B_DEFAULT},
145                 {0x0C, SAA_0C_DEFAULT},
146                 {0x0D, SAA_0D_DEFAULT},
147                 {0x0E, 0x01},
148                 {0x0F, 0x36},
149                 {0x10, 0x00},
150                 {0x11, 0x0C},
151                 {0x12, 0xE7},
152                 {0x13, 0x00},
153                 {0x15, 0x00},
154                 {0x16, 0x00},
155                 {0x40, 0x02},
156                 {0x41, 0xFF},
157                 {0x42, 0xFF},
158                 {0x43, 0xFF},
159                 {0x44, 0xFF},
160                 {0x45, 0xFF},
161                 {0x46, 0xFF},
162                 {0x47, 0xFF},
163                 {0x48, 0xFF},
164                 {0x49, 0xFF},
165                 {0x4A, 0xFF},
166                 {0x4B, 0xFF},
167                 {0x4C, 0xFF},
168                 {0x4D, 0xFF},
169                 {0x4E, 0xFF},
170                 {0x4F, 0xFF},
171                 {0x50, 0xFF},
172                 {0x51, 0xFF},
173                 {0x52, 0xFF},
174                 {0x53, 0xFF},
175                 {0x54, 0xFF},
176                 {0x55, 0xFF},
177                 {0x56, 0xFF},
178                 {0x57, 0xFF},
179                 {0x58, 0x40},
180                 {0x59, 0x54},
181                 {0x5A, 0x07},
182                 {0x5B, 0x83},
183
184                 {0xFF, 0xFF}
185 };
186 /*--------------------------------------------------------------------------*/
187 const struct saa7113config saa7113configNTSC[256] = {
188                 {0x01, 0x08},
189 #if defined(ANTIALIAS)
190                 {0x02, 0xC0},
191 #else
192                 {0x02, 0x80},
193 #endif /*ANTIALIAS*/
194                 {0x03, 0x33},
195                 {0x04, 0x00},
196                 {0x05, 0x00},
197                 {0x06, 0xE9},
198                 {0x07, 0x0D},
199                 {0x08, 0x78},
200                 {0x09, 0x00},
201                 {0x0A, SAA_0A_DEFAULT},
202                 {0x0B, SAA_0B_DEFAULT},
203                 {0x0C, SAA_0C_DEFAULT},
204                 {0x0D, SAA_0D_DEFAULT},
205                 {0x0E, 0x01},
206                 {0x0F, 0x36},
207                 {0x10, 0x00},
208                 {0x11, 0x0C},
209                 {0x12, 0xE7},
210                 {0x13, 0x00},
211                 {0x15, 0x00},
212                 {0x16, 0x00},
213                 {0x40, 0x82},
214                 {0x41, 0xFF},
215                 {0x42, 0xFF},
216                 {0x43, 0xFF},
217                 {0x44, 0xFF},
218                 {0x45, 0xFF},
219                 {0x46, 0xFF},
220                 {0x47, 0xFF},
221                 {0x48, 0xFF},
222                 {0x49, 0xFF},
223                 {0x4A, 0xFF},
224                 {0x4B, 0xFF},
225                 {0x4C, 0xFF},
226                 {0x4D, 0xFF},
227                 {0x4E, 0xFF},
228                 {0x4F, 0xFF},
229                 {0x50, 0xFF},
230                 {0x51, 0xFF},
231                 {0x52, 0xFF},
232                 {0x53, 0xFF},
233                 {0x54, 0xFF},
234                 {0x55, 0xFF},
235                 {0x56, 0xFF},
236                 {0x57, 0xFF},
237                 {0x58, 0x40},
238                 {0x59, 0x54},
239                 {0x5A, 0x0A},
240                 {0x5B, 0x83},
241
242                 {0xFF, 0xFF}
243 };
244 /*--------------------------------------------------------------------------*/
245
246 /****************************************************************************/
247 int
248 confirm_resolution(struct usb_device *p)
249 {
250 __u8 get0, get1, get2, get3, get4, get5, get6, get7;
251
252 if (NULL == p)
253         return -ENODEV;
254 GET(p, 0x0110, &get0);
255 GET(p, 0x0111, &get1);
256 GET(p, 0x0112, &get2);
257 GET(p, 0x0113, &get3);
258 GET(p, 0x0114, &get4);
259 GET(p, 0x0115, &get5);
260 GET(p, 0x0116, &get6);
261 GET(p, 0x0117, &get7);
262 JOT(8,  "0x%03X, 0x%03X, " \
263         "0x%03X, 0x%03X, " \
264         "0x%03X, 0x%03X, " \
265         "0x%03X, 0x%03X\n", \
266         get0, get1, get2, get3, get4, get5, get6, get7);
267 JOT(8,  "....cf PAL_720x526: " \
268         "0x%03X, 0x%03X, " \
269         "0x%03X, 0x%03X, " \
270         "0x%03X, 0x%03X, " \
271         "0x%03X, 0x%03X\n", \
272         0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001);
273 JOT(8,  "....cf PAL_704x526: " \
274         "0x%03X, 0x%03X, " \
275         "0x%03X, 0x%03X, " \
276         "0x%03X, 0x%03X, " \
277         "0x%03X, 0x%03X\n", \
278         0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001);
279 JOT(8,  "....cf VGA_640x480: " \
280         "0x%03X, 0x%03X, " \
281         "0x%03X, 0x%03X, " \
282         "0x%03X, 0x%03X, " \
283         "0x%03X, 0x%03X\n", \
284         0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001);
285 return 0;
286 }
287 /****************************************************************************/
288 int
289 confirm_stream(struct usb_device *p)
290 {
291 __u16 get2;
292 __u8 igot;
293
294 if (NULL == p)
295         return -ENODEV;
296 GET(p, 0x0100, &igot);  get2 = 0x80 & igot;
297 if (0x80 == get2)
298         JOT(8, "confirm_stream:  OK\n");
299 else
300         JOT(8, "confirm_stream:  STUCK\n");
301 return 0;
302 }
303 /****************************************************************************/
304 int
305 setup_stk(struct usb_device *p, bool ntsc)
306 {
307 int i0;
308
309 if (NULL == p)
310         return -ENODEV;
311 i0 = 0;
312 if (true == ntsc) {
313         while (0xFFF != stk1160configNTSC[i0].reg) {
314                 SET(p, stk1160configNTSC[i0].reg, stk1160configNTSC[i0].set);
315                 i0++;
316         }
317 } else {
318         while (0xFFF != stk1160configPAL[i0].reg) {
319                 SET(p, stk1160configPAL[i0].reg, stk1160configPAL[i0].set);
320                 i0++;
321         }
322 }
323
324 write_300(p);
325
326 return 0;
327 }
328 /****************************************************************************/
329 int
330 setup_saa(struct usb_device *p, bool ntsc)
331 {
332 int i0, ir;
333
334 if (NULL == p)
335         return -ENODEV;
336 i0 = 0;
337 if (true == ntsc) {
338         while (0xFF != saa7113configNTSC[i0].reg) {
339                 ir = write_saa(p, saa7113configNTSC[i0].reg, \
340                                         saa7113configNTSC[i0].set);
341                 i0++;
342         }
343 } else {
344         while (0xFF != saa7113configPAL[i0].reg) {
345                 ir = write_saa(p, saa7113configPAL[i0].reg, \
346                                         saa7113configPAL[i0].set);
347                 i0++;
348         }
349 }
350 return 0;
351 }
352 /****************************************************************************/
353 int
354 write_000(struct usb_device *p, __u16 set2, __u16 set0)
355 {
356 __u8 igot0, igot2;
357
358 if (NULL == p)
359         return -ENODEV;
360 GET(p, 0x0002, &igot2);
361 GET(p, 0x0000, &igot0);
362 SET(p, 0x0002, set2);
363 SET(p, 0x0000, set0);
364 return 0;
365 }
366 /****************************************************************************/
367 int
368 write_saa(struct usb_device *p, __u16 reg0, __u16 set0)
369 {
370 if (NULL == p)
371         return -ENODEV;
372 SET(p, 0x200, 0x00);
373 SET(p, 0x204, reg0);
374 SET(p, 0x205, set0);
375 SET(p, 0x200, 0x01);
376 return wait_i2c(p);
377 }
378 /****************************************************************************/
379 /*--------------------------------------------------------------------------*/
380 /*
381  *  REGISTER 500:  SETTING VALUE TO 0x008B READS FROM VT1612A (?)
382  *  REGISTER 500:  SETTING VALUE TO 0x008C WRITES TO  VT1612A
383  *  REGISTER 502:  LEAST SIGNIFICANT BYTE OF VALUE TO SET
384  *  REGISTER 503:  MOST SIGNIFICANT BYTE OF VALUE TO SET
385  *  REGISTER 504:  TARGET ADDRESS ON VT1612A
386  */
387 /*--------------------------------------------------------------------------*/
388 int
389 write_vt(struct usb_device *p, __u16 reg0, __u16 set0)
390 {
391 __u8 igot;
392 __u16 got502, got503;
393 __u16 set502, set503;
394
395 if (NULL == p)
396         return -ENODEV;
397 SET(p, 0x0504, reg0);
398 SET(p, 0x0500, 0x008B);
399
400 GET(p, 0x0502, &igot);  got502 = (0xFF & igot);
401 GET(p, 0x0503, &igot);  got503 = (0xFF & igot);
402
403 JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", \
404                                         reg0, set0, ((got503 << 8) | got502));
405
406 set502 =  (0x00FF & set0);
407 set503 = ((0xFF00 & set0) >> 8);
408
409 SET(p, 0x0504, reg0);
410 SET(p, 0x0502, set502);
411 SET(p, 0x0503, set503);
412 SET(p, 0x0500, 0x008C);
413
414 return 0;
415 }
416 /****************************************************************************/
417 /*--------------------------------------------------------------------------*/
418 /*
419  *  REGISTER 500:  SETTING VALUE TO 0x008B READS FROM VT1612A (?)
420  *  REGISTER 500:  SETTING VALUE TO 0x008C WRITES TO  VT1612A
421  *  REGISTER 502:  LEAST SIGNIFICANT BYTE OF VALUE TO GET
422  *  REGISTER 503:  MOST SIGNIFICANT BYTE OF VALUE TO GET
423  *  REGISTER 504:  TARGET ADDRESS ON VT1612A
424  */
425 /*--------------------------------------------------------------------------*/
426 int
427 read_vt(struct usb_device *p, __u16 reg0)
428 {
429 __u8 igot;
430 __u16 got502, got503;
431
432 if (NULL == p)
433         return -ENODEV;
434 SET(p, 0x0504, reg0);
435 SET(p, 0x0500, 0x008B);
436
437 GET(p, 0x0502, &igot);  got502 = (0xFF & igot);
438 GET(p, 0x0503, &igot);  got503 = (0xFF & igot);
439
440 JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", reg0, ((got503 << 8) | got502));
441
442 return (got503 << 8) | got502;
443 }
444 /****************************************************************************/
445 /*--------------------------------------------------------------------------*/
446 /*
447  *  THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
448  */
449 /*--------------------------------------------------------------------------*/
450 int
451 write_300(struct usb_device *p)
452 {
453 if (NULL == p)
454         return -ENODEV;
455 SET(p, 0x300, 0x0012);
456 SET(p, 0x350, 0x002D);
457 SET(p, 0x351, 0x0001);
458 SET(p, 0x352, 0x0000);
459 SET(p, 0x353, 0x0000);
460 SET(p, 0x300, 0x0080);
461 return 0;
462 }
463 /****************************************************************************/
464 /*--------------------------------------------------------------------------*/
465 /*
466  *  NOTE: THE FOLLOWING IS NOT CHECKED:
467  *  REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL.
468  */
469 /*--------------------------------------------------------------------------*/
470 int
471 check_saa(struct usb_device *p, bool ntsc)
472 {
473 int i0, ir, rc;
474
475 if (NULL == p)
476         return -ENODEV;
477 i0 = 0;
478 rc = 0;
479 if (true == ntsc) {
480         while (0xFF != saa7113configNTSC[i0].reg) {
481                 if (0x0F == saa7113configNTSC[i0].reg) {
482                         i0++;
483                         continue;
484                 }
485
486                 ir = read_saa(p, saa7113configNTSC[i0].reg);
487                 if (ir != saa7113configNTSC[i0].set) {
488                         SAY("SAA register 0x%02X has 0x%02X, " \
489                                                 "expected 0x%02X\n", \
490                                                 saa7113configNTSC[i0].reg, \
491                                                 ir, saa7113configNTSC[i0].set);
492                         rc--;
493                 }
494                 i0++;
495         }
496 } else {
497         while (0xFF != saa7113configPAL[i0].reg) {
498                 if (0x0F == saa7113configPAL[i0].reg) {
499                         i0++;
500                         continue;
501                 }
502
503                 ir = read_saa(p, saa7113configPAL[i0].reg);
504                 if (ir != saa7113configPAL[i0].set) {
505                         SAY("SAA register 0x%02X has 0x%02X, " \
506                                                 "expected 0x%02X\n", \
507                                                 saa7113configPAL[i0].reg, \
508                                                 ir, saa7113configPAL[i0].set);
509                         rc--;
510                 }
511                 i0++;
512         }
513 }
514 if (-8 > rc)
515         return rc;
516 else
517         return 0;
518 }
519 /****************************************************************************/
520 int
521 merit_saa(struct usb_device *p)
522 {
523 int rc;
524
525 if (NULL == p)
526         return -ENODEV;
527 rc = read_saa(p, 0x1F);
528 if ((0 > rc) || (0x02 & rc))
529         return 1 ;
530 else
531         return 0;
532 }
533 /****************************************************************************/
534 int
535 ready_saa(struct usb_device *p)
536 {
537 int j, rc, rate;
538 const int max = 5, marktime = PATIENCE/5;
539 /*--------------------------------------------------------------------------*/
540 /*
541  *   RETURNS    0     FOR INTERLACED       50 Hz
542  *              1     FOR NON-INTERLACED   50 Hz
543  *              2     FOR INTERLACED       60 Hz
544  *              3     FOR NON-INTERLACED   60 Hz
545 */
546 /*--------------------------------------------------------------------------*/
547 if (NULL == p)
548         return -ENODEV;
549 j = 0;
550 while (max > j) {
551         rc = read_saa(p, 0x1F);
552         if (0 <= rc) {
553                 if (0 == (0x40 & rc))
554                         break;
555                 if (1 == (0x01 & rc))
556                         break;
557         }
558         msleep(marktime);
559         j++;
560 }
561 if (max == j)
562         return -1;
563 else {
564         if (0x20 & rc) {
565                 rate = 2;
566                 JOT(8, "hardware detects 60 Hz\n");
567         } else {
568                 rate = 0;
569                 JOT(8, "hardware detects 50 Hz\n");
570         }
571         if (0x80 & rc)
572                 JOT(8, "hardware detects interlacing\n");
573         else {
574                 rate++;
575                 JOT(8, "hardware detects no interlacing\n");
576         }
577 }
578 return 0;
579 }
580 /****************************************************************************/
581 /*--------------------------------------------------------------------------*/
582 /*
583  *  NOTE: THE FOLLOWING ARE NOT CHECKED:
584  *  REGISTERS 0x000, 0x002:  FUNCTIONALITY IS NOT KNOWN
585  *  REGISTER  0x100:  ACCEPT ALSO (0x80 | stk1160config....[.].set)
586  */
587 /*--------------------------------------------------------------------------*/
588 int
589 check_stk(struct usb_device *p, bool ntsc)
590 {
591 int i0, ir;
592
593 if (NULL == p)
594         return -ENODEV;
595 i0 = 0;
596 if (true == ntsc) {
597         while (0xFFF != stk1160configNTSC[i0].reg) {
598                 if (0x000 == stk1160configNTSC[i0].reg) {
599                         i0++; continue;
600                 }
601                 if (0x002 == stk1160configNTSC[i0].reg) {
602                         i0++; continue;
603                 }
604                 ir = read_stk(p, stk1160configNTSC[i0].reg);
605                 if (0x100 == stk1160configNTSC[i0].reg) {
606                         if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \
607                                         (ir != (0x80 | (0xFF & \
608                                         stk1160configNTSC[i0].set))) && \
609                                         (0xFFFF != \
610                                         stk1160configNTSC[i0].set)) {
611                                 SAY("STK register 0x%03X has 0x%02X, " \
612                                                 "expected 0x%02X\n", \
613                                                 stk1160configNTSC[i0].reg, \
614                                                 ir, stk1160configNTSC[i0].set);
615                                 }
616                         i0++; continue;
617                         }
618                 if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \
619                                 (0xFFFF != stk1160configNTSC[i0].set)) {
620                         SAY("STK register 0x%03X has 0x%02X, " \
621                                                 "expected 0x%02X\n", \
622                                                 stk1160configNTSC[i0].reg, \
623                                                 ir, stk1160configNTSC[i0].set);
624                 }
625                 i0++;
626         }
627 } else {
628         while (0xFFF != stk1160configPAL[i0].reg) {
629                 if (0x000 == stk1160configPAL[i0].reg) {
630                         i0++; continue;
631                 }
632                 if (0x002 == stk1160configPAL[i0].reg) {
633                         i0++; continue;
634                 }
635                 ir = read_stk(p, stk1160configPAL[i0].reg);
636                 if (0x100 == stk1160configPAL[i0].reg) {
637                         if ((ir != (0xFF & stk1160configPAL[i0].set)) && \
638                                         (ir != (0x80 | (0xFF & \
639                                         stk1160configPAL[i0].set))) && \
640                                         (0xFFFF != \
641                                         stk1160configPAL[i0].set)) {
642                                 SAY("STK register 0x%03X has 0x%02X, " \
643                                                 "expected 0x%02X\n", \
644                                                 stk1160configPAL[i0].reg, \
645                                                 ir, stk1160configPAL[i0].set);
646                                 }
647                         i0++; continue;
648                         }
649                 if ((ir != (0xFF & stk1160configPAL[i0].set)) && \
650                                 (0xFFFF != stk1160configPAL[i0].set)) {
651                         SAY("STK register 0x%03X has 0x%02X, " \
652                                                 "expected 0x%02X\n", \
653                                                 stk1160configPAL[i0].reg, \
654                                                 ir, stk1160configPAL[i0].set);
655                 }
656                 i0++;
657         }
658 }
659 return 0;
660 }
661 /****************************************************************************/
662 int
663 read_saa(struct usb_device *p, __u16 reg0)
664 {
665 __u8 igot;
666
667 if (NULL == p)
668         return -ENODEV;
669 SET(p, 0x208, reg0);
670 SET(p, 0x200, 0x20);
671 if (0 != wait_i2c(p))
672         return -1;
673 igot = 0;
674 GET(p, 0x0209, &igot);
675 return igot;
676 }
677 /****************************************************************************/
678 int
679 read_stk(struct usb_device *p, __u32 reg0)
680 {
681 __u8 igot;
682
683 if (NULL == p)
684         return -ENODEV;
685 igot = 0;
686 GET(p, reg0, &igot);
687 return igot;
688 }
689 /****************************************************************************/
690 /*--------------------------------------------------------------------------*/
691 /*
692  *    HARDWARE    USERSPACE INPUT NUMBER   PHYSICAL INPUT   DRIVER input VALUE
693  *
694  *  CVBS+S-VIDEO           0 or 1              CVBS                 1
695  *   FOUR-CVBS             0 or 1              CVBS1                1
696  *   FOUR-CVBS                2                CVBS2                2
697  *   FOUR-CVBS                3                CVBS3                3
698  *   FOUR-CVBS                4                CVBS4                4
699  *  CVBS+S-VIDEO              5               S-VIDEO               5
700  *
701  *  WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED:
702  *
703  *     mode  7   => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED)
704  *     mode  9   => USE AUTOMATIC GAIN CONTROL (DEFAULT)
705  *
706 */
707 /*---------------------------------------------------------------------------*/
708 int
709 select_input(struct usb_device *p, int input, int mode)
710 {
711 int ir;
712
713 if (NULL == p)
714         return -ENODEV;
715 stop_100(p);
716 switch (input) {
717 case 0:
718 case 1: {
719         if (0 != write_saa(p, 0x02, 0x80)) {
720                 SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
721                                                                         input);
722         }
723         SET(p, 0x0000, 0x0098);
724         SET(p, 0x0002, 0x0078);
725         break;
726 }
727 case 2: {
728         if (0 != write_saa(p, 0x02, 0x80)) {
729                 SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
730                                                                         input);
731         }
732         SET(p, 0x0000, 0x0090);
733         SET(p, 0x0002, 0x0078);
734         break;
735 }
736 case 3: {
737         if (0 != write_saa(p, 0x02, 0x80)) {
738                 SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
739                                                                         input);
740         }
741         SET(p, 0x0000, 0x0088);
742         SET(p, 0x0002, 0x0078);
743         break;
744 }
745 case 4: {
746         if (0 != write_saa(p, 0x02, 0x80)) {
747                 SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
748                                                                         input);
749         }
750         SET(p, 0x0000, 0x0080);
751         SET(p, 0x0002, 0x0078);
752         break;
753 }
754 case 5: {
755         if (9 != mode)
756                 mode = 7;
757         switch (mode) {
758         case 7: {
759                 if (0 != write_saa(p, 0x02, 0x87)) {
760                         SAY("ERROR: failed to set SAA register 0x02 " \
761                                                 "for input %i\n", input);
762                 }
763                 if (0 != write_saa(p, 0x05, 0xFF)) {
764                         SAY("ERROR: failed to set SAA register 0x05 " \
765                                                 "for input %i\n", input);
766                 }
767                 break;
768         }
769         case 9: {
770                 if (0 != write_saa(p, 0x02, 0x89)) {
771                         SAY("ERROR: failed to set SAA register 0x02 " \
772                                                 "for input %i\n", input);
773                 }
774                 if (0 != write_saa(p, 0x05, 0x00)) {
775                         SAY("ERROR: failed to set SAA register 0x05 " \
776                                                 "for input %i\n", input);
777                 }
778         break;
779         }
780         default: {
781                 SAY("MISTAKE:  bad mode: %i\n", mode);
782                 return -1;
783         }
784         }
785         if (0 != write_saa(p, 0x04, 0x00)) {
786                 SAY("ERROR: failed to set SAA register 0x04 for input %i\n", \
787                                                                         input);
788         }
789         if (0 != write_saa(p, 0x09, 0x80)) {
790                 SAY("ERROR: failed to set SAA register 0x09 for input %i\n", \
791                                                                         input);
792         }
793         SET(p, 0x0002, 0x0093);
794         break;
795 }
796 default: {
797         SAY("ERROR:  bad input: %i\n", input);
798         return -1;
799 }
800 }
801 ir = read_stk(p, 0x00);
802 JOT(8, "STK register 0x00 has 0x%02X\n", ir);
803 ir = read_saa(p, 0x02);
804 JOT(8, "SAA register 0x02 has 0x%02X\n", ir);
805
806 start_100(p);
807
808 return 0;
809 }
810 /****************************************************************************/
811 int
812 set_resolution(struct usb_device *p, \
813                                 __u16 set0, __u16 set1, __u16 set2, __u16 set3)
814 {
815 __u16 u0x0111, u0x0113, u0x0115, u0x0117;
816
817 if (NULL == p)
818         return -ENODEV;
819 u0x0111 = ((0xFF00 & set0) >> 8);
820 u0x0113 = ((0xFF00 & set1) >> 8);
821 u0x0115 = ((0xFF00 & set2) >> 8);
822 u0x0117 = ((0xFF00 & set3) >> 8);
823
824 SET(p, 0x0110, (0x00FF & set0));
825 SET(p, 0x0111, u0x0111);
826 SET(p, 0x0112, (0x00FF & set1));
827 SET(p, 0x0113, u0x0113);
828 SET(p, 0x0114, (0x00FF & set2));
829 SET(p, 0x0115, u0x0115);
830 SET(p, 0x0116, (0x00FF & set3));
831 SET(p, 0x0117, u0x0117);
832
833 return 0;
834 }
835 /****************************************************************************/
836 int
837 start_100(struct usb_device *p)
838 {
839 __u16 get116, get117, get0;
840 __u8 igot116, igot117, igot;
841
842 if (NULL == p)
843         return -ENODEV;
844 GET(p, 0x0116, &igot116);
845 get116 = igot116;
846 GET(p, 0x0117, &igot117);
847 get117 = igot117;
848 SET(p, 0x0116, 0x0000);
849 SET(p, 0x0117, 0x0000);
850
851 GET(p, 0x0100, &igot);
852 get0 = igot;
853 SET(p, 0x0100, (0x80 | get0));
854
855 SET(p, 0x0116, get116);
856 SET(p, 0x0117, get117);
857
858 return 0;
859 }
860 /****************************************************************************/
861 int
862 stop_100(struct usb_device *p)
863 {
864 __u16 get0;
865 __u8 igot;
866
867 if (NULL == p)
868         return -ENODEV;
869 GET(p, 0x0100, &igot);
870 get0 = igot;
871 SET(p, 0x0100, (0x7F & get0));
872 return 0;
873 }
874 /****************************************************************************/
875 /*--------------------------------------------------------------------------*/
876 /*
877  *  FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
878 */
879 /*--------------------------------------------------------------------------*/
880 int
881 wait_i2c(struct usb_device *p)
882 {
883 __u16 get0;
884 __u8 igot;
885 const int max = 2;
886 int k;
887
888 if (NULL == p)
889         return -ENODEV;
890 for (k = 0;  k < max;  k++) {
891         GET(p, 0x0201, &igot);  get0 = igot;
892         switch (get0) {
893         case 0x04:
894         case 0x01: {
895                 return 0;
896         }
897         case 0x00: {
898                 msleep(20);
899                 continue;
900         }
901         default: {
902                 return get0 - 1;
903         }
904         }
905 }
906 return -1;
907 }
908 /****************************************************************************/
909 int
910 regset(struct usb_device *pusb_device, __u16 index, __u16 value)
911 {
912 __u16 igot;
913 int rc0, rc1;
914
915 if (!pusb_device)
916         return -ENODEV;
917 rc1 = 0;  igot = 0;
918 rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \
919                 (__u8)0x01, \
920                 (__u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
921                 (__u16)value, \
922                 (__u16)index, \
923                 (void *)NULL, \
924                 (__u16)0, \
925                 (int)500);
926
927 #if defined(NOREADBACK)
928 #
929 #else
930 rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \
931                 (__u8)0x00, \
932                 (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
933                 (__u16)0x00, \
934                 (__u16)index, \
935                 (void *)&igot, \
936                 (__u16)sizeof(__u16), \
937                 (int)50000);
938 igot = 0xFF & igot;
939 switch (index) {
940 case 0x000:
941 case 0x500:
942 case 0x502:
943 case 0x503:
944 case 0x504:
945 case 0x506:
946 case 0x507: {
947         break;
948 }
949 case 0x204:
950 case 0x205:
951 case 0x350:
952 case 0x351: {
953         if (0 != (0xFF & igot)) {
954                 JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", \
955                                                                 igot, index);
956         }
957 break;
958 }
959 default: {
960         if ((0xFF & value) != (0xFF & igot)) {
961                 JOT(8, "unexpected 0x%02X != 0x%02X " \
962                                         "for STK register 0x%03X\n", \
963                                         igot, value, index);
964         }
965 break;
966 }
967 }
968 #endif /* ! NOREADBACK*/
969
970 return (0 > rc0) ? rc0 : rc1;
971 }
972 /*****************************************************************************/
973 int
974 regget(struct usb_device *pusb_device, __u16 index, void *pvoid)
975 {
976 int ir;
977
978 if (!pusb_device)
979         return -ENODEV;
980 ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \
981                 (__u8)0x00, \
982                 (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
983                 (__u16)0x00, \
984                 (__u16)index, \
985                 (void *)pvoid, \
986                 sizeof(__u8), \
987                 (int)50000);
988 return 0xFF & ir;
989 }
990 /*****************************************************************************/
991 int
992 wakeup_device(struct usb_device *pusb_device)
993 {
994 if (!pusb_device)
995         return -ENODEV;
996 return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \
997                 (__u8)USB_REQ_SET_FEATURE, \
998                 (__u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), \
999                 USB_DEVICE_REMOTE_WAKEUP, \
1000                 (__u16)0, \
1001                 (void *) NULL, \
1002                 (__u16)0, \
1003                 (int)50000);
1004 }
1005 /*****************************************************************************/
1006 int
1007 audio_setup(struct easycap *peasycap)
1008 {
1009 struct usb_device *pusb_device;
1010 unsigned char buffer[1];
1011 int rc, id1, id2;
1012 /*---------------------------------------------------------------------------*/
1013 /*
1014  *                                IMPORTANT:
1015  *  THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
1016  *  CAUSES MUTING IF THE VALUE 0x0100 IS SENT.
1017  *  TO ENABLE AUDIO  THE VALUE 0x0200 MUST BE SENT.
1018  */
1019 /*---------------------------------------------------------------------------*/
1020 const __u8 request = 0x01;
1021 const __u8 requesttype = \
1022                 (__u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
1023 const __u16 value_unmute = 0x0200;
1024 const __u16 index = 0x0301;
1025 const __u16 length = 1;
1026
1027 if (NULL == peasycap)
1028         return -EFAULT;
1029
1030 pusb_device = peasycap->pusb_device;
1031 if (NULL == pusb_device)
1032         return -ENODEV;
1033
1034 JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",     \
1035                         requesttype, request,           \
1036                         (0x00FF & value_unmute),        \
1037                         (0xFF00 & value_unmute) >> 8,   \
1038                         (0x00FF & index),               \
1039                         (0xFF00 & index) >> 8,          \
1040                         (0x00FF & length),              \
1041                         (0xFF00 & length) >> 8);
1042
1043 buffer[0] = 0x01;
1044
1045 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),      \
1046                         (__u8)request,                                  \
1047                         (__u8)requesttype,                              \
1048                         (__u16)value_unmute,                            \
1049                         (__u16)index,                                   \
1050                         (void *)&buffer[0],                             \
1051                         (__u16)length,                                  \
1052                         (int)50000);
1053
1054 JOT(8, "0x%02X=buffer\n", *((__u8 *) &buffer[0]));
1055 if (rc != (int)length)
1056         SAY("ERROR: usb_control_msg returned %i\n", rc);
1057
1058 /*--------------------------------------------------------------------------*/
1059 /*
1060  *  REGISTER 500:  SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
1061  *  REGISTER 506:  ANALOGUE AUDIO ATTENTUATOR ???
1062  *                 FOR THE CVBS+S-VIDEO HARDWARE:
1063  *                    SETTING VALUE TO 0x0000 GIVES QUIET SOUND.
1064  *                    THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
1065  *                 FOR THE FOUR-CVBS HARDWARE:
1066  *                    SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT.
1067  *  REGISTER 507:  ANALOGUE AUDIO PREAMPLIFIER ON/OFF ???
1068  *                 FOR THE CVBS-S-VIDEO HARDWARE:
1069  *                    SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND.
1070  *                    THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
1071  */
1072 /*--------------------------------------------------------------------------*/
1073 SET(pusb_device, 0x0500, 0x0094);
1074 SET(pusb_device, 0x0500, 0x008C);
1075 SET(pusb_device, 0x0506, 0x0001);
1076 SET(pusb_device, 0x0507, 0x0000);
1077 id1 = read_vt(pusb_device, 0x007C);
1078 id2 = read_vt(pusb_device, 0x007E);
1079 SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2);
1080 /*---------------------------------------------------------------------------*/
1081 /*
1082  *  SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
1083 */
1084 /*---------------------------------------------------------------------------*/
1085 if (31 < easycap_gain)
1086         easycap_gain = 31;
1087 if (0 > easycap_gain)
1088         easycap_gain = 0;
1089 if (0 != audio_gainset(pusb_device, (__s8)easycap_gain))
1090         SAY("ERROR: audio_gainset() failed\n");
1091 check_vt(pusb_device);
1092 return 0;
1093 }
1094 /*****************************************************************************/
1095 int
1096 check_vt(struct usb_device *pusb_device)
1097 {
1098 int igot;
1099
1100 if (!pusb_device)
1101         return -ENODEV;
1102 igot = read_vt(pusb_device, 0x0002);
1103 if (0 > igot)
1104         SAY("ERROR: failed to read VT1612A register 0x02\n");
1105 if (0x8000 & igot)
1106         SAY("register 0x%02X muted\n", 0x02);
1107
1108 igot = read_vt(pusb_device, 0x000E);
1109 if (0 > igot)
1110         SAY("ERROR: failed to read VT1612A register 0x0E\n");
1111 if (0x8000 & igot)
1112         SAY("register 0x%02X muted\n", 0x0E);
1113
1114 igot = read_vt(pusb_device, 0x0010);
1115 if (0 > igot)
1116         SAY("ERROR: failed to read VT1612A register 0x10\n");
1117 if (0x8000 & igot)
1118         SAY("register 0x%02X muted\n", 0x10);
1119
1120 igot = read_vt(pusb_device, 0x0012);
1121 if (0 > igot)
1122         SAY("ERROR: failed to read VT1612A register 0x12\n");
1123 if (0x8000 & igot)
1124         SAY("register 0x%02X muted\n", 0x12);
1125
1126 igot = read_vt(pusb_device, 0x0014);
1127 if (0 > igot)
1128         SAY("ERROR: failed to read VT1612A register 0x14\n");
1129 if (0x8000 & igot)
1130         SAY("register 0x%02X muted\n", 0x14);
1131
1132 igot = read_vt(pusb_device, 0x0016);
1133 if (0 > igot)
1134         SAY("ERROR: failed to read VT1612A register 0x16\n");
1135 if (0x8000 & igot)
1136         SAY("register 0x%02X muted\n", 0x16);
1137
1138 igot = read_vt(pusb_device, 0x0018);
1139 if (0 > igot)
1140         SAY("ERROR: failed to read VT1612A register 0x18\n");
1141 if (0x8000 & igot)
1142         SAY("register 0x%02X muted\n", 0x18);
1143
1144 igot = read_vt(pusb_device, 0x001C);
1145 if (0 > igot)
1146         SAY("ERROR: failed to read VT1612A register 0x1C\n");
1147 if (0x8000 & igot)
1148         SAY("register 0x%02X muted\n", 0x1C);
1149
1150 return 0;
1151 }
1152 /*****************************************************************************/
1153 /*---------------------------------------------------------------------------*/
1154 /*  NOTE:  THIS DOES INCREASE THE VOLUME DRAMATICALLY:
1155  *                      audio_gainset(pusb_device, 0x000F);
1156  *
1157  *       loud        dB  register 0x10      dB register 0x1C    dB total
1158  *         0               -34.5                   0             -34.5
1159  *        ..                ....                   .              ....
1160  *        15                10.5                   0              10.5
1161  *        16                12.0                   0              12.0
1162  *        17                12.0                   1.5            13.5
1163  *        ..                ....                  ....            ....
1164  *        31                12.0                  22.5            34.5
1165 */
1166 /*---------------------------------------------------------------------------*/
1167 int
1168 audio_gainset(struct usb_device *pusb_device, __s8 loud)
1169 {
1170 int igot;
1171 __u8 u8;
1172 __u16 mute;
1173
1174 if (NULL == pusb_device)
1175         return -ENODEV;
1176 if (0 > loud)
1177         loud = 0;
1178 if (31 < loud)
1179         loud = 31;
1180
1181 write_vt(pusb_device, 0x0002, 0x8000);
1182 /*---------------------------------------------------------------------------*/
1183 igot = read_vt(pusb_device, 0x000E);
1184 if (0 > igot) {
1185         SAY("ERROR: failed to read VT1612A register 0x0E\n");
1186         mute = 0x0000;
1187 } else
1188         mute = 0x8000 & ((unsigned int)igot);
1189 mute = 0;
1190
1191 if (16 > loud)
1192         u8 = 0x01 | (0x001F & (((__u8)(15 - loud)) << 1));
1193 else
1194         u8 = 0;
1195
1196 JOT(8, "0x%04X=(mute|u8) for VT1612A register 0x0E\n", mute | u8);
1197 write_vt(pusb_device, 0x000E, (mute | u8));
1198 /*---------------------------------------------------------------------------*/
1199 igot = read_vt(pusb_device, 0x0010);
1200 if (0 > igot) {
1201         SAY("ERROR: failed to read VT1612A register 0x10\n");
1202         mute = 0x0000;
1203 } else
1204         mute = 0x8000 & ((unsigned int)igot);
1205 mute = 0;
1206
1207 JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x10,...0x18\n", \
1208                                                         mute | u8 | (u8 << 8));
1209 write_vt(pusb_device, 0x0010, (mute | u8 | (u8 << 8)));
1210 write_vt(pusb_device, 0x0012, (mute | u8 | (u8 << 8)));
1211 write_vt(pusb_device, 0x0014, (mute | u8 | (u8 << 8)));
1212 write_vt(pusb_device, 0x0016, (mute | u8 | (u8 << 8)));
1213 write_vt(pusb_device, 0x0018, (mute | u8 | (u8 << 8)));
1214 /*---------------------------------------------------------------------------*/
1215 igot = read_vt(pusb_device, 0x001C);
1216 if (0 > igot) {
1217         SAY("ERROR: failed to read VT1612A register 0x1C\n");
1218         mute = 0x0000;
1219 } else
1220         mute = 0x8000 & ((unsigned int)igot);
1221 mute = 0;
1222
1223 if (16 <= loud)
1224         u8 = 0x000F & (__u8)(loud - 16);
1225 else
1226         u8 = 0;
1227
1228 JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x1C\n", \
1229                                                         mute | u8 | (u8 << 8));
1230 write_vt(pusb_device, 0x001C, (mute | u8 | (u8 << 8)));
1231 write_vt(pusb_device, 0x001A, 0x0404);
1232 write_vt(pusb_device, 0x0002, 0x0000);
1233 return 0;
1234 }
1235 /*****************************************************************************/
1236 int
1237 audio_gainget(struct usb_device *pusb_device)
1238 {
1239 int igot;
1240
1241 if (NULL == pusb_device)
1242         return -ENODEV;
1243 igot = read_vt(pusb_device, 0x001C);
1244 if (0 > igot)
1245         SAY("ERROR: failed to read VT1612A register 0x1C\n");
1246 return igot;
1247 }
1248 /*****************************************************************************/