staging/easycap: remove EASYCAP_SILENT option
[wandboard.git] / drivers / staging / easycap / easycap_low.c
blob06ccd19d8457e3c849bde91c82bf34c14cb4a356
1 /*****************************************************************************
2 * *
3 * *
4 * easycap_low.c *
5 * *
6 * *
7 *****************************************************************************/
8 /*
10 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
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.
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.
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
28 /*****************************************************************************/
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.
39 /****************************************************************************/
41 #include "easycap.h"
43 /*--------------------------------------------------------------------------*/
44 static const struct stk1160config {
45 int reg;
46 int set;
47 } stk1160configPAL[256] = {
48 {0x000, 0x0098},
49 {0x002, 0x0093},
51 {0x001, 0x0003},
52 {0x003, 0x0080},
53 {0x00D, 0x0000},
54 {0x00F, 0x0002},
55 {0x018, 0x0010},
56 {0x019, 0x0000},
57 {0x01A, 0x0014},
58 {0x01B, 0x000E},
59 {0x01C, 0x0046},
61 {0x100, 0x0033},
62 {0x103, 0x0000},
63 {0x104, 0x0000},
64 {0x105, 0x0000},
65 {0x106, 0x0000},
67 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
69 * RESOLUTION 640x480
71 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
72 {0x110, 0x0008},
73 {0x111, 0x0000},
74 {0x112, 0x0020},
75 {0x113, 0x0000},
76 {0x114, 0x0508},
77 {0x115, 0x0005},
78 {0x116, 0x0110},
79 {0x117, 0x0001},
80 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
82 {0x202, 0x000F},
83 {0x203, 0x004A},
84 {0x2FF, 0x0000},
86 {0xFFF, 0xFFFF}
88 /*--------------------------------------------------------------------------*/
89 static const struct stk1160config stk1160configNTSC[256] = {
90 {0x000, 0x0098},
91 {0x002, 0x0093},
93 {0x001, 0x0003},
94 {0x003, 0x0080},
95 {0x00D, 0x0000},
96 {0x00F, 0x0002},
97 {0x018, 0x0010},
98 {0x019, 0x0000},
99 {0x01A, 0x0014},
100 {0x01B, 0x000E},
101 {0x01C, 0x0046},
103 {0x100, 0x0033},
104 {0x103, 0x0000},
105 {0x104, 0x0000},
106 {0x105, 0x0000},
107 {0x106, 0x0000},
109 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
111 * RESOLUTION 640x480
113 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
114 {0x110, 0x0008},
115 {0x111, 0x0000},
116 {0x112, 0x0003},
117 {0x113, 0x0000},
118 {0x114, 0x0508},
119 {0x115, 0x0005},
120 {0x116, 0x00F3},
121 {0x117, 0x0000},
122 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
124 {0x202, 0x000F},
125 {0x203, 0x004A},
126 {0x2FF, 0x0000},
128 {0xFFF, 0xFFFF}
130 /*--------------------------------------------------------------------------*/
131 static const struct saa7113config{
132 int reg;
133 int set;
134 } saa7113configPAL[256] = {
135 {0x01, 0x08},
136 {0x02, 0x80},
137 {0x03, 0x33},
138 {0x04, 0x00},
139 {0x05, 0x00},
140 {0x06, 0xE9},
141 {0x07, 0x0D},
142 {0x08, 0x38},
143 {0x09, 0x00},
144 {0x0A, SAA_0A_DEFAULT},
145 {0x0B, SAA_0B_DEFAULT},
146 {0x0C, SAA_0C_DEFAULT},
147 {0x0D, SAA_0D_DEFAULT},
148 {0x0E, 0x01},
149 {0x0F, 0x36},
150 {0x10, 0x00},
151 {0x11, 0x0C},
152 {0x12, 0xE7},
153 {0x13, 0x00},
154 {0x15, 0x00},
155 {0x16, 0x00},
156 {0x40, 0x02},
157 {0x41, 0xFF},
158 {0x42, 0xFF},
159 {0x43, 0xFF},
160 {0x44, 0xFF},
161 {0x45, 0xFF},
162 {0x46, 0xFF},
163 {0x47, 0xFF},
164 {0x48, 0xFF},
165 {0x49, 0xFF},
166 {0x4A, 0xFF},
167 {0x4B, 0xFF},
168 {0x4C, 0xFF},
169 {0x4D, 0xFF},
170 {0x4E, 0xFF},
171 {0x4F, 0xFF},
172 {0x50, 0xFF},
173 {0x51, 0xFF},
174 {0x52, 0xFF},
175 {0x53, 0xFF},
176 {0x54, 0xFF},
177 {0x55, 0xFF},
178 {0x56, 0xFF},
179 {0x57, 0xFF},
180 {0x58, 0x40},
181 {0x59, 0x54},
182 {0x5A, 0x07},
183 {0x5B, 0x83},
185 {0xFF, 0xFF}
187 /*--------------------------------------------------------------------------*/
188 static const struct saa7113config saa7113configNTSC[256] = {
189 {0x01, 0x08},
190 {0x02, 0x80},
191 {0x03, 0x33},
192 {0x04, 0x00},
193 {0x05, 0x00},
194 {0x06, 0xE9},
195 {0x07, 0x0D},
196 {0x08, 0x78},
197 {0x09, 0x00},
198 {0x0A, SAA_0A_DEFAULT},
199 {0x0B, SAA_0B_DEFAULT},
200 {0x0C, SAA_0C_DEFAULT},
201 {0x0D, SAA_0D_DEFAULT},
202 {0x0E, 0x01},
203 {0x0F, 0x36},
204 {0x10, 0x00},
205 {0x11, 0x0C},
206 {0x12, 0xE7},
207 {0x13, 0x00},
208 {0x15, 0x00},
209 {0x16, 0x00},
210 {0x40, 0x82},
211 {0x41, 0xFF},
212 {0x42, 0xFF},
213 {0x43, 0xFF},
214 {0x44, 0xFF},
215 {0x45, 0xFF},
216 {0x46, 0xFF},
217 {0x47, 0xFF},
218 {0x48, 0xFF},
219 {0x49, 0xFF},
220 {0x4A, 0xFF},
221 {0x4B, 0xFF},
222 {0x4C, 0xFF},
223 {0x4D, 0xFF},
224 {0x4E, 0xFF},
225 {0x4F, 0xFF},
226 {0x50, 0xFF},
227 {0x51, 0xFF},
228 {0x52, 0xFF},
229 {0x53, 0xFF},
230 {0x54, 0xFF},
231 {0x55, 0xFF},
232 {0x56, 0xFF},
233 {0x57, 0xFF},
234 {0x58, 0x40},
235 {0x59, 0x54},
236 {0x5A, 0x0A},
237 {0x5B, 0x83},
239 {0xFF, 0xFF}
241 /*--------------------------------------------------------------------------*/
243 /****************************************************************************/
245 confirm_resolution(struct usb_device *p)
247 u8 get0, get1, get2, get3, get4, get5, get6, get7;
249 if (NULL == p)
250 return -ENODEV;
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;
284 /****************************************************************************/
286 confirm_stream(struct usb_device *p)
288 u16 get2;
289 u8 igot;
291 if (NULL == p)
292 return -ENODEV;
293 GET(p, 0x0100, &igot); get2 = 0x80 & igot;
294 if (0x80 == get2)
295 JOT(8, "confirm_stream: OK\n");
296 else
297 JOT(8, "confirm_stream: STUCK\n");
298 return 0;
300 /****************************************************************************/
302 setup_stk(struct usb_device *p, bool ntsc)
304 int i0;
306 if (NULL == p)
307 return -ENODEV;
308 i0 = 0;
309 if (true == ntsc) {
310 while (0xFFF != stk1160configNTSC[i0].reg) {
311 SET(p, stk1160configNTSC[i0].reg, stk1160configNTSC[i0].set);
312 i0++;
314 } else {
315 while (0xFFF != stk1160configPAL[i0].reg) {
316 SET(p, stk1160configPAL[i0].reg, stk1160configPAL[i0].set);
317 i0++;
321 write_300(p);
323 return 0;
325 /****************************************************************************/
327 setup_saa(struct usb_device *p, bool ntsc)
329 int i0, ir;
331 if (NULL == p)
332 return -ENODEV;
333 i0 = 0;
334 if (true == ntsc) {
335 while (0xFF != saa7113configNTSC[i0].reg) {
336 ir = write_saa(p, saa7113configNTSC[i0].reg,
337 saa7113configNTSC[i0].set);
338 i0++;
340 } else {
341 while (0xFF != saa7113configPAL[i0].reg) {
342 ir = write_saa(p, saa7113configPAL[i0].reg,
343 saa7113configPAL[i0].set);
344 i0++;
347 return 0;
349 /****************************************************************************/
351 write_000(struct usb_device *p, u16 set2, u16 set0)
353 u8 igot0, igot2;
355 if (NULL == p)
356 return -ENODEV;
357 GET(p, 0x0002, &igot2);
358 GET(p, 0x0000, &igot0);
359 SET(p, 0x0002, set2);
360 SET(p, 0x0000, set0);
361 return 0;
363 /****************************************************************************/
365 write_saa(struct usb_device *p, u16 reg0, u16 set0)
367 if (NULL == p)
368 return -ENODEV;
369 SET(p, 0x200, 0x00);
370 SET(p, 0x204, reg0);
371 SET(p, 0x205, set0);
372 SET(p, 0x200, 0x01);
373 return wait_i2c(p);
375 /****************************************************************************/
376 /*--------------------------------------------------------------------------*/
378 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
379 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
380 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO SET
381 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO SET
382 * REGISTER 504: TARGET ADDRESS ON VT1612A
384 /*--------------------------------------------------------------------------*/
386 write_vt(struct usb_device *p, u16 reg0, u16 set0)
388 u8 igot;
389 u16 got502, got503;
390 u16 set502, set503;
392 if (NULL == p)
393 return -ENODEV;
394 SET(p, 0x0504, reg0);
395 SET(p, 0x0500, 0x008B);
397 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
398 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
400 JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n",
401 reg0, set0, ((got503 << 8) | got502));
403 set502 = (0x00FF & set0);
404 set503 = ((0xFF00 & set0) >> 8);
406 SET(p, 0x0504, reg0);
407 SET(p, 0x0502, set502);
408 SET(p, 0x0503, set503);
409 SET(p, 0x0500, 0x008C);
411 return 0;
413 /****************************************************************************/
414 /*--------------------------------------------------------------------------*/
416 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
417 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
418 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO GET
419 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO GET
420 * REGISTER 504: TARGET ADDRESS ON VT1612A
422 /*--------------------------------------------------------------------------*/
424 read_vt(struct usb_device *p, u16 reg0)
426 u8 igot;
427 u16 got502, got503;
429 if (NULL == p)
430 return -ENODEV;
431 SET(p, 0x0504, reg0);
432 SET(p, 0x0500, 0x008B);
434 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
435 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
437 JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", reg0, ((got503 << 8) | got502));
439 return (got503 << 8) | got502;
441 /****************************************************************************/
442 /*--------------------------------------------------------------------------*/
444 * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
446 /*--------------------------------------------------------------------------*/
448 write_300(struct usb_device *p)
450 if (NULL == p)
451 return -ENODEV;
452 SET(p, 0x300, 0x0012);
453 SET(p, 0x350, 0x002D);
454 SET(p, 0x351, 0x0001);
455 SET(p, 0x352, 0x0000);
456 SET(p, 0x353, 0x0000);
457 SET(p, 0x300, 0x0080);
458 return 0;
460 /****************************************************************************/
461 /*--------------------------------------------------------------------------*/
463 * NOTE: THE FOLLOWING IS NOT CHECKED:
464 * REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL.
466 /*--------------------------------------------------------------------------*/
468 check_saa(struct usb_device *p, bool ntsc)
470 int i0, ir, rc;
472 if (NULL == p)
473 return -ENODEV;
474 i0 = 0;
475 rc = 0;
476 if (true == ntsc) {
477 while (0xFF != saa7113configNTSC[i0].reg) {
478 if (0x0F == saa7113configNTSC[i0].reg) {
479 i0++;
480 continue;
483 ir = read_saa(p, saa7113configNTSC[i0].reg);
484 if (ir != saa7113configNTSC[i0].set) {
485 SAY("SAA register 0x%02X has 0x%02X, "
486 "expected 0x%02X\n",
487 saa7113configNTSC[i0].reg,
488 ir, saa7113configNTSC[i0].set);
489 rc--;
491 i0++;
493 } else {
494 while (0xFF != saa7113configPAL[i0].reg) {
495 if (0x0F == saa7113configPAL[i0].reg) {
496 i0++;
497 continue;
500 ir = read_saa(p, saa7113configPAL[i0].reg);
501 if (ir != saa7113configPAL[i0].set) {
502 SAY("SAA register 0x%02X has 0x%02X, "
503 "expected 0x%02X\n",
504 saa7113configPAL[i0].reg,
505 ir, saa7113configPAL[i0].set);
506 rc--;
508 i0++;
511 if (-8 > rc)
512 return rc;
513 else
514 return 0;
516 /****************************************************************************/
518 merit_saa(struct usb_device *p)
520 int rc;
522 if (NULL == p)
523 return -ENODEV;
524 rc = read_saa(p, 0x1F);
525 if ((0 > rc) || (0x02 & rc))
526 return 1 ;
527 else
528 return 0;
530 /****************************************************************************/
532 ready_saa(struct usb_device *p)
534 int j, rc, rate;
535 const int max = 5, marktime = PATIENCE/5;
536 /*--------------------------------------------------------------------------*/
538 * RETURNS 0 FOR INTERLACED 50 Hz
539 * 1 FOR NON-INTERLACED 50 Hz
540 * 2 FOR INTERLACED 60 Hz
541 * 3 FOR NON-INTERLACED 60 Hz
543 /*--------------------------------------------------------------------------*/
544 if (NULL == p)
545 return -ENODEV;
546 j = 0;
547 while (max > j) {
548 rc = read_saa(p, 0x1F);
549 if (0 <= rc) {
550 if (0 == (0x40 & rc))
551 break;
552 if (1 == (0x01 & rc))
553 break;
555 msleep(marktime);
556 j++;
558 if (max == j)
559 return -1;
560 else {
561 if (0x20 & rc) {
562 rate = 2;
563 JOT(8, "hardware detects 60 Hz\n");
564 } else {
565 rate = 0;
566 JOT(8, "hardware detects 50 Hz\n");
568 if (0x80 & rc)
569 JOT(8, "hardware detects interlacing\n");
570 else {
571 rate++;
572 JOT(8, "hardware detects no interlacing\n");
575 return 0;
577 /****************************************************************************/
578 /*--------------------------------------------------------------------------*/
580 * NOTE: THE FOLLOWING ARE NOT CHECKED:
581 * REGISTERS 0x000, 0x002: FUNCTIONALITY IS NOT KNOWN
582 * REGISTER 0x100: ACCEPT ALSO (0x80 | stk1160config....[.].set)
584 /*--------------------------------------------------------------------------*/
586 check_stk(struct usb_device *p, bool ntsc)
588 int i0, ir;
590 if (NULL == p)
591 return -ENODEV;
592 i0 = 0;
593 if (true == ntsc) {
594 while (0xFFF != stk1160configNTSC[i0].reg) {
595 if (0x000 == stk1160configNTSC[i0].reg) {
596 i0++; continue;
598 if (0x002 == stk1160configNTSC[i0].reg) {
599 i0++; continue;
601 ir = read_stk(p, stk1160configNTSC[i0].reg);
602 if (0x100 == stk1160configNTSC[i0].reg) {
603 if ((ir != (0xFF & stk1160configNTSC[i0].set)) &&
604 (ir != (0x80 | (0xFF &
605 stk1160configNTSC[i0].set))) &&
606 (0xFFFF !=
607 stk1160configNTSC[i0].set)) {
608 SAY("STK register 0x%03X has 0x%02X, "
609 "expected 0x%02X\n",
610 stk1160configNTSC[i0].reg,
611 ir, stk1160configNTSC[i0].set);
613 i0++; continue;
615 if ((ir != (0xFF & stk1160configNTSC[i0].set)) &&
616 (0xFFFF != stk1160configNTSC[i0].set)) {
617 SAY("STK register 0x%03X has 0x%02X, "
618 "expected 0x%02X\n",
619 stk1160configNTSC[i0].reg,
620 ir, stk1160configNTSC[i0].set);
622 i0++;
624 } else {
625 while (0xFFF != stk1160configPAL[i0].reg) {
626 if (0x000 == stk1160configPAL[i0].reg) {
627 i0++; continue;
629 if (0x002 == stk1160configPAL[i0].reg) {
630 i0++; continue;
632 ir = read_stk(p, stk1160configPAL[i0].reg);
633 if (0x100 == stk1160configPAL[i0].reg) {
634 if ((ir != (0xFF & stk1160configPAL[i0].set)) &&
635 (ir != (0x80 | (0xFF &
636 stk1160configPAL[i0].set))) &&
637 (0xFFFF !=
638 stk1160configPAL[i0].set)) {
639 SAY("STK register 0x%03X has 0x%02X, "
640 "expected 0x%02X\n",
641 stk1160configPAL[i0].reg,
642 ir, stk1160configPAL[i0].set);
644 i0++; continue;
646 if ((ir != (0xFF & stk1160configPAL[i0].set)) &&
647 (0xFFFF != stk1160configPAL[i0].set)) {
648 SAY("STK register 0x%03X has 0x%02X, "
649 "expected 0x%02X\n",
650 stk1160configPAL[i0].reg,
651 ir, stk1160configPAL[i0].set);
653 i0++;
656 return 0;
658 /****************************************************************************/
660 read_saa(struct usb_device *p, u16 reg0)
662 u8 igot;
664 if (NULL == p)
665 return -ENODEV;
666 SET(p, 0x208, reg0);
667 SET(p, 0x200, 0x20);
668 if (0 != wait_i2c(p))
669 return -1;
670 igot = 0;
671 GET(p, 0x0209, &igot);
672 return igot;
674 /****************************************************************************/
676 read_stk(struct usb_device *p, u32 reg0)
678 u8 igot;
680 if (NULL == p)
681 return -ENODEV;
682 igot = 0;
683 GET(p, reg0, &igot);
684 return igot;
686 /****************************************************************************/
687 /*--------------------------------------------------------------------------*/
689 * HARDWARE USERSPACE INPUT NUMBER PHYSICAL INPUT DRIVER input VALUE
691 * CVBS+S-VIDEO 0 or 1 CVBS 1
692 * FOUR-CVBS 0 or 1 CVBS1 1
693 * FOUR-CVBS 2 CVBS2 2
694 * FOUR-CVBS 3 CVBS3 3
695 * FOUR-CVBS 4 CVBS4 4
696 * CVBS+S-VIDEO 5 S-VIDEO 5
698 * WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED:
700 * mode 7 => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED)
701 * mode 9 => USE AUTOMATIC GAIN CONTROL (DEFAULT)
704 /*---------------------------------------------------------------------------*/
706 select_input(struct usb_device *p, int input, int mode)
708 int ir;
710 if (NULL == p)
711 return -ENODEV;
712 stop_100(p);
713 switch (input) {
714 case 0:
715 case 1: {
716 if (0 != write_saa(p, 0x02, 0x80)) {
717 SAY("ERROR: failed to set SAA register 0x02 for input %i\n",
718 input);
720 SET(p, 0x0000, 0x0098);
721 SET(p, 0x0002, 0x0078);
722 break;
724 case 2: {
725 if (0 != write_saa(p, 0x02, 0x80)) {
726 SAY("ERROR: failed to set SAA register 0x02 for input %i\n",
727 input);
729 SET(p, 0x0000, 0x0090);
730 SET(p, 0x0002, 0x0078);
731 break;
733 case 3: {
734 if (0 != write_saa(p, 0x02, 0x80)) {
735 SAY("ERROR: failed to set SAA register 0x02 for input %i\n",
736 input);
738 SET(p, 0x0000, 0x0088);
739 SET(p, 0x0002, 0x0078);
740 break;
742 case 4: {
743 if (0 != write_saa(p, 0x02, 0x80)) {
744 SAY("ERROR: failed to set SAA register 0x02 for input %i\n",
745 input);
747 SET(p, 0x0000, 0x0080);
748 SET(p, 0x0002, 0x0078);
749 break;
751 case 5: {
752 if (9 != mode)
753 mode = 7;
754 switch (mode) {
755 case 7: {
756 if (0 != write_saa(p, 0x02, 0x87)) {
757 SAY("ERROR: failed to set SAA register 0x02 "
758 "for input %i\n", input);
760 if (0 != write_saa(p, 0x05, 0xFF)) {
761 SAY("ERROR: failed to set SAA register 0x05 "
762 "for input %i\n", input);
764 break;
766 case 9: {
767 if (0 != write_saa(p, 0x02, 0x89)) {
768 SAY("ERROR: failed to set SAA register 0x02 "
769 "for input %i\n", input);
771 if (0 != write_saa(p, 0x05, 0x00)) {
772 SAY("ERROR: failed to set SAA register 0x05 "
773 "for input %i\n", input);
775 break;
777 default: {
778 SAY("MISTAKE: bad mode: %i\n", mode);
779 return -1;
782 if (0 != write_saa(p, 0x04, 0x00)) {
783 SAY("ERROR: failed to set SAA register 0x04 for input %i\n",
784 input);
786 if (0 != write_saa(p, 0x09, 0x80)) {
787 SAY("ERROR: failed to set SAA register 0x09 for input %i\n",
788 input);
790 SET(p, 0x0002, 0x0093);
791 break;
793 default: {
794 SAY("ERROR: bad input: %i\n", input);
795 return -1;
798 ir = read_stk(p, 0x00);
799 JOT(8, "STK register 0x00 has 0x%02X\n", ir);
800 ir = read_saa(p, 0x02);
801 JOT(8, "SAA register 0x02 has 0x%02X\n", ir);
803 start_100(p);
805 return 0;
807 /****************************************************************************/
809 set_resolution(struct usb_device *p,
810 u16 set0, u16 set1, u16 set2, u16 set3)
812 u16 u0x0111, u0x0113, u0x0115, u0x0117;
814 if (NULL == p)
815 return -ENODEV;
816 u0x0111 = ((0xFF00 & set0) >> 8);
817 u0x0113 = ((0xFF00 & set1) >> 8);
818 u0x0115 = ((0xFF00 & set2) >> 8);
819 u0x0117 = ((0xFF00 & set3) >> 8);
821 SET(p, 0x0110, (0x00FF & set0));
822 SET(p, 0x0111, u0x0111);
823 SET(p, 0x0112, (0x00FF & set1));
824 SET(p, 0x0113, u0x0113);
825 SET(p, 0x0114, (0x00FF & set2));
826 SET(p, 0x0115, u0x0115);
827 SET(p, 0x0116, (0x00FF & set3));
828 SET(p, 0x0117, u0x0117);
830 return 0;
832 /****************************************************************************/
834 start_100(struct usb_device *p)
836 u16 get116, get117, get0;
837 u8 igot116, igot117, igot;
839 if (NULL == p)
840 return -ENODEV;
841 GET(p, 0x0116, &igot116);
842 get116 = igot116;
843 GET(p, 0x0117, &igot117);
844 get117 = igot117;
845 SET(p, 0x0116, 0x0000);
846 SET(p, 0x0117, 0x0000);
848 GET(p, 0x0100, &igot);
849 get0 = igot;
850 SET(p, 0x0100, (0x80 | get0));
852 SET(p, 0x0116, get116);
853 SET(p, 0x0117, get117);
855 return 0;
857 /****************************************************************************/
859 stop_100(struct usb_device *p)
861 u16 get0;
862 u8 igot;
864 if (NULL == p)
865 return -ENODEV;
866 GET(p, 0x0100, &igot);
867 get0 = igot;
868 SET(p, 0x0100, (0x7F & get0));
869 return 0;
871 /****************************************************************************/
872 /*--------------------------------------------------------------------------*/
874 * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
876 /*--------------------------------------------------------------------------*/
878 wait_i2c(struct usb_device *p)
880 u16 get0;
881 u8 igot;
882 const int max = 2;
883 int k;
885 if (NULL == p)
886 return -ENODEV;
887 for (k = 0; k < max; k++) {
888 GET(p, 0x0201, &igot); get0 = igot;
889 switch (get0) {
890 case 0x04:
891 case 0x01: {
892 return 0;
894 case 0x00: {
895 msleep(20);
896 continue;
898 default: {
899 return get0 - 1;
903 return -1;
905 /****************************************************************************/
907 regset(struct usb_device *pusb_device, u16 index, u16 value)
909 u16 igot;
910 int rc0, rc1;
912 if (!pusb_device)
913 return -ENODEV;
914 rc1 = 0; igot = 0;
915 rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
916 (u8)0x01,
917 (u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
918 (u16)value,
919 (u16)index,
920 NULL,
921 (u16)0,
922 (int)500);
924 #ifdef NOREADBACK
926 #else
927 rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0),
928 (u8)0x00,
929 (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
930 (u16)0x00,
931 (u16)index,
932 (void *)&igot,
933 (u16)sizeof(u16),
934 (int)50000);
935 igot = 0xFF & igot;
936 switch (index) {
937 case 0x000:
938 case 0x500:
939 case 0x502:
940 case 0x503:
941 case 0x504:
942 case 0x506:
943 case 0x507: {
944 break;
946 case 0x204:
947 case 0x205:
948 case 0x350:
949 case 0x351: {
950 if (0 != (0xFF & igot)) {
951 JOT(8, "unexpected 0x%02X for STK register 0x%03X\n",
952 igot, index);
954 break;
956 default: {
957 if ((0xFF & value) != (0xFF & igot)) {
958 JOT(8, "unexpected 0x%02X != 0x%02X "
959 "for STK register 0x%03X\n",
960 igot, value, index);
962 break;
965 #endif /* ! NOREADBACK*/
967 return (0 > rc0) ? rc0 : rc1;
969 /*****************************************************************************/
971 regget(struct usb_device *pusb_device, u16 index, void *pvoid)
973 int ir;
975 if (!pusb_device)
976 return -ENODEV;
977 ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0),
978 (u8)0x00,
979 (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
980 (u16)0x00,
981 (u16)index,
982 (void *)pvoid,
983 sizeof(u8),
984 (int)50000);
985 return 0xFF & ir;
987 /*****************************************************************************/
989 wakeup_device(struct usb_device *pusb_device)
991 if (!pusb_device)
992 return -ENODEV;
993 return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
994 (u8)USB_REQ_SET_FEATURE,
995 (u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE),
996 USB_DEVICE_REMOTE_WAKEUP,
997 (u16)0,
998 (void *) NULL,
999 (u16)0,
1000 (int)50000);
1002 /*****************************************************************************/
1004 audio_setup(struct easycap *peasycap)
1006 struct usb_device *pusb_device;
1007 unsigned char buffer[1];
1008 int rc, id1, id2;
1009 /*---------------------------------------------------------------------------*/
1011 * IMPORTANT:
1012 * THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
1013 * CAUSES MUTING IF THE VALUE 0x0100 IS SENT.
1014 * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT.
1016 /*---------------------------------------------------------------------------*/
1017 const u8 request = 0x01;
1018 const u8 requesttype =
1019 (u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
1020 const u16 value_unmute = 0x0200;
1021 const u16 index = 0x0301;
1022 const u16 length = 1;
1024 if (NULL == peasycap)
1025 return -EFAULT;
1027 pusb_device = peasycap->pusb_device;
1028 if (NULL == pusb_device)
1029 return -ENODEV;
1031 JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",
1032 requesttype, request,
1033 (0x00FF & value_unmute),
1034 (0xFF00 & value_unmute) >> 8,
1035 (0x00FF & index),
1036 (0xFF00 & index) >> 8,
1037 (0x00FF & length),
1038 (0xFF00 & length) >> 8);
1040 buffer[0] = 0x01;
1042 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
1043 (u8)request,
1044 (u8)requesttype,
1045 (u16)value_unmute,
1046 (u16)index,
1047 (void *)&buffer[0],
1048 (u16)length,
1049 (int)50000);
1051 JOT(8, "0x%02X=buffer\n", *((u8 *) &buffer[0]));
1052 if (rc != (int)length) {
1053 switch (rc) {
1054 case -EPIPE: {
1055 SAY("usb_control_msg returned -EPIPE\n");
1056 break;
1058 default: {
1059 SAY("ERROR: usb_control_msg returned %i\n", rc);
1060 break;
1064 /*--------------------------------------------------------------------------*/
1066 * REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
1067 * REGISTER 506: ANALOGUE AUDIO ATTENTUATOR ???
1068 * FOR THE CVBS+S-VIDEO HARDWARE:
1069 * SETTING VALUE TO 0x0000 GIVES QUIET SOUND.
1070 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
1071 * FOR THE FOUR-CVBS HARDWARE:
1072 * SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT.
1073 * REGISTER 507: ANALOGUE AUDIO PREAMPLIFIER ON/OFF ???
1074 * FOR THE CVBS-S-VIDEO HARDWARE:
1075 * SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND.
1076 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
1078 /*--------------------------------------------------------------------------*/
1079 SET(pusb_device, 0x0500, 0x0094);
1080 SET(pusb_device, 0x0500, 0x008C);
1081 SET(pusb_device, 0x0506, 0x0001);
1082 SET(pusb_device, 0x0507, 0x0000);
1083 id1 = read_vt(pusb_device, 0x007C);
1084 id2 = read_vt(pusb_device, 0x007E);
1085 SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2);
1086 /*---------------------------------------------------------------------------*/
1088 * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
1090 /*---------------------------------------------------------------------------*/
1091 if (0 != audio_gainset(pusb_device, peasycap->gain))
1092 SAY("ERROR: audio_gainset() failed\n");
1093 check_vt(pusb_device);
1094 return 0;
1096 /*****************************************************************************/
1098 check_vt(struct usb_device *pusb_device)
1100 int igot;
1102 if (!pusb_device)
1103 return -ENODEV;
1104 igot = read_vt(pusb_device, 0x0002);
1105 if (0 > igot)
1106 SAY("ERROR: failed to read VT1612A register 0x02\n");
1107 if (0x8000 & igot)
1108 SAY("register 0x%02X muted\n", 0x02);
1110 igot = read_vt(pusb_device, 0x000E);
1111 if (0 > igot)
1112 SAY("ERROR: failed to read VT1612A register 0x0E\n");
1113 if (0x8000 & igot)
1114 SAY("register 0x%02X muted\n", 0x0E);
1116 igot = read_vt(pusb_device, 0x0010);
1117 if (0 > igot)
1118 SAY("ERROR: failed to read VT1612A register 0x10\n");
1119 if (0x8000 & igot)
1120 SAY("register 0x%02X muted\n", 0x10);
1122 igot = read_vt(pusb_device, 0x0012);
1123 if (0 > igot)
1124 SAY("ERROR: failed to read VT1612A register 0x12\n");
1125 if (0x8000 & igot)
1126 SAY("register 0x%02X muted\n", 0x12);
1128 igot = read_vt(pusb_device, 0x0014);
1129 if (0 > igot)
1130 SAY("ERROR: failed to read VT1612A register 0x14\n");
1131 if (0x8000 & igot)
1132 SAY("register 0x%02X muted\n", 0x14);
1134 igot = read_vt(pusb_device, 0x0016);
1135 if (0 > igot)
1136 SAY("ERROR: failed to read VT1612A register 0x16\n");
1137 if (0x8000 & igot)
1138 SAY("register 0x%02X muted\n", 0x16);
1140 igot = read_vt(pusb_device, 0x0018);
1141 if (0 > igot)
1142 SAY("ERROR: failed to read VT1612A register 0x18\n");
1143 if (0x8000 & igot)
1144 SAY("register 0x%02X muted\n", 0x18);
1146 igot = read_vt(pusb_device, 0x001C);
1147 if (0 > igot)
1148 SAY("ERROR: failed to read VT1612A register 0x1C\n");
1149 if (0x8000 & igot)
1150 SAY("register 0x%02X muted\n", 0x1C);
1152 return 0;
1154 /*****************************************************************************/
1155 /*---------------------------------------------------------------------------*/
1156 /* NOTE: THIS DOES INCREASE THE VOLUME DRAMATICALLY:
1157 * audio_gainset(pusb_device, 0x000F);
1159 * loud dB register 0x10 dB register 0x1C dB total
1160 * 0 -34.5 0 -34.5
1161 * .. .... . ....
1162 * 15 10.5 0 10.5
1163 * 16 12.0 0 12.0
1164 * 17 12.0 1.5 13.5
1165 * .. .... .... ....
1166 * 31 12.0 22.5 34.5
1168 /*---------------------------------------------------------------------------*/
1170 audio_gainset(struct usb_device *pusb_device, s8 loud)
1172 int igot;
1173 u8 tmp;
1174 u16 mute;
1176 if (NULL == pusb_device)
1177 return -ENODEV;
1178 if (0 > loud)
1179 loud = 0;
1180 if (31 < loud)
1181 loud = 31;
1183 write_vt(pusb_device, 0x0002, 0x8000);
1184 /*---------------------------------------------------------------------------*/
1185 igot = read_vt(pusb_device, 0x000E);
1186 if (0 > igot) {
1187 SAY("ERROR: failed to read VT1612A register 0x0E\n");
1188 mute = 0x0000;
1189 } else
1190 mute = 0x8000 & ((unsigned int)igot);
1191 mute = 0;
1193 if (16 > loud)
1194 tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1));
1195 else
1196 tmp = 0;
1198 JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp);
1199 write_vt(pusb_device, 0x000E, (mute | tmp));
1200 /*---------------------------------------------------------------------------*/
1201 igot = read_vt(pusb_device, 0x0010);
1202 if (0 > igot) {
1203 SAY("ERROR: failed to read VT1612A register 0x10\n");
1204 mute = 0x0000;
1205 } else
1206 mute = 0x8000 & ((unsigned int)igot);
1207 mute = 0;
1209 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n",
1210 mute | tmp | (tmp << 8));
1211 write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8)));
1212 write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8)));
1213 write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8)));
1214 write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8)));
1215 write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8)));
1216 /*---------------------------------------------------------------------------*/
1217 igot = read_vt(pusb_device, 0x001C);
1218 if (0 > igot) {
1219 SAY("ERROR: failed to read VT1612A register 0x1C\n");
1220 mute = 0x0000;
1221 } else
1222 mute = 0x8000 & ((unsigned int)igot);
1223 mute = 0;
1225 if (16 <= loud)
1226 tmp = 0x000F & (u8)(loud - 16);
1227 else
1228 tmp = 0;
1230 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n",
1231 mute | tmp | (tmp << 8));
1232 write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8)));
1233 write_vt(pusb_device, 0x001A, 0x0404);
1234 write_vt(pusb_device, 0x0002, 0x0000);
1235 return 0;
1237 /*****************************************************************************/
1239 audio_gainget(struct usb_device *pusb_device)
1241 int igot;
1243 if (NULL == pusb_device)
1244 return -ENODEV;
1245 igot = read_vt(pusb_device, 0x001C);
1246 if (0 > igot)
1247 SAY("ERROR: failed to read VT1612A register 0x1C\n");
1248 return igot;
1250 /*****************************************************************************/