staging/easycap: make module params private/static, fix build
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / easycap / easycap_low.c
blob28c4d1e3c02fe99e8f0482934b98277591a464dd
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"
42 #include "easycap_debug.h"
44 /*--------------------------------------------------------------------------*/
45 const struct stk1160config { int reg; int set; } stk1160configPAL[256] = {
46 {0x000, 0x0098},
47 {0x002, 0x0093},
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},
59 {0x100, 0x0033},
60 {0x103, 0x0000},
61 {0x104, 0x0000},
62 {0x105, 0x0000},
63 {0x106, 0x0000},
65 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
67 * RESOLUTION 640x480
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 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
80 {0x202, 0x000F},
81 {0x203, 0x004A},
82 {0x2FF, 0x0000},
84 {0xFFF, 0xFFFF}
86 /*--------------------------------------------------------------------------*/
87 const struct stk1160config stk1160configNTSC[256] = {
88 {0x000, 0x0098},
89 {0x002, 0x0093},
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},
101 {0x100, 0x0033},
102 {0x103, 0x0000},
103 {0x104, 0x0000},
104 {0x105, 0x0000},
105 {0x106, 0x0000},
107 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
109 * RESOLUTION 640x480
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 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
122 {0x202, 0x000F},
123 {0x203, 0x004A},
124 {0x2FF, 0x0000},
126 {0xFFF, 0xFFFF}
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},
184 {0xFF, 0xFF}
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},
242 {0xFF, 0xFF}
244 /*--------------------------------------------------------------------------*/
246 /****************************************************************************/
248 confirm_resolution(struct usb_device *p)
250 __u8 get0, get1, get2, get3, get4, get5, get6, get7;
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;
287 /****************************************************************************/
289 confirm_stream(struct usb_device *p)
291 __u16 get2;
292 __u8 igot;
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;
303 /****************************************************************************/
305 setup_stk(struct usb_device *p, bool ntsc)
307 int i0;
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++;
317 } else {
318 while (0xFFF != stk1160configPAL[i0].reg) {
319 SET(p, stk1160configPAL[i0].reg, stk1160configPAL[i0].set);
320 i0++;
324 write_300(p);
326 return 0;
328 /****************************************************************************/
330 setup_saa(struct usb_device *p, bool ntsc)
332 int i0, ir;
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++;
343 } else {
344 while (0xFF != saa7113configPAL[i0].reg) {
345 ir = write_saa(p, saa7113configPAL[i0].reg, \
346 saa7113configPAL[i0].set);
347 i0++;
350 return 0;
352 /****************************************************************************/
354 write_000(struct usb_device *p, __u16 set2, __u16 set0)
356 __u8 igot0, igot2;
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;
366 /****************************************************************************/
368 write_saa(struct usb_device *p, __u16 reg0, __u16 set0)
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);
378 /****************************************************************************/
379 /*--------------------------------------------------------------------------*/
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
387 /*--------------------------------------------------------------------------*/
389 write_vt(struct usb_device *p, __u16 reg0, __u16 set0)
391 __u8 igot;
392 __u16 got502, got503;
393 __u16 set502, set503;
395 if (NULL == p)
396 return -ENODEV;
397 SET(p, 0x0504, reg0);
398 SET(p, 0x0500, 0x008B);
400 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
401 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
403 JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", \
404 reg0, set0, ((got503 << 8) | got502));
406 set502 = (0x00FF & set0);
407 set503 = ((0xFF00 & set0) >> 8);
409 SET(p, 0x0504, reg0);
410 SET(p, 0x0502, set502);
411 SET(p, 0x0503, set503);
412 SET(p, 0x0500, 0x008C);
414 return 0;
416 /****************************************************************************/
417 /*--------------------------------------------------------------------------*/
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
425 /*--------------------------------------------------------------------------*/
427 read_vt(struct usb_device *p, __u16 reg0)
429 __u8 igot;
430 __u16 got502, got503;
432 if (NULL == p)
433 return -ENODEV;
434 SET(p, 0x0504, reg0);
435 SET(p, 0x0500, 0x008B);
437 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
438 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
440 JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", reg0, ((got503 << 8) | got502));
442 return (got503 << 8) | got502;
444 /****************************************************************************/
445 /*--------------------------------------------------------------------------*/
447 * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
449 /*--------------------------------------------------------------------------*/
451 write_300(struct usb_device *p)
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;
463 /****************************************************************************/
464 /*--------------------------------------------------------------------------*/
466 * NOTE: THE FOLLOWING IS NOT CHECKED:
467 * REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL.
469 /*--------------------------------------------------------------------------*/
471 check_saa(struct usb_device *p, bool ntsc)
473 int i0, ir, rc;
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;
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--;
494 i0++;
496 } else {
497 while (0xFF != saa7113configPAL[i0].reg) {
498 if (0x0F == saa7113configPAL[i0].reg) {
499 i0++;
500 continue;
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--;
511 i0++;
514 if (-8 > rc)
515 return rc;
516 else
517 return 0;
519 /****************************************************************************/
521 merit_saa(struct usb_device *p)
523 int rc;
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;
533 /****************************************************************************/
535 ready_saa(struct usb_device *p)
537 int j, rc, rate;
538 const int max = 5, marktime = PATIENCE/5;
539 /*--------------------------------------------------------------------------*/
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
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;
558 msleep(marktime);
559 j++;
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");
571 if (0x80 & rc)
572 JOT(8, "hardware detects interlacing\n");
573 else {
574 rate++;
575 JOT(8, "hardware detects no interlacing\n");
578 return 0;
580 /****************************************************************************/
581 /*--------------------------------------------------------------------------*/
583 * NOTE: THE FOLLOWING ARE NOT CHECKED:
584 * REGISTERS 0x000, 0x002: FUNCTIONALITY IS NOT KNOWN
585 * REGISTER 0x100: ACCEPT ALSO (0x80 | stk1160config....[.].set)
587 /*--------------------------------------------------------------------------*/
589 check_stk(struct usb_device *p, bool ntsc)
591 int i0, ir;
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;
601 if (0x002 == stk1160configNTSC[i0].reg) {
602 i0++; continue;
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);
616 i0++; continue;
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);
625 i0++;
627 } else {
628 while (0xFFF != stk1160configPAL[i0].reg) {
629 if (0x000 == stk1160configPAL[i0].reg) {
630 i0++; continue;
632 if (0x002 == stk1160configPAL[i0].reg) {
633 i0++; continue;
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);
647 i0++; continue;
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);
656 i0++;
659 return 0;
661 /****************************************************************************/
663 read_saa(struct usb_device *p, __u16 reg0)
665 __u8 igot;
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;
677 /****************************************************************************/
679 read_stk(struct usb_device *p, __u32 reg0)
681 __u8 igot;
683 if (NULL == p)
684 return -ENODEV;
685 igot = 0;
686 GET(p, reg0, &igot);
687 return igot;
689 /****************************************************************************/
690 /*--------------------------------------------------------------------------*/
692 * HARDWARE USERSPACE INPUT NUMBER PHYSICAL INPUT DRIVER input VALUE
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
701 * WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED:
703 * mode 7 => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED)
704 * mode 9 => USE AUTOMATIC GAIN CONTROL (DEFAULT)
707 /*---------------------------------------------------------------------------*/
709 select_input(struct usb_device *p, int input, int mode)
711 int ir;
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);
723 SET(p, 0x0000, 0x0098);
724 SET(p, 0x0002, 0x0078);
725 break;
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);
732 SET(p, 0x0000, 0x0090);
733 SET(p, 0x0002, 0x0078);
734 break;
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);
741 SET(p, 0x0000, 0x0088);
742 SET(p, 0x0002, 0x0078);
743 break;
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);
750 SET(p, 0x0000, 0x0080);
751 SET(p, 0x0002, 0x0078);
752 break;
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);
763 if (0 != write_saa(p, 0x05, 0xFF)) {
764 SAY("ERROR: failed to set SAA register 0x05 " \
765 "for input %i\n", input);
767 break;
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);
774 if (0 != write_saa(p, 0x05, 0x00)) {
775 SAY("ERROR: failed to set SAA register 0x05 " \
776 "for input %i\n", input);
778 break;
780 default: {
781 SAY("MISTAKE: bad mode: %i\n", mode);
782 return -1;
785 if (0 != write_saa(p, 0x04, 0x00)) {
786 SAY("ERROR: failed to set SAA register 0x04 for input %i\n", \
787 input);
789 if (0 != write_saa(p, 0x09, 0x80)) {
790 SAY("ERROR: failed to set SAA register 0x09 for input %i\n", \
791 input);
793 SET(p, 0x0002, 0x0093);
794 break;
796 default: {
797 SAY("ERROR: bad input: %i\n", input);
798 return -1;
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);
806 start_100(p);
808 return 0;
810 /****************************************************************************/
812 set_resolution(struct usb_device *p, \
813 __u16 set0, __u16 set1, __u16 set2, __u16 set3)
815 __u16 u0x0111, u0x0113, u0x0115, u0x0117;
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);
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);
833 return 0;
835 /****************************************************************************/
837 start_100(struct usb_device *p)
839 __u16 get116, get117, get0;
840 __u8 igot116, igot117, igot;
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);
851 GET(p, 0x0100, &igot);
852 get0 = igot;
853 SET(p, 0x0100, (0x80 | get0));
855 SET(p, 0x0116, get116);
856 SET(p, 0x0117, get117);
858 return 0;
860 /****************************************************************************/
862 stop_100(struct usb_device *p)
864 __u16 get0;
865 __u8 igot;
867 if (NULL == p)
868 return -ENODEV;
869 GET(p, 0x0100, &igot);
870 get0 = igot;
871 SET(p, 0x0100, (0x7F & get0));
872 return 0;
874 /****************************************************************************/
875 /*--------------------------------------------------------------------------*/
877 * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
879 /*--------------------------------------------------------------------------*/
881 wait_i2c(struct usb_device *p)
883 __u16 get0;
884 __u8 igot;
885 const int max = 2;
886 int k;
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;
897 case 0x00: {
898 msleep(20);
899 continue;
901 default: {
902 return get0 - 1;
906 return -1;
908 /****************************************************************************/
910 regset(struct usb_device *pusb_device, __u16 index, __u16 value)
912 __u16 igot;
913 int rc0, rc1;
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);
927 #if defined(NOREADBACK)
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;
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);
957 break;
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);
965 break;
968 #endif /* ! NOREADBACK*/
970 return (0 > rc0) ? rc0 : rc1;
972 /*****************************************************************************/
974 regget(struct usb_device *pusb_device, __u16 index, void *pvoid)
976 int ir;
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;
990 /*****************************************************************************/
992 wakeup_device(struct usb_device *pusb_device)
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);
1005 /*****************************************************************************/
1007 audio_setup(struct easycap *peasycap)
1009 struct usb_device *pusb_device;
1010 unsigned char buffer[1];
1011 int rc, id1, id2;
1012 /*---------------------------------------------------------------------------*/
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.
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;
1027 if (NULL == peasycap)
1028 return -EFAULT;
1030 pusb_device = peasycap->pusb_device;
1031 if (NULL == pusb_device)
1032 return -ENODEV;
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);
1043 buffer[0] = 0x01;
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);
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);
1058 /*--------------------------------------------------------------------------*/
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.
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 /*---------------------------------------------------------------------------*/
1082 * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
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;
1094 /*****************************************************************************/
1096 check_vt(struct usb_device *pusb_device)
1098 int igot;
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);
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);
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);
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);
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);
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);
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);
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);
1150 return 0;
1152 /*****************************************************************************/
1153 /*---------------------------------------------------------------------------*/
1154 /* NOTE: THIS DOES INCREASE THE VOLUME DRAMATICALLY:
1155 * audio_gainset(pusb_device, 0x000F);
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
1166 /*---------------------------------------------------------------------------*/
1168 audio_gainset(struct usb_device *pusb_device, __s8 loud)
1170 int igot;
1171 __u8 u8;
1172 __u16 mute;
1174 if (NULL == pusb_device)
1175 return -ENODEV;
1176 if (0 > loud)
1177 loud = 0;
1178 if (31 < loud)
1179 loud = 31;
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;
1191 if (16 > loud)
1192 u8 = 0x01 | (0x001F & (((__u8)(15 - loud)) << 1));
1193 else
1194 u8 = 0;
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;
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;
1223 if (16 <= loud)
1224 u8 = 0x000F & (__u8)(loud - 16);
1225 else
1226 u8 = 0;
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;
1235 /*****************************************************************************/
1237 audio_gainget(struct usb_device *pusb_device)
1239 int igot;
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;
1248 /*****************************************************************************/