Staging: hv: hv_mouse: unwind the initialization process a bit
[zen-stable.git] / drivers / staging / easycap / easycap_low.c
blob1f914b428c840f6b64c22ed31e3fefc43dd73971
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 #define GET(X, Y, Z) do { \
44 int __rc; \
45 *(Z) = (u16)0; \
46 __rc = regget(X, Y, Z, sizeof(u8)); \
47 if (0 > __rc) { \
48 JOT(8, ":-(%i\n", __LINE__); return __rc; \
49 } \
50 } while (0)
52 #define SET(X, Y, Z) do { \
53 int __rc; \
54 __rc = regset(X, Y, Z); \
55 if (0 > __rc) { \
56 JOT(8, ":-(%i\n", __LINE__); return __rc; \
57 } \
58 } while (0)
60 /*--------------------------------------------------------------------------*/
61 static const struct stk1160config {
62 int reg;
63 int set;
64 } stk1160configPAL[256] = {
65 {0x000, 0x0098},
66 {0x002, 0x0093},
68 {0x001, 0x0003},
69 {0x003, 0x0080},
70 {0x00D, 0x0000},
71 {0x00F, 0x0002},
72 {0x018, 0x0010},
73 {0x019, 0x0000},
74 {0x01A, 0x0014},
75 {0x01B, 0x000E},
76 {0x01C, 0x0046},
78 {0x100, 0x0033},
79 {0x103, 0x0000},
80 {0x104, 0x0000},
81 {0x105, 0x0000},
82 {0x106, 0x0000},
84 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
86 * RESOLUTION 640x480
88 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
89 {0x110, 0x0008},
90 {0x111, 0x0000},
91 {0x112, 0x0020},
92 {0x113, 0x0000},
93 {0x114, 0x0508},
94 {0x115, 0x0005},
95 {0x116, 0x0110},
96 {0x117, 0x0001},
97 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
99 {0x202, 0x000F},
100 {0x203, 0x004A},
101 {0x2FF, 0x0000},
103 {0xFFF, 0xFFFF}
105 /*--------------------------------------------------------------------------*/
106 static const struct stk1160config stk1160configNTSC[256] = {
107 {0x000, 0x0098},
108 {0x002, 0x0093},
110 {0x001, 0x0003},
111 {0x003, 0x0080},
112 {0x00D, 0x0000},
113 {0x00F, 0x0002},
114 {0x018, 0x0010},
115 {0x019, 0x0000},
116 {0x01A, 0x0014},
117 {0x01B, 0x000E},
118 {0x01C, 0x0046},
120 {0x100, 0x0033},
121 {0x103, 0x0000},
122 {0x104, 0x0000},
123 {0x105, 0x0000},
124 {0x106, 0x0000},
126 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
128 * RESOLUTION 640x480
130 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
131 {0x110, 0x0008},
132 {0x111, 0x0000},
133 {0x112, 0x0003},
134 {0x113, 0x0000},
135 {0x114, 0x0508},
136 {0x115, 0x0005},
137 {0x116, 0x00F3},
138 {0x117, 0x0000},
139 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
141 {0x202, 0x000F},
142 {0x203, 0x004A},
143 {0x2FF, 0x0000},
145 {0xFFF, 0xFFFF}
147 /*--------------------------------------------------------------------------*/
148 static const struct saa7113config {
149 int reg;
150 int set;
151 } saa7113configPAL[256] = {
152 {0x01, 0x08},
153 {0x02, 0x80},
154 {0x03, 0x33},
155 {0x04, 0x00},
156 {0x05, 0x00},
157 {0x06, 0xE9},
158 {0x07, 0x0D},
159 {0x08, 0x38},
160 {0x09, 0x00},
161 {0x0A, SAA_0A_DEFAULT},
162 {0x0B, SAA_0B_DEFAULT},
163 {0x0C, SAA_0C_DEFAULT},
164 {0x0D, SAA_0D_DEFAULT},
165 {0x0E, 0x01},
166 {0x0F, 0x36},
167 {0x10, 0x00},
168 {0x11, 0x0C},
169 {0x12, 0xE7},
170 {0x13, 0x00},
171 {0x15, 0x00},
172 {0x16, 0x00},
173 {0x40, 0x02},
174 {0x41, 0xFF},
175 {0x42, 0xFF},
176 {0x43, 0xFF},
177 {0x44, 0xFF},
178 {0x45, 0xFF},
179 {0x46, 0xFF},
180 {0x47, 0xFF},
181 {0x48, 0xFF},
182 {0x49, 0xFF},
183 {0x4A, 0xFF},
184 {0x4B, 0xFF},
185 {0x4C, 0xFF},
186 {0x4D, 0xFF},
187 {0x4E, 0xFF},
188 {0x4F, 0xFF},
189 {0x50, 0xFF},
190 {0x51, 0xFF},
191 {0x52, 0xFF},
192 {0x53, 0xFF},
193 {0x54, 0xFF},
194 {0x55, 0xFF},
195 {0x56, 0xFF},
196 {0x57, 0xFF},
197 {0x58, 0x40},
198 {0x59, 0x54},
199 {0x5A, 0x07},
200 {0x5B, 0x83},
202 {0xFF, 0xFF}
204 /*--------------------------------------------------------------------------*/
205 static const struct saa7113config saa7113configNTSC[256] = {
206 {0x01, 0x08},
207 {0x02, 0x80},
208 {0x03, 0x33},
209 {0x04, 0x00},
210 {0x05, 0x00},
211 {0x06, 0xE9},
212 {0x07, 0x0D},
213 {0x08, 0x78},
214 {0x09, 0x00},
215 {0x0A, SAA_0A_DEFAULT},
216 {0x0B, SAA_0B_DEFAULT},
217 {0x0C, SAA_0C_DEFAULT},
218 {0x0D, SAA_0D_DEFAULT},
219 {0x0E, 0x01},
220 {0x0F, 0x36},
221 {0x10, 0x00},
222 {0x11, 0x0C},
223 {0x12, 0xE7},
224 {0x13, 0x00},
225 {0x15, 0x00},
226 {0x16, 0x00},
227 {0x40, 0x82},
228 {0x41, 0xFF},
229 {0x42, 0xFF},
230 {0x43, 0xFF},
231 {0x44, 0xFF},
232 {0x45, 0xFF},
233 {0x46, 0xFF},
234 {0x47, 0xFF},
235 {0x48, 0xFF},
236 {0x49, 0xFF},
237 {0x4A, 0xFF},
238 {0x4B, 0xFF},
239 {0x4C, 0xFF},
240 {0x4D, 0xFF},
241 {0x4E, 0xFF},
242 {0x4F, 0xFF},
243 {0x50, 0xFF},
244 {0x51, 0xFF},
245 {0x52, 0xFF},
246 {0x53, 0xFF},
247 {0x54, 0xFF},
248 {0x55, 0xFF},
249 {0x56, 0xFF},
250 {0x57, 0xFF},
251 {0x58, 0x40},
252 {0x59, 0x54},
253 {0x5A, 0x0A},
254 {0x5B, 0x83},
256 {0xFF, 0xFF}
259 static int regget(struct usb_device *pusb_device,
260 u16 index, void *reg, int reg_size)
262 int rc;
264 if (!pusb_device)
265 return -ENODEV;
267 rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0),
268 0x00,
269 (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
270 0x00,
271 index, reg, reg_size, 50000);
273 return rc;
276 static int regset(struct usb_device *pusb_device, u16 index, u16 value)
278 int rc;
280 if (!pusb_device)
281 return -ENODEV;
283 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
284 0x01,
285 (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
286 value, index, NULL, 0, 500);
288 if (rc < 0)
289 return rc;
291 if (easycap_readback) {
292 u16 igot = 0;
293 rc = regget(pusb_device, index, &igot, sizeof(igot));
294 igot = 0xFF & igot;
295 switch (index) {
296 case 0x000:
297 case 0x500:
298 case 0x502:
299 case 0x503:
300 case 0x504:
301 case 0x506:
302 case 0x507:
303 break;
305 case 0x204:
306 case 0x205:
307 case 0x350:
308 case 0x351:
309 if (igot)
310 JOT(8, "unexpected 0x%02X "
311 "for STK register 0x%03X\n",
312 igot, index);
313 break;
315 default:
316 if ((0xFF & value) != igot)
317 JOT(8, "unexpected 0x%02X != 0x%02X "
318 "for STK register 0x%03X\n",
319 igot, value, index);
320 break;
324 return rc;
326 /*****************************************************************************/
328 /****************************************************************************/
329 int confirm_resolution(struct usb_device *p)
331 u8 get0, get1, get2, get3, get4, get5, get6, get7;
333 if (NULL == p)
334 return -ENODEV;
335 GET(p, 0x0110, &get0);
336 GET(p, 0x0111, &get1);
337 GET(p, 0x0112, &get2);
338 GET(p, 0x0113, &get3);
339 GET(p, 0x0114, &get4);
340 GET(p, 0x0115, &get5);
341 GET(p, 0x0116, &get6);
342 GET(p, 0x0117, &get7);
343 JOT(8, "0x%03X, 0x%03X, "
344 "0x%03X, 0x%03X, "
345 "0x%03X, 0x%03X, "
346 "0x%03X, 0x%03X\n",
347 get0, get1, get2, get3, get4, get5, get6, get7);
348 JOT(8, "....cf PAL_720x526: "
349 "0x%03X, 0x%03X, "
350 "0x%03X, 0x%03X, "
351 "0x%03X, 0x%03X, "
352 "0x%03X, 0x%03X\n",
353 0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001);
354 JOT(8, "....cf PAL_704x526: "
355 "0x%03X, 0x%03X, "
356 "0x%03X, 0x%03X, "
357 "0x%03X, 0x%03X, "
358 "0x%03X, 0x%03X\n",
359 0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001);
360 JOT(8, "....cf VGA_640x480: "
361 "0x%03X, 0x%03X, "
362 "0x%03X, 0x%03X, "
363 "0x%03X, 0x%03X, "
364 "0x%03X, 0x%03X\n",
365 0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001);
366 return 0;
368 /****************************************************************************/
369 int confirm_stream(struct usb_device *p)
371 u16 get2;
372 u8 igot;
374 if (NULL == p)
375 return -ENODEV;
376 GET(p, 0x0100, &igot); get2 = 0x80 & igot;
377 if (0x80 == get2)
378 JOT(8, "confirm_stream: OK\n");
379 else
380 JOT(8, "confirm_stream: STUCK\n");
381 return 0;
383 /****************************************************************************/
384 int setup_stk(struct usb_device *p, bool ntsc)
386 int i0;
388 if (NULL == p)
389 return -ENODEV;
390 i0 = 0;
391 if (true == ntsc) {
392 while (0xFFF != stk1160configNTSC[i0].reg) {
393 SET(p, stk1160configNTSC[i0].reg,
394 stk1160configNTSC[i0].set);
395 i0++;
397 } else {
398 while (0xFFF != stk1160configPAL[i0].reg) {
399 SET(p, stk1160configPAL[i0].reg,
400 stk1160configPAL[i0].set);
401 i0++;
405 write_300(p);
407 return 0;
409 /****************************************************************************/
410 int setup_saa(struct usb_device *p, bool ntsc)
412 int i0, ir;
414 if (NULL == p)
415 return -ENODEV;
416 i0 = 0;
417 if (true == ntsc) {
418 while (0xFF != saa7113configNTSC[i0].reg) {
419 ir = write_saa(p, saa7113configNTSC[i0].reg,
420 saa7113configNTSC[i0].set);
421 i0++;
423 } else {
424 while (0xFF != saa7113configPAL[i0].reg) {
425 ir = write_saa(p, saa7113configPAL[i0].reg,
426 saa7113configPAL[i0].set);
427 i0++;
430 return 0;
432 /****************************************************************************/
433 int write_000(struct usb_device *p, u16 set2, u16 set0)
435 u8 igot0, igot2;
437 if (NULL == p)
438 return -ENODEV;
439 GET(p, 0x0002, &igot2);
440 GET(p, 0x0000, &igot0);
441 SET(p, 0x0002, set2);
442 SET(p, 0x0000, set0);
443 return 0;
445 /****************************************************************************/
446 int write_saa(struct usb_device *p, u16 reg0, u16 set0)
448 if (NULL == p)
449 return -ENODEV;
450 SET(p, 0x200, 0x00);
451 SET(p, 0x204, reg0);
452 SET(p, 0x205, set0);
453 SET(p, 0x200, 0x01);
454 return wait_i2c(p);
456 /****************************************************************************/
457 /*--------------------------------------------------------------------------*/
459 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
460 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
461 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO SET
462 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO SET
463 * REGISTER 504: TARGET ADDRESS ON VT1612A
465 /*--------------------------------------------------------------------------*/
467 write_vt(struct usb_device *p, u16 reg0, u16 set0)
469 u8 igot;
470 u16 got502, got503;
471 u16 set502, set503;
473 if (NULL == p)
474 return -ENODEV;
475 SET(p, 0x0504, reg0);
476 SET(p, 0x0500, 0x008B);
478 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
479 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
481 JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n",
482 reg0, set0, ((got503 << 8) | got502));
484 set502 = (0x00FF & set0);
485 set503 = ((0xFF00 & set0) >> 8);
487 SET(p, 0x0504, reg0);
488 SET(p, 0x0502, set502);
489 SET(p, 0x0503, set503);
490 SET(p, 0x0500, 0x008C);
492 return 0;
494 /****************************************************************************/
495 /*--------------------------------------------------------------------------*/
497 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
498 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
499 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO GET
500 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO GET
501 * REGISTER 504: TARGET ADDRESS ON VT1612A
503 /*--------------------------------------------------------------------------*/
504 int read_vt(struct usb_device *p, u16 reg0)
506 u8 igot;
507 u16 got502, got503;
509 if (NULL == p)
510 return -ENODEV;
511 SET(p, 0x0504, reg0);
512 SET(p, 0x0500, 0x008B);
514 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
515 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
517 JOT(16, "read_vt(., 0x%04X): has 0x%04X\n",
518 reg0, ((got503 << 8) | got502));
520 return (got503 << 8) | got502;
522 /****************************************************************************/
523 /*--------------------------------------------------------------------------*/
525 * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
527 /*--------------------------------------------------------------------------*/
528 int write_300(struct usb_device *p)
530 if (NULL == p)
531 return -ENODEV;
532 SET(p, 0x300, 0x0012);
533 SET(p, 0x350, 0x002D);
534 SET(p, 0x351, 0x0001);
535 SET(p, 0x352, 0x0000);
536 SET(p, 0x353, 0x0000);
537 SET(p, 0x300, 0x0080);
538 return 0;
540 /****************************************************************************/
541 /*--------------------------------------------------------------------------*/
543 * NOTE: THE FOLLOWING IS NOT CHECKED:
544 * REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL.
546 /*--------------------------------------------------------------------------*/
547 int check_saa(struct usb_device *p, bool ntsc)
549 int i0, ir, rc;
551 if (NULL == p)
552 return -ENODEV;
553 i0 = 0;
554 rc = 0;
555 if (true == ntsc) {
556 while (0xFF != saa7113configNTSC[i0].reg) {
557 if (0x0F == saa7113configNTSC[i0].reg) {
558 i0++;
559 continue;
562 ir = read_saa(p, saa7113configNTSC[i0].reg);
563 if (ir != saa7113configNTSC[i0].set) {
564 SAY("SAA register 0x%02X has 0x%02X, "
565 "expected 0x%02X\n",
566 saa7113configNTSC[i0].reg,
567 ir, saa7113configNTSC[i0].set);
568 rc--;
570 i0++;
572 } else {
573 while (0xFF != saa7113configPAL[i0].reg) {
574 if (0x0F == saa7113configPAL[i0].reg) {
575 i0++;
576 continue;
579 ir = read_saa(p, saa7113configPAL[i0].reg);
580 if (ir != saa7113configPAL[i0].set) {
581 SAY("SAA register 0x%02X has 0x%02X, "
582 "expected 0x%02X\n",
583 saa7113configPAL[i0].reg,
584 ir, saa7113configPAL[i0].set);
585 rc--;
587 i0++;
590 if (-8 > rc)
591 return rc;
592 else
593 return 0;
595 /****************************************************************************/
596 int merit_saa(struct usb_device *p)
598 int rc;
600 if (NULL == p)
601 return -ENODEV;
602 rc = read_saa(p, 0x1F);
603 return ((0 > rc) || (0x02 & rc)) ? 1 : 0;
605 /****************************************************************************/
606 int ready_saa(struct usb_device *p)
608 int j, rc, rate;
609 const int max = 5, marktime = PATIENCE/5;
610 /*--------------------------------------------------------------------------*/
612 * RETURNS 0 FOR INTERLACED 50 Hz
613 * 1 FOR NON-INTERLACED 50 Hz
614 * 2 FOR INTERLACED 60 Hz
615 * 3 FOR NON-INTERLACED 60 Hz
617 /*--------------------------------------------------------------------------*/
618 if (NULL == p)
619 return -ENODEV;
620 j = 0;
621 while (max > j) {
622 rc = read_saa(p, 0x1F);
623 if (0 <= rc) {
624 if (0 == (0x40 & rc))
625 break;
626 if (1 == (0x01 & rc))
627 break;
629 msleep(marktime);
630 j++;
632 if (max == j)
633 return -1;
634 else {
635 if (0x20 & rc) {
636 rate = 2;
637 JOT(8, "hardware detects 60 Hz\n");
638 } else {
639 rate = 0;
640 JOT(8, "hardware detects 50 Hz\n");
642 if (0x80 & rc)
643 JOT(8, "hardware detects interlacing\n");
644 else {
645 rate++;
646 JOT(8, "hardware detects no interlacing\n");
649 return 0;
651 /****************************************************************************/
652 /*--------------------------------------------------------------------------*/
654 * NOTE: THE FOLLOWING ARE NOT CHECKED:
655 * REGISTERS 0x000, 0x002: FUNCTIONALITY IS NOT KNOWN
656 * REGISTER 0x100: ACCEPT ALSO (0x80 | stk1160config....[.].set)
658 /*--------------------------------------------------------------------------*/
659 int check_stk(struct usb_device *p, bool ntsc)
661 int i0, ir;
663 if (NULL == p)
664 return -ENODEV;
665 i0 = 0;
666 if (true == ntsc) {
667 while (0xFFF != stk1160configNTSC[i0].reg) {
668 if (0x000 == stk1160configNTSC[i0].reg) {
669 i0++; continue;
671 if (0x002 == stk1160configNTSC[i0].reg) {
672 i0++; continue;
674 ir = read_stk(p, stk1160configNTSC[i0].reg);
675 if (0x100 == stk1160configNTSC[i0].reg) {
676 if ((ir != (0xFF & stk1160configNTSC[i0].set)) &&
677 (ir != (0x80 | (0xFF & stk1160configNTSC[i0].set))) &&
678 (0xFFFF != stk1160configNTSC[i0].set)) {
679 SAY("STK register 0x%03X has 0x%02X, "
680 "expected 0x%02X\n",
681 stk1160configNTSC[i0].reg,
682 ir, stk1160configNTSC[i0].set);
684 i0++; continue;
686 if ((ir != (0xFF & stk1160configNTSC[i0].set)) &&
687 (0xFFFF != stk1160configNTSC[i0].set)) {
688 SAY("STK register 0x%03X has 0x%02X, "
689 "expected 0x%02X\n",
690 stk1160configNTSC[i0].reg,
691 ir, stk1160configNTSC[i0].set);
693 i0++;
695 } else {
696 while (0xFFF != stk1160configPAL[i0].reg) {
697 if (0x000 == stk1160configPAL[i0].reg) {
698 i0++; continue;
700 if (0x002 == stk1160configPAL[i0].reg) {
701 i0++; continue;
703 ir = read_stk(p, stk1160configPAL[i0].reg);
704 if (0x100 == stk1160configPAL[i0].reg) {
705 if ((ir != (0xFF & stk1160configPAL[i0].set)) &&
706 (ir != (0x80 | (0xFF &
707 stk1160configPAL[i0].set))) &&
708 (0xFFFF !=
709 stk1160configPAL[i0].set)) {
710 SAY("STK register 0x%03X has 0x%02X, "
711 "expected 0x%02X\n",
712 stk1160configPAL[i0].reg,
713 ir, stk1160configPAL[i0].set);
715 i0++; continue;
717 if ((ir != (0xFF & stk1160configPAL[i0].set)) &&
718 (0xFFFF != stk1160configPAL[i0].set)) {
719 SAY("STK register 0x%03X has 0x%02X, "
720 "expected 0x%02X\n",
721 stk1160configPAL[i0].reg,
722 ir, stk1160configPAL[i0].set);
724 i0++;
727 return 0;
729 /****************************************************************************/
730 int read_saa(struct usb_device *p, u16 reg0)
732 u8 igot;
734 if (NULL == p)
735 return -ENODEV;
736 SET(p, 0x208, reg0);
737 SET(p, 0x200, 0x20);
738 if (0 != wait_i2c(p))
739 return -1;
740 igot = 0;
741 GET(p, 0x0209, &igot);
742 return igot;
744 /****************************************************************************/
745 int read_stk(struct usb_device *p, u32 reg0)
747 u8 igot;
749 if (NULL == p)
750 return -ENODEV;
751 igot = 0;
752 GET(p, reg0, &igot);
753 return igot;
755 /****************************************************************************/
756 /*--------------------------------------------------------------------------*/
758 * HARDWARE USERSPACE INPUT NUMBER PHYSICAL INPUT DRIVER input VALUE
760 * CVBS+S-VIDEO 0 or 1 CVBS 1
761 * FOUR-CVBS 0 or 1 CVBS1 1
762 * FOUR-CVBS 2 CVBS2 2
763 * FOUR-CVBS 3 CVBS3 3
764 * FOUR-CVBS 4 CVBS4 4
765 * CVBS+S-VIDEO 5 S-VIDEO 5
767 * WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED:
769 * mode 7 => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED)
770 * mode 9 => USE AUTOMATIC GAIN CONTROL (DEFAULT)
773 /*---------------------------------------------------------------------------*/
775 select_input(struct usb_device *p, int input, int mode)
777 int ir;
779 if (NULL == p)
780 return -ENODEV;
781 stop_100(p);
782 switch (input) {
783 case 0:
784 case 1: {
785 if (0 != write_saa(p, 0x02, 0x80))
786 SAY("ERROR: failed to set SAA register 0x02 "
787 "for input %i\n", input);
789 SET(p, 0x0000, 0x0098);
790 SET(p, 0x0002, 0x0078);
791 break;
793 case 2: {
794 if (0 != write_saa(p, 0x02, 0x80))
795 SAY("ERROR: failed to set SAA register 0x02 "
796 "for input %i\n", input);
798 SET(p, 0x0000, 0x0090);
799 SET(p, 0x0002, 0x0078);
800 break;
802 case 3: {
803 if (0 != write_saa(p, 0x02, 0x80))
804 SAY("ERROR: failed to set SAA register 0x02 "
805 " for input %i\n", input);
807 SET(p, 0x0000, 0x0088);
808 SET(p, 0x0002, 0x0078);
809 break;
811 case 4: {
812 if (0 != write_saa(p, 0x02, 0x80)) {
813 SAY("ERROR: failed to set SAA register 0x02 "
814 "for input %i\n", input);
816 SET(p, 0x0000, 0x0080);
817 SET(p, 0x0002, 0x0078);
818 break;
820 case 5: {
821 if (9 != mode)
822 mode = 7;
823 switch (mode) {
824 case 7: {
825 if (0 != write_saa(p, 0x02, 0x87))
826 SAY("ERROR: failed to set SAA register 0x02 "
827 "for input %i\n", input);
829 if (0 != write_saa(p, 0x05, 0xFF))
830 SAY("ERROR: failed to set SAA register 0x05 "
831 "for input %i\n", input);
833 break;
835 case 9: {
836 if (0 != write_saa(p, 0x02, 0x89))
837 SAY("ERROR: failed to set SAA register 0x02 "
838 "for input %i\n", input);
840 if (0 != write_saa(p, 0x05, 0x00))
841 SAY("ERROR: failed to set SAA register 0x05 "
842 "for input %i\n", input);
844 break;
846 default:
847 SAY("MISTAKE: bad mode: %i\n", mode);
848 return -1;
851 if (0 != write_saa(p, 0x04, 0x00))
852 SAY("ERROR: failed to set SAA register 0x04 "
853 "for input %i\n", input);
855 if (0 != write_saa(p, 0x09, 0x80))
856 SAY("ERROR: failed to set SAA register 0x09 "
857 "for input %i\n", input);
859 SET(p, 0x0002, 0x0093);
860 break;
862 default:
863 SAY("ERROR: bad input: %i\n", input);
864 return -1;
867 ir = read_stk(p, 0x00);
868 JOT(8, "STK register 0x00 has 0x%02X\n", ir);
869 ir = read_saa(p, 0x02);
870 JOT(8, "SAA register 0x02 has 0x%02X\n", ir);
872 start_100(p);
874 return 0;
876 /****************************************************************************/
877 int set_resolution(struct usb_device *p,
878 u16 set0, u16 set1, u16 set2, u16 set3)
880 u16 u0x0111, u0x0113, u0x0115, u0x0117;
882 if (NULL == p)
883 return -ENODEV;
884 u0x0111 = ((0xFF00 & set0) >> 8);
885 u0x0113 = ((0xFF00 & set1) >> 8);
886 u0x0115 = ((0xFF00 & set2) >> 8);
887 u0x0117 = ((0xFF00 & set3) >> 8);
889 SET(p, 0x0110, (0x00FF & set0));
890 SET(p, 0x0111, u0x0111);
891 SET(p, 0x0112, (0x00FF & set1));
892 SET(p, 0x0113, u0x0113);
893 SET(p, 0x0114, (0x00FF & set2));
894 SET(p, 0x0115, u0x0115);
895 SET(p, 0x0116, (0x00FF & set3));
896 SET(p, 0x0117, u0x0117);
898 return 0;
900 /****************************************************************************/
901 int start_100(struct usb_device *p)
903 u16 get116, get117, get0;
904 u8 igot116, igot117, igot;
906 if (NULL == p)
907 return -ENODEV;
908 GET(p, 0x0116, &igot116);
909 get116 = igot116;
910 GET(p, 0x0117, &igot117);
911 get117 = igot117;
912 SET(p, 0x0116, 0x0000);
913 SET(p, 0x0117, 0x0000);
915 GET(p, 0x0100, &igot);
916 get0 = igot;
917 SET(p, 0x0100, (0x80 | get0));
919 SET(p, 0x0116, get116);
920 SET(p, 0x0117, get117);
922 return 0;
924 /****************************************************************************/
925 int stop_100(struct usb_device *p)
927 u16 get0;
928 u8 igot;
930 if (NULL == p)
931 return -ENODEV;
932 GET(p, 0x0100, &igot);
933 get0 = igot;
934 SET(p, 0x0100, (0x7F & get0));
935 return 0;
937 /****************************************************************************/
938 /*--------------------------------------------------------------------------*/
940 * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
942 /*--------------------------------------------------------------------------*/
943 int wait_i2c(struct usb_device *p)
945 u16 get0;
946 u8 igot;
947 const int max = 2;
948 int k;
950 if (NULL == p)
951 return -ENODEV;
953 for (k = 0; k < max; k++) {
954 GET(p, 0x0201, &igot); get0 = igot;
955 switch (get0) {
956 case 0x04:
957 case 0x01:
958 return 0;
959 case 0x00:
960 msleep(20);
961 continue;
962 default:
963 return get0 - 1;
966 return -1;
968 /****************************************************************************/
969 /*****************************************************************************/
970 int wakeup_device(struct usb_device *pusb_device)
972 if (!pusb_device)
973 return -ENODEV;
974 return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
975 USB_REQ_SET_FEATURE,
976 USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
977 USB_DEVICE_REMOTE_WAKEUP,
978 0, NULL, 0, 50000);
980 /*****************************************************************************/
982 audio_setup(struct easycap *peasycap)
984 struct usb_device *pusb_device;
985 u8 buffer[1];
986 int rc, id1, id2;
987 /*---------------------------------------------------------------------------*/
989 * IMPORTANT:
990 * THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
991 * CAUSES MUTING IF THE VALUE 0x0100 IS SENT.
992 * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT.
994 /*---------------------------------------------------------------------------*/
995 const u8 request = 0x01;
996 const u8 requesttype = USB_DIR_OUT |
997 USB_TYPE_CLASS |
998 USB_RECIP_INTERFACE;
999 const u16 value_unmute = 0x0200;
1000 const u16 index = 0x0301;
1001 const u16 length = 1;
1003 if (NULL == peasycap)
1004 return -EFAULT;
1006 pusb_device = peasycap->pusb_device;
1007 if (NULL == pusb_device)
1008 return -ENODEV;
1010 JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",
1011 requesttype, request,
1012 (0x00FF & value_unmute),
1013 (0xFF00 & value_unmute) >> 8,
1014 (0x00FF & index),
1015 (0xFF00 & index) >> 8,
1016 (0x00FF & length),
1017 (0xFF00 & length) >> 8);
1019 buffer[0] = 0x01;
1021 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
1022 request, requesttype, value_unmute,
1023 index, &buffer[0], length, 50000);
1025 JOT(8, "0x%02X=buffer\n", buffer[0]);
1026 if (rc != (int)length) {
1027 switch (rc) {
1028 case -EPIPE:
1029 SAY("usb_control_msg returned -EPIPE\n");
1030 break;
1031 default:
1032 SAY("ERROR: usb_control_msg returned %i\n", rc);
1033 break;
1036 /*--------------------------------------------------------------------------*/
1038 * REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
1039 * REGISTER 506: ANALOGUE AUDIO ATTENTUATOR ???
1040 * FOR THE CVBS+S-VIDEO HARDWARE:
1041 * SETTING VALUE TO 0x0000 GIVES QUIET SOUND.
1042 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
1043 * FOR THE FOUR-CVBS HARDWARE:
1044 * SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT.
1045 * REGISTER 507: ANALOGUE AUDIO PREAMPLIFIER ON/OFF ???
1046 * FOR THE CVBS-S-VIDEO HARDWARE:
1047 * SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND.
1048 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
1050 /*--------------------------------------------------------------------------*/
1051 SET(pusb_device, 0x0500, 0x0094);
1052 SET(pusb_device, 0x0500, 0x008C);
1053 SET(pusb_device, 0x0506, 0x0001);
1054 SET(pusb_device, 0x0507, 0x0000);
1055 id1 = read_vt(pusb_device, 0x007C);
1056 id2 = read_vt(pusb_device, 0x007E);
1057 SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2);
1058 /*---------------------------------------------------------------------------*/
1060 * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
1062 /*---------------------------------------------------------------------------*/
1063 if (0 != audio_gainset(pusb_device, peasycap->gain))
1064 SAY("ERROR: audio_gainset() failed\n");
1065 check_vt(pusb_device);
1066 return 0;
1068 /*****************************************************************************/
1069 int check_vt(struct usb_device *pusb_device)
1071 int igot;
1073 if (!pusb_device)
1074 return -ENODEV;
1075 igot = read_vt(pusb_device, 0x0002);
1076 if (0 > igot)
1077 SAY("ERROR: failed to read VT1612A register 0x02\n");
1078 if (0x8000 & igot)
1079 SAY("register 0x%02X muted\n", 0x02);
1081 igot = read_vt(pusb_device, 0x000E);
1082 if (0 > igot)
1083 SAY("ERROR: failed to read VT1612A register 0x0E\n");
1084 if (0x8000 & igot)
1085 SAY("register 0x%02X muted\n", 0x0E);
1087 igot = read_vt(pusb_device, 0x0010);
1088 if (0 > igot)
1089 SAY("ERROR: failed to read VT1612A register 0x10\n");
1090 if (0x8000 & igot)
1091 SAY("register 0x%02X muted\n", 0x10);
1093 igot = read_vt(pusb_device, 0x0012);
1094 if (0 > igot)
1095 SAY("ERROR: failed to read VT1612A register 0x12\n");
1096 if (0x8000 & igot)
1097 SAY("register 0x%02X muted\n", 0x12);
1099 igot = read_vt(pusb_device, 0x0014);
1100 if (0 > igot)
1101 SAY("ERROR: failed to read VT1612A register 0x14\n");
1102 if (0x8000 & igot)
1103 SAY("register 0x%02X muted\n", 0x14);
1105 igot = read_vt(pusb_device, 0x0016);
1106 if (0 > igot)
1107 SAY("ERROR: failed to read VT1612A register 0x16\n");
1108 if (0x8000 & igot)
1109 SAY("register 0x%02X muted\n", 0x16);
1111 igot = read_vt(pusb_device, 0x0018);
1112 if (0 > igot)
1113 SAY("ERROR: failed to read VT1612A register 0x18\n");
1114 if (0x8000 & igot)
1115 SAY("register 0x%02X muted\n", 0x18);
1117 igot = read_vt(pusb_device, 0x001C);
1118 if (0 > igot)
1119 SAY("ERROR: failed to read VT1612A register 0x1C\n");
1120 if (0x8000 & igot)
1121 SAY("register 0x%02X muted\n", 0x1C);
1123 return 0;
1125 /*****************************************************************************/
1126 /*---------------------------------------------------------------------------*/
1127 /* NOTE: THIS DOES INCREASE THE VOLUME DRAMATICALLY:
1128 * audio_gainset(pusb_device, 0x000F);
1130 * loud dB register 0x10 dB register 0x1C dB total
1131 * 0 -34.5 0 -34.5
1132 * .. .... . ....
1133 * 15 10.5 0 10.5
1134 * 16 12.0 0 12.0
1135 * 17 12.0 1.5 13.5
1136 * .. .... .... ....
1137 * 31 12.0 22.5 34.5
1139 /*---------------------------------------------------------------------------*/
1140 int audio_gainset(struct usb_device *pusb_device, s8 loud)
1142 int igot;
1143 u8 tmp;
1144 u16 mute;
1146 if (NULL == pusb_device)
1147 return -ENODEV;
1148 if (0 > loud)
1149 loud = 0;
1150 if (31 < loud)
1151 loud = 31;
1153 write_vt(pusb_device, 0x0002, 0x8000);
1154 /*---------------------------------------------------------------------------*/
1155 igot = read_vt(pusb_device, 0x000E);
1156 if (0 > igot) {
1157 SAY("ERROR: failed to read VT1612A register 0x0E\n");
1158 mute = 0x0000;
1159 } else
1160 mute = 0x8000 & ((unsigned int)igot);
1161 mute = 0;
1163 if (16 > loud)
1164 tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1));
1165 else
1166 tmp = 0;
1168 JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp);
1169 write_vt(pusb_device, 0x000E, (mute | tmp));
1170 /*---------------------------------------------------------------------------*/
1171 igot = read_vt(pusb_device, 0x0010);
1172 if (0 > igot) {
1173 SAY("ERROR: failed to read VT1612A register 0x10\n");
1174 mute = 0x0000;
1175 } else
1176 mute = 0x8000 & ((unsigned int)igot);
1177 mute = 0;
1179 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n",
1180 mute | tmp | (tmp << 8));
1181 write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8)));
1182 write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8)));
1183 write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8)));
1184 write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8)));
1185 write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8)));
1186 /*---------------------------------------------------------------------------*/
1187 igot = read_vt(pusb_device, 0x001C);
1188 if (0 > igot) {
1189 SAY("ERROR: failed to read VT1612A register 0x1C\n");
1190 mute = 0x0000;
1191 } else
1192 mute = 0x8000 & ((unsigned int)igot);
1193 mute = 0;
1195 if (16 <= loud)
1196 tmp = 0x000F & (u8)(loud - 16);
1197 else
1198 tmp = 0;
1200 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n",
1201 mute | tmp | (tmp << 8));
1202 write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8)));
1203 write_vt(pusb_device, 0x001A, 0x0404);
1204 write_vt(pusb_device, 0x0002, 0x0000);
1205 return 0;
1207 /*****************************************************************************/
1208 int audio_gainget(struct usb_device *pusb_device)
1210 int igot;
1212 if (NULL == pusb_device)
1213 return -ENODEV;
1214 igot = read_vt(pusb_device, 0x001C);
1215 if (0 > igot)
1216 SAY("ERROR: failed to read VT1612A register 0x1C\n");
1217 return igot;
1219 /*****************************************************************************/