staging/easycap: Add option to set the hardware audio gain
[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_debug.h"
42 #include "easycap.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 GET(p, 0x0110, &get0);
252 GET(p, 0x0111, &get1);
253 GET(p, 0x0112, &get2);
254 GET(p, 0x0113, &get3);
255 GET(p, 0x0114, &get4);
256 GET(p, 0x0115, &get5);
257 GET(p, 0x0116, &get6);
258 GET(p, 0x0117, &get7);
259 JOT(8,  "0x%03X, 0x%03X, " \
260         "0x%03X, 0x%03X, " \
261         "0x%03X, 0x%03X, " \
262         "0x%03X, 0x%03X\n", \
263         get0, get1, get2, get3, get4, get5, get6, get7);
264 JOT(8,  "....cf PAL_720x526: " \
265         "0x%03X, 0x%03X, " \
266         "0x%03X, 0x%03X, " \
267         "0x%03X, 0x%03X, " \
268         "0x%03X, 0x%03X\n", \
269         0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001);
270 JOT(8,  "....cf PAL_704x526: " \
271         "0x%03X, 0x%03X, " \
272         "0x%03X, 0x%03X, " \
273         "0x%03X, 0x%03X, " \
274         "0x%03X, 0x%03X\n", \
275         0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001);
276 JOT(8,  "....cf VGA_640x480: " \
277         "0x%03X, 0x%03X, " \
278         "0x%03X, 0x%03X, " \
279         "0x%03X, 0x%03X, " \
280         "0x%03X, 0x%03X\n", \
281         0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001);
282 return 0;
283 }
284 /****************************************************************************/
285 int
286 confirm_stream(struct usb_device *p)
287 {
288 __u16 get2;
289 __u8 igot;
290
291 GET(p, 0x0100, &igot);  get2 = 0x80 & igot;
292 if (0x80 == get2)
293         JOT(8, "confirm_stream:  OK\n");
294 else
295         JOT(8, "confirm_stream:  STUCK\n");
296 return 0;
297 }
298 /****************************************************************************/
299 int
300 setup_stk(struct usb_device *p, bool ntsc)
301 {
302 int i0;
303
304 i0 = 0;
305 if (true == ntsc) {
306         while (0xFFF != stk1160configNTSC[i0].reg) {
307                 SET(p, stk1160configNTSC[i0].reg, stk1160configNTSC[i0].set);
308                 i0++;
309         }
310 } else {
311         while (0xFFF != stk1160configPAL[i0].reg) {
312                 SET(p, stk1160configPAL[i0].reg, stk1160configPAL[i0].set);
313                 i0++;
314         }
315 }
316
317 write_300(p);
318
319 return 0;
320 }
321 /****************************************************************************/
322 int
323 setup_saa(struct usb_device *p, bool ntsc)
324 {
325 int i0, ir;
326
327 i0 = 0;
328 if (true == ntsc) {
329         while (0xFF != saa7113configNTSC[i0].reg) {
330                 ir = write_saa(p, saa7113configNTSC[i0].reg, \
331                                         saa7113configNTSC[i0].set);
332                 i0++;
333         }
334 } else {
335         while (0xFF != saa7113configPAL[i0].reg) {
336                 ir = write_saa(p, saa7113configPAL[i0].reg, \
337                                         saa7113configPAL[i0].set);
338                 i0++;
339         }
340 }
341 return 0;
342 }
343 /****************************************************************************/
344 int
345 write_000(struct usb_device *p, __u16 set2, __u16 set0)
346 {
347 __u8 igot0, igot2;
348
349 GET(p, 0x0002, &igot2);
350 GET(p, 0x0000, &igot0);
351 SET(p, 0x0002, set2);
352 SET(p, 0x0000, set0);
353 return 0;
354 }
355 /****************************************************************************/
356 int
357 write_saa(struct usb_device *p, __u16 reg0, __u16 set0)
358 {
359 SET(p, 0x200, 0x00);
360 SET(p, 0x204, reg0);
361 SET(p, 0x205, set0);
362 SET(p, 0x200, 0x01);
363 return wait_i2c(p);
364 }
365 /****************************************************************************/
366 /*--------------------------------------------------------------------------*/
367 /*
368  *  REGISTER 500:  SETTING VALUE TO 0x008B READS FROM VT1612A (?)
369  *  REGISTER 500:  SETTING VALUE TO 0x008C WRITES TO  VT1612A
370  *  REGISTER 502:  LEAST SIGNIFICANT BYTE OF VALUE TO SET
371  *  REGISTER 503:  MOST SIGNIFICANT BYTE OF VALUE TO SET
372  *  REGISTER 504:  TARGET ADDRESS ON VT1612A
373  */
374 /*--------------------------------------------------------------------------*/
375 int
376 write_vt(struct usb_device *p, __u16 reg0, __u16 set0)
377 {
378 __u8 igot;
379 __u16 got502, got503;
380 __u16 set502, set503;
381
382 SET(p, 0x0504, reg0);
383 SET(p, 0x0500, 0x008B);
384
385 GET(p, 0x0502, &igot);  got502 = (0xFF & igot);
386 GET(p, 0x0503, &igot);  got503 = (0xFF & igot);
387
388 JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", \
389                                         reg0, set0, ((got503 << 8) | got502));
390
391 set502 =  (0x00FF & set0);
392 set503 = ((0xFF00 & set0) >> 8);
393
394 SET(p, 0x0504, reg0);
395 SET(p, 0x0502, set502);
396 SET(p, 0x0503, set503);
397 SET(p, 0x0500, 0x008C);
398
399 return 0;
400 }
401 /****************************************************************************/
402 /*--------------------------------------------------------------------------*/
403 /*
404  *  REGISTER 500:  SETTING VALUE TO 0x008B READS FROM VT1612A (?)
405  *  REGISTER 500:  SETTING VALUE TO 0x008C WRITES TO  VT1612A
406  *  REGISTER 502:  LEAST SIGNIFICANT BYTE OF VALUE TO GET
407  *  REGISTER 503:  MOST SIGNIFICANT BYTE OF VALUE TO GET
408  *  REGISTER 504:  TARGET ADDRESS ON VT1612A
409  */
410 /*--------------------------------------------------------------------------*/
411 int
412 read_vt(struct usb_device *p, __u16 reg0)
413 {
414 __u8 igot;
415 __u16 got502, got503;
416
417 SET(p, 0x0504, reg0);
418 SET(p, 0x0500, 0x008B);
419
420 GET(p, 0x0502, &igot);  got502 = (0xFF & igot);
421 GET(p, 0x0503, &igot);  got503 = (0xFF & igot);
422
423 JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", reg0, ((got503 << 8) | got502));
424
425 return (got503 << 8) | got502;
426 }
427 /****************************************************************************/
428 /*--------------------------------------------------------------------------*/
429 /*
430  *  THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
431  */
432 /*--------------------------------------------------------------------------*/
433 int
434 write_300(struct usb_device *p)
435 {
436 SET(p, 0x300, 0x0012);
437 SET(p, 0x350, 0x002D);
438 SET(p, 0x351, 0x0001);
439 SET(p, 0x352, 0x0000);
440 SET(p, 0x353, 0x0000);
441 SET(p, 0x300, 0x0080);
442 return 0;
443 }
444 /****************************************************************************/
445 /*--------------------------------------------------------------------------*/
446 /*
447  *  NOTE: THE FOLLOWING IS NOT CHECKED:
448  *  REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL.
449  */
450 /*--------------------------------------------------------------------------*/
451 int
452 check_saa(struct usb_device *p, bool ntsc)
453 {
454 int i0, ir, rc;
455
456 i0 = 0;
457 rc = 0;
458 if (true == ntsc) {
459         while (0xFF != saa7113configNTSC[i0].reg) {
460                 if (0x0F == saa7113configNTSC[i0].reg) {
461                         i0++;
462                         continue;
463                 }
464
465                 ir = read_saa(p, saa7113configNTSC[i0].reg);
466                 if (ir != saa7113configNTSC[i0].set) {
467                         SAY("SAA register 0x%02X has 0x%02X, " \
468                                                 "expected 0x%02X\n", \
469                                                 saa7113configNTSC[i0].reg, \
470                                                 ir, saa7113configNTSC[i0].set);
471                         rc--;
472                 }
473                 i0++;
474         }
475 } else {
476         while (0xFF != saa7113configPAL[i0].reg) {
477                 if (0x0F == saa7113configPAL[i0].reg) {
478                         i0++;
479                         continue;
480                 }
481
482                 ir = read_saa(p, saa7113configPAL[i0].reg);
483                 if (ir != saa7113configPAL[i0].set) {
484                         SAY("SAA register 0x%02X has 0x%02X, " \
485                                                 "expected 0x%02X\n", \
486                                                 saa7113configPAL[i0].reg, \
487                                                 ir, saa7113configPAL[i0].set);
488                         rc--;
489                 }
490                 i0++;
491         }
492 }
493 if (-8 > rc)
494         return rc;
495 else
496         return 0;
497 }
498 /****************************************************************************/
499 int
500 merit_saa(struct usb_device *p)
501 {
502 int rc;
503
504 rc = read_saa(p, 0x1F);
505 if ((0 > rc) || (0x02 & rc))
506         return 1 ;
507 else
508         return 0;
509 }
510 /****************************************************************************/
511 int
512 ready_saa(struct usb_device *p)
513 {
514 int j, rc, rate;
515 const int max = 5, marktime = PATIENCE/5;
516 /*--------------------------------------------------------------------------*/
517 /*
518  *   RETURNS    0     FOR INTERLACED       50 Hz
519  *              1     FOR NON-INTERLACED   50 Hz
520  *              2     FOR INTERLACED       60 Hz
521  *              3     FOR NON-INTERLACED   60 Hz
522 */
523 /*--------------------------------------------------------------------------*/
524 j = 0;
525 while (max > j) {
526         rc = read_saa(p, 0x1F);
527         if (0 <= rc) {
528                 if (0 == (0x40 & rc))
529                         break;
530                 if (1 == (0x01 & rc))
531                         break;
532         }
533         msleep(marktime);
534         j++;
535 }
536 if (max == j)
537         return -1;
538 else {
539         if (0x20 & rc) {
540                 rate = 2;
541                 JOT(8, "hardware detects 60 Hz\n");
542         } else {
543                 rate = 0;
544                 JOT(8, "hardware detects 50 Hz\n");
545         }
546         if (0x80 & rc)
547                 JOT(8, "hardware detects interlacing\n");
548         else {
549                 rate++;
550                 JOT(8, "hardware detects no interlacing\n");
551         }
552 }
553 return 0;
554 }
555 /****************************************************************************/
556 /*--------------------------------------------------------------------------*/
557 /*
558  *  NOTE: THE FOLLOWING ARE NOT CHECKED:
559  *  REGISTERS 0x000, 0x002:  FUNCTIONALITY IS NOT KNOWN
560  *  REGISTER  0x100:  ACCEPT ALSO (0x80 | stk1160config....[.].set)
561  */
562 /*--------------------------------------------------------------------------*/
563 int
564 check_stk(struct usb_device *p, bool ntsc)
565 {
566 int i0, ir;
567
568 i0 = 0;
569 if (true == ntsc) {
570         while (0xFFF != stk1160configNTSC[i0].reg) {
571                 if (0x000 == stk1160configNTSC[i0].reg) {
572                         i0++; continue;
573                 }
574                 if (0x002 == stk1160configNTSC[i0].reg) {
575                         i0++; continue;
576                 }
577                 ir = read_stk(p, stk1160configNTSC[i0].reg);
578                 if (0x100 == stk1160configNTSC[i0].reg) {
579                         if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \
580                                         (ir != (0x80 | (0xFF & \
581                                         stk1160configNTSC[i0].set))) && \
582                                         (0xFFFF != \
583                                         stk1160configNTSC[i0].set)) {
584                                 SAY("STK register 0x%03X has 0x%02X, " \
585                                                 "expected 0x%02X\n", \
586                                                 stk1160configNTSC[i0].reg, \
587                                                 ir, stk1160configNTSC[i0].set);
588                                 }
589                         i0++; continue;
590                         }
591                 if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \
592                                 (0xFFFF != stk1160configNTSC[i0].set)) {
593                         SAY("STK register 0x%03X has 0x%02X, " \
594                                                 "expected 0x%02X\n", \
595                                                 stk1160configNTSC[i0].reg, \
596                                                 ir, stk1160configNTSC[i0].set);
597                 }
598                 i0++;
599         }
600 } else {
601         while (0xFFF != stk1160configPAL[i0].reg) {
602                 if (0x000 == stk1160configPAL[i0].reg) {
603                         i0++; continue;
604                 }
605                 if (0x002 == stk1160configPAL[i0].reg) {
606                         i0++; continue;
607                 }
608                 ir = read_stk(p, stk1160configPAL[i0].reg);
609                 if (0x100 == stk1160configPAL[i0].reg) {
610                         if ((ir != (0xFF & stk1160configPAL[i0].set)) && \
611                                         (ir != (0x80 | (0xFF & \
612                                         stk1160configPAL[i0].set))) && \
613                                         (0xFFFF != \
614                                         stk1160configPAL[i0].set)) {
615                                 SAY("STK register 0x%03X has 0x%02X, " \
616                                                 "expected 0x%02X\n", \
617                                                 stk1160configPAL[i0].reg, \
618                                                 ir, stk1160configPAL[i0].set);
619                                 }
620                         i0++; continue;
621                         }
622                 if ((ir != (0xFF & stk1160configPAL[i0].set)) && \
623                                 (0xFFFF != stk1160configPAL[i0].set)) {
624                         SAY("STK register 0x%03X has 0x%02X, " \
625                                                 "expected 0x%02X\n", \
626                                                 stk1160configPAL[i0].reg, \
627                                                 ir, stk1160configPAL[i0].set);
628                 }
629                 i0++;
630         }
631 }
632 return 0;
633 }
634 /****************************************************************************/
635 int
636 read_saa(struct usb_device *p, __u16 reg0)
637 {
638 __u8 igot;
639
640 SET(p, 0x208, reg0);
641 SET(p, 0x200, 0x20);
642 if (0 != wait_i2c(p))
643         return -1;
644 igot = 0;
645 GET(p, 0x0209, &igot);
646 return igot;
647 }
648 /****************************************************************************/
649 int
650 read_stk(struct usb_device *p, __u32 reg0)
651 {
652 __u8 igot;
653
654 igot = 0;
655 GET(p, reg0, &igot);
656 return igot;
657 }
658 /****************************************************************************/
659 /*--------------------------------------------------------------------------*/
660 /*
661  *    HARDWARE    USERSPACE INPUT NUMBER   PHYSICAL INPUT   DRIVER input VALUE
662  *
663  *  CVBS+S-VIDEO           0 or 1              CVBS                 1
664  *   FOUR-CVBS             0 or 1              CVBS1                1
665  *   FOUR-CVBS                2                CVBS2                2
666  *   FOUR-CVBS                3                CVBS3                3
667  *   FOUR-CVBS                4                CVBS4                4
668  *  CVBS+S-VIDEO              5               S-VIDEO               5
669  *
670  *  WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED:
671  *
672  *     mode  7   => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED)
673  *     mode  9   => USE AUTOMATIC GAIN CONTROL (DEFAULT)
674  *
675 */
676 /*---------------------------------------------------------------------------*/
677 int
678 select_input(struct usb_device *p, int input, int mode)
679 {
680 int ir;
681
682 stop_100(p);
683 switch (input) {
684 case 0:
685 case 1: {
686         if (0 != write_saa(p, 0x02, 0x80)) {
687                 SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
688                                                                         input);
689         }
690         SET(p, 0x0000, 0x0098);
691         SET(p, 0x0002, 0x0078);
692         break;
693 }
694 case 2: {
695         if (0 != write_saa(p, 0x02, 0x80)) {
696                 SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
697                                                                         input);
698         }
699         SET(p, 0x0000, 0x0090);
700         SET(p, 0x0002, 0x0078);
701         break;
702 }
703 case 3: {
704         if (0 != write_saa(p, 0x02, 0x80)) {
705                 SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
706                                                                         input);
707         }
708         SET(p, 0x0000, 0x0088);
709         SET(p, 0x0002, 0x0078);
710         break;
711 }
712 case 4: {
713         if (0 != write_saa(p, 0x02, 0x80)) {
714                 SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
715                                                                         input);
716         }
717         SET(p, 0x0000, 0x0080);
718         SET(p, 0x0002, 0x0078);
719         break;
720 }
721 case 5: {
722         if (9 != mode)
723                 mode = 7;
724         switch (mode) {
725         case 7: {
726                 if (0 != write_saa(p, 0x02, 0x87)) {
727                         SAY("ERROR: failed to set SAA register 0x02 " \
728                                                 "for input %i\n", input);
729                 }
730                 if (0 != write_saa(p, 0x05, 0xFF)) {
731                         SAY("ERROR: failed to set SAA register 0x05 " \
732                                                 "for input %i\n", input);
733                 }
734                 break;
735         }
736         case 9: {
737                 if (0 != write_saa(p, 0x02, 0x89)) {
738                         SAY("ERROR: failed to set SAA register 0x02 " \
739                                                 "for input %i\n", input);
740                 }
741                 if (0 != write_saa(p, 0x05, 0x00)) {
742                         SAY("ERROR: failed to set SAA register 0x05 " \
743                                                 "for input %i\n", input);
744                 }
745         break;
746         }
747         default: {
748                 SAY("MISTAKE:  bad mode: %i\n", mode);
749                 return -1;
750         }
751         }
752         if (0 != write_saa(p, 0x04, 0x00)) {
753                 SAY("ERROR: failed to set SAA register 0x04 for input %i\n", \
754                                                                         input);
755         }
756         if (0 != write_saa(p, 0x09, 0x80)) {
757                 SAY("ERROR: failed to set SAA register 0x09 for input %i\n", \
758                                                                         input);
759         }
760         SET(p, 0x0002, 0x0093);
761         break;
762 }
763 default: {
764         SAY("ERROR:  bad input: %i\n", input);
765         return -1;
766 }
767 }
768 ir = read_stk(p, 0x00);
769 JOT(8, "STK register 0x00 has 0x%02X\n", ir);
770 ir = read_saa(p, 0x02);
771 JOT(8, "SAA register 0x02 has 0x%02X\n", ir);
772
773 start_100(p);
774
775 return 0;
776 }
777 /****************************************************************************/
778 int
779 set_resolution(struct usb_device *p, \
780                                 __u16 set0, __u16 set1, __u16 set2, __u16 set3)
781 {
782 __u16 u0x0111, u0x0113, u0x0115, u0x0117;
783
784 u0x0111 = ((0xFF00 & set0) >> 8);
785 u0x0113 = ((0xFF00 & set1) >> 8);
786 u0x0115 = ((0xFF00 & set2) >> 8);
787 u0x0117 = ((0xFF00 & set3) >> 8);
788
789 SET(p, 0x0110, (0x00FF & set0));
790 SET(p, 0x0111, u0x0111);
791 SET(p, 0x0112, (0x00FF & set1));
792 SET(p, 0x0113, u0x0113);
793 SET(p, 0x0114, (0x00FF & set2));
794 SET(p, 0x0115, u0x0115);
795 SET(p, 0x0116, (0x00FF & set3));
796 SET(p, 0x0117, u0x0117);
797
798 return 0;
799 }
800 /****************************************************************************/
801 int
802 start_100(struct usb_device *p)
803 {
804 __u16 get116, get117, get0;
805 __u8 igot116, igot117, igot;
806
807 GET(p, 0x0116, &igot116);
808 get116 = igot116;
809 GET(p, 0x0117, &igot117);
810 get117 = igot117;
811 SET(p, 0x0116, 0x0000);
812 SET(p, 0x0117, 0x0000);
813
814 GET(p, 0x0100, &igot);
815 get0 = igot;
816 SET(p, 0x0100, (0x80 | get0));
817
818 SET(p, 0x0116, get116);
819 SET(p, 0x0117, get117);
820
821 return 0;
822 }
823 /****************************************************************************/
824 int
825 stop_100(struct usb_device *p)
826 {
827 __u16 get0;
828 __u8 igot;
829
830 GET(p, 0x0100, &igot);
831 get0 = igot;
832 SET(p, 0x0100, (0x7F & get0));
833 return 0;
834 }
835 /****************************************************************************/
836 /*--------------------------------------------------------------------------*/
837 /*
838  *  FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
839 */
840 /*--------------------------------------------------------------------------*/
841 int
842 wait_i2c(struct usb_device *p)
843 {
844 __u16 get0;
845 __u8 igot;
846 const int max = 2;
847 int k;
848
849 for (k = 0;  k < max;  k++) {
850         GET(p, 0x0201, &igot);  get0 = igot;
851         switch (get0) {
852         case 0x04:
853         case 0x01: {
854                 return 0;
855         }
856         case 0x00: {
857                 msleep(20);
858                 continue;
859         }
860         default: {
861                 return get0 - 1;
862         }
863         }
864 }
865 return -1;
866 }
867 /****************************************************************************/
868 int
869 regset(struct usb_device *pusb_device, __u16 index, __u16 value)
870 {
871 __u16 igot;
872 int rc0, rc1;
873
874 if (!pusb_device)
875         return -EFAULT;
876
877 rc1 = 0;  igot = 0;
878 rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \
879                 (__u8)0x01, \
880                 (__u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
881                 (__u16)value, \
882                 (__u16)index, \
883                 (void *)NULL, \
884                 (__u16)0, \
885                 (int)500);
886
887 #if defined(NOREADBACK)
888 #
889 #else
890 rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \
891                 (__u8)0x00, \
892                 (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
893                 (__u16)0x00, \
894                 (__u16)index, \
895                 (void *)&igot, \
896                 (__u16)sizeof(__u16), \
897                 (int)50000);
898 igot = 0xFF & igot;
899 switch (index) {
900 case 0x000:
901 case 0x500:
902 case 0x502:
903 case 0x503:
904 case 0x504:
905 case 0x506:
906 case 0x507: {
907         break;
908 }
909 case 0x204:
910 case 0x205:
911 case 0x350:
912 case 0x351: {
913         if (0 != (0xFF & igot)) {
914                 JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", \
915                                                                 igot, index);
916         }
917 break;
918 }
919 default: {
920         if ((0xFF & value) != (0xFF & igot)) {
921                 JOT(8, "unexpected 0x%02X != 0x%02X " \
922                                         "for STK register 0x%03X\n", \
923                                         igot, value, index);
924         }
925 break;
926 }
927 }
928 #endif /* ! NOREADBACK*/
929
930 return (0 > rc0) ? rc0 : rc1;
931 }
932 /*****************************************************************************/
933 int
934 regget(struct usb_device *pusb_device, __u16 index, void *pvoid)
935 {
936 int ir;
937
938 if (!pusb_device)
939         return -EFAULT;
940
941 ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \
942                 (__u8)0x00, \
943                 (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
944                 (__u16)0x00, \
945                 (__u16)index, \
946                 (void *)pvoid, \
947                 sizeof(__u8), \
948                 (int)50000);
949 return 0xFF & ir;
950 }
951 /*****************************************************************************/
952 int
953 wakeup_device(struct usb_device *pusb_device)
954 {
955 return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \
956                 (__u8)USB_REQ_SET_FEATURE, \
957                 (__u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), \
958                 USB_DEVICE_REMOTE_WAKEUP, \
959                 (__u16)0, \
960                 (void *) NULL, \
961                 (__u16)0, \
962                 (int)50000);
963 }
964 /*****************************************************************************/
965 int
966 audio_setup(struct easycap *peasycap)
967 {
968 struct usb_device *pusb_device;
969 unsigned char buffer[1];
970 int rc, id1, id2;
971 /*---------------------------------------------------------------------------*/
972 /*
973  *                                IMPORTANT:
974  *  THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
975  *  CAUSES MUTING IF THE VALUE 0x0100 IS SENT.
976  *  TO ENABLE AUDIO  THE VALUE 0x0200 MUST BE SENT.
977  */
978 /*---------------------------------------------------------------------------*/
979 const __u8 request = 0x01;
980 const __u8 requesttype = \
981                 (__u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
982 const __u16 value_unmute = 0x0200;
983 const __u16 index = 0x0301;
984 const __u16 length = 1;
985
986 if (NULL == peasycap)
987         return -EFAULT;
988
989 pusb_device = peasycap->pusb_device;
990 if (NULL == pusb_device)
991         return -ENODEV;
992
993 JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",     \
994                         requesttype, request,           \
995                         (0x00FF & value_unmute),        \
996                         (0xFF00 & value_unmute) >> 8,   \
997                         (0x00FF & index),               \
998                         (0xFF00 & index) >> 8,          \
999                         (0x00FF & length),              \
1000                         (0xFF00 & length) >> 8);
1001
1002 buffer[0] = 0x01;
1003
1004 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),      \
1005                         (__u8)request,                                  \
1006                         (__u8)requesttype,                              \
1007                         (__u16)value_unmute,                            \
1008                         (__u16)index,                                   \
1009                         (void *)&buffer[0],                             \
1010                         (__u16)length,                                  \
1011                         (int)50000);
1012
1013 JOT(8, "0x%02X=buffer\n", *((__u8 *) &buffer[0]));
1014 if (rc != (int)length)
1015         SAY("ERROR: usb_control_msg returned %i\n", rc);
1016
1017 /*--------------------------------------------------------------------------*/
1018 /*
1019  *  REGISTER 500:  SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
1020  *  REGISTER 506:  ANALOGUE AUDIO ATTENTUATOR ???
1021  *                 FOR THE CVBS+S-VIDEO HARDWARE:
1022  *                    SETTING VALUE TO 0x0000 GIVES QUIET SOUND.
1023  *                    THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
1024  *                 FOR THE FOUR-CVBS HARDWARE:
1025  *                    SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT.
1026  *  REGISTER 507:  ANALOGUE AUDIO PREAMPLIFIER ON/OFF ???
1027  *                 FOR THE CVBS-S-VIDEO HARDWARE:
1028  *                    SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND.
1029  *                    THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
1030  */
1031 /*--------------------------------------------------------------------------*/
1032 SET(pusb_device, 0x0500, 0x0094);
1033 SET(pusb_device, 0x0500, 0x008C);
1034 SET(pusb_device, 0x0506, 0x0001);
1035 SET(pusb_device, 0x0507, 0x0000);
1036 id1 = read_vt(pusb_device, 0x007C);
1037 id2 = read_vt(pusb_device, 0x007E);
1038 SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2);
1039 /*---------------------------------------------------------------------------*/
1040 /*
1041  *  SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
1042 */
1043 /*---------------------------------------------------------------------------*/
1044 if (31 < gain)
1045         gain = 31;
1046 if (0 > gain)
1047         gain = 0;
1048 if (0 != audio_gainset(pusb_device, (__s8)gain))
1049         SAY("ERROR: audio_gainset() failed\n");
1050 check_vt(pusb_device);
1051 return 0;
1052 }
1053 /*****************************************************************************/
1054 int
1055 check_vt(struct usb_device *pusb_device)
1056 {
1057 int igot;
1058
1059 igot = read_vt(pusb_device, 0x0002);
1060 if (0 > igot)
1061         SAY("ERROR: failed to read VT1612A register 0x02\n");
1062 if (0x8000 & igot)
1063         SAY("register 0x%02X muted\n", 0x02);
1064
1065 igot = read_vt(pusb_device, 0x000E);
1066 if (0 > igot)
1067         SAY("ERROR: failed to read VT1612A register 0x0E\n");
1068 if (0x8000 & igot)
1069         SAY("register 0x%02X muted\n", 0x0E);
1070
1071 igot = read_vt(pusb_device, 0x0010);
1072 if (0 > igot)
1073         SAY("ERROR: failed to read VT1612A register 0x10\n");
1074 if (0x8000 & igot)
1075         SAY("register 0x%02X muted\n", 0x10);
1076
1077 igot = read_vt(pusb_device, 0x0012);
1078 if (0 > igot)
1079         SAY("ERROR: failed to read VT1612A register 0x12\n");
1080 if (0x8000 & igot)
1081         SAY("register 0x%02X muted\n", 0x12);
1082
1083 igot = read_vt(pusb_device, 0x0014);
1084 if (0 > igot)
1085         SAY("ERROR: failed to read VT1612A register 0x14\n");
1086 if (0x8000 & igot)
1087         SAY("register 0x%02X muted\n", 0x14);
1088
1089 igot = read_vt(pusb_device, 0x0016);
1090 if (0 > igot)
1091         SAY("ERROR: failed to read VT1612A register 0x16\n");
1092 if (0x8000 & igot)
1093         SAY("register 0x%02X muted\n", 0x16);
1094
1095 igot = read_vt(pusb_device, 0x0018);
1096 if (0 > igot)
1097         SAY("ERROR: failed to read VT1612A register 0x18\n");
1098 if (0x8000 & igot)
1099         SAY("register 0x%02X muted\n", 0x18);
1100
1101 igot = read_vt(pusb_device, 0x001C);
1102 if (0 > igot)
1103         SAY("ERROR: failed to read VT1612A register 0x1C\n");
1104 if (0x8000 & igot)
1105         SAY("register 0x%02X muted\n", 0x1C);
1106
1107 return 0;
1108 }
1109 /*****************************************************************************/
1110 /*---------------------------------------------------------------------------*/
1111 /*  NOTE:  THIS DOES INCREASE THE VOLUME DRAMATICALLY:
1112  *                      audio_gainset(pusb_device, 0x000F);
1113  *
1114  *       loud        dB  register 0x10      dB register 0x1C    dB total
1115  *         0               -34.5                   0             -34.5
1116  *        ..                ....                   .              ....
1117  *        15                10.5                   0              10.5
1118  *        16                12.0                   0              12.0
1119  *        17                12.0                   1.5            13.5
1120  *        ..                ....                  ....            ....
1121  *        31                12.0                  22.5            34.5
1122 */
1123 /*---------------------------------------------------------------------------*/
1124 int
1125 audio_gainset(struct usb_device *pusb_device, __s8 loud)
1126 {
1127 int igot;
1128 __u8 u8;
1129 __u16 mute;
1130
1131 if ((struct usb_device *)NULL == pusb_device)
1132         return -ENODEV;
1133 if (0 > loud)
1134         loud = 0;
1135 if (31 < loud)
1136         loud = 31;
1137
1138 write_vt(pusb_device, 0x0002, 0x8000);
1139 /*---------------------------------------------------------------------------*/
1140 igot = read_vt(pusb_device, 0x000E);
1141 if (0 > igot) {
1142         SAY("ERROR: failed to read VT1612A register 0x0E\n");
1143         mute = 0x0000;
1144 } else
1145         mute = 0x8000 & ((unsigned int)igot);
1146 mute = 0;
1147
1148 if (16 > loud)
1149         u8 = 0x01 | (0x001F & (((__u8)(15 - loud)) << 1));
1150 else
1151         u8 = 0;
1152
1153 JOT(8, "0x%04X=(mute|u8) for VT1612A register 0x0E\n", mute | u8);
1154 write_vt(pusb_device, 0x000E, (mute | u8));
1155 /*---------------------------------------------------------------------------*/
1156 igot = read_vt(pusb_device, 0x0010);
1157 if (0 > igot) {
1158         SAY("ERROR: failed to read VT1612A register 0x10\n");
1159         mute = 0x0000;
1160 } else
1161         mute = 0x8000 & ((unsigned int)igot);
1162 mute = 0;
1163
1164 JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x10,...0x18\n", \
1165                                                         mute | u8 | (u8 << 8));
1166 write_vt(pusb_device, 0x0010, (mute | u8 | (u8 << 8)));
1167 write_vt(pusb_device, 0x0012, (mute | u8 | (u8 << 8)));
1168 write_vt(pusb_device, 0x0014, (mute | u8 | (u8 << 8)));
1169 write_vt(pusb_device, 0x0016, (mute | u8 | (u8 << 8)));
1170 write_vt(pusb_device, 0x0018, (mute | u8 | (u8 << 8)));
1171 /*---------------------------------------------------------------------------*/
1172 igot = read_vt(pusb_device, 0x001C);
1173 if (0 > igot) {
1174         SAY("ERROR: failed to read VT1612A register 0x1C\n");
1175         mute = 0x0000;
1176 } else
1177         mute = 0x8000 & ((unsigned int)igot);
1178 mute = 0;
1179
1180 if (16 <= loud)
1181         u8 = 0x000F & (__u8)(loud - 16);
1182 else
1183         u8 = 0;
1184
1185 JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x1C\n", \
1186                                                         mute | u8 | (u8 << 8));
1187 write_vt(pusb_device, 0x001C, (mute | u8 | (u8 << 8)));
1188 write_vt(pusb_device, 0x001A, 0x0404);
1189 write_vt(pusb_device, 0x0002, 0x0000);
1190 return 0;
1191 }
1192 /*****************************************************************************/
1193 int
1194 audio_gainget(struct usb_device *pusb_device)
1195 {
1196 int igot;
1197
1198 if (NULL == pusb_device)
1199         return -ENODEV;
1200 igot = read_vt(pusb_device, 0x001C);
1201 if (0 > igot)
1202         SAY("ERROR: failed to read VT1612A register 0x1C\n");
1203 return igot;
1204 }
1205 /*****************************************************************************/