1 /*****************************************************************************
2 * *
3 * *
4 * easycap_low.c *
5 * *
6 * *
7 *****************************************************************************/
8 /*
9 *
10 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
11 *
12 *
13 * This is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * The software is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this software; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28 /*****************************************************************************/
29 /*
30 * ACKNOWLEGEMENTS AND REFERENCES
31 * ------------------------------
32 * This driver makes use of register information contained in the Syntek
33 * Semicon DC-1125 driver hosted at
34 * http://sourceforge.net/projects/syntekdriver/.
35 * Particularly useful has been a patch to the latter driver provided by
36 * Ivor Hewitt in January 2009. The NTSC implementation is taken from the
37 * work of Ben Trask.
38 */
39 /****************************************************************************/
40
41 #include "easycap.h"
42
43
44 #define GET(X, Y, Z) do { \
45 int __rc; \
46 *(Z) = (u16)0; \
47 __rc = regget(X, Y, Z, sizeof(u8)); \
48 if (0 > __rc) { \
49 JOT(8, ":-(%i\n", __LINE__); return __rc; \
50 } \
51 } while (0)
52
53 #define SET(X, Y, Z) do { \
54 int __rc; \
55 __rc = regset(X, Y, Z); \
56 if (0 > __rc) { \
57 JOT(8, ":-(%i\n", __LINE__); return __rc; \
58 } \
59 } while (0)
60
61 /*--------------------------------------------------------------------------*/
62 static const struct stk1160config {
63 u16 reg;
64 u16 set;
65 } stk1160configPAL[] = {
66 {0x000, 0x0098},
67 {0x002, 0x0093},
68
69 {0x001, 0x0003},
70 {0x003, 0x0080},
71 {0x00D, 0x0000},
72 {0x00F, 0x0002},
73 {0x018, 0x0010},
74 {0x019, 0x0000},
75 {0x01A, 0x0014},
76 {0x01B, 0x000E},
77 {0x01C, 0x0046},
78
79 {0x100, 0x0033},
80 {0x103, 0x0000},
81 {0x104, 0x0000},
82 {0x105, 0x0000},
83 {0x106, 0x0000},
84
85 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
86 /*
87 * RESOLUTION 640x480
88 */
89 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
90 {0x110, 0x0008},
91 {0x111, 0x0000},
92 {0x112, 0x0020},
93 {0x113, 0x0000},
94 {0x114, 0x0508},
95 {0x115, 0x0005},
96 {0x116, 0x0110},
97 {0x117, 0x0001},
98 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
99
100 {0x202, 0x000F},
101 {0x203, 0x004A},
102 {0x2FF, 0x0000},
103
104 {0xFFF, 0xFFFF}
105 };
106 /*--------------------------------------------------------------------------*/
107 static const struct stk1160config stk1160configNTSC[] = {
108 {0x000, 0x0098},
109 {0x002, 0x0093},
110
111 {0x001, 0x0003},
112 {0x003, 0x0080},
113 {0x00D, 0x0000},
114 {0x00F, 0x0002},
115 {0x018, 0x0010},
116 {0x019, 0x0000},
117 {0x01A, 0x0014},
118 {0x01B, 0x000E},
119 {0x01C, 0x0046},
120
121 {0x100, 0x0033},
122 {0x103, 0x0000},
123 {0x104, 0x0000},
124 {0x105, 0x0000},
125 {0x106, 0x0000},
126
127 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
128 /*
129 * RESOLUTION 640x480
130 */
131 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
132 {0x110, 0x0008},
133 {0x111, 0x0000},
134 {0x112, 0x0003},
135 {0x113, 0x0000},
136 {0x114, 0x0508},
137 {0x115, 0x0005},
138 {0x116, 0x00F3},
139 {0x117, 0x0000},
140 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
141
142 {0x202, 0x000F},
143 {0x203, 0x004A},
144 {0x2FF, 0x0000},
145
146 {0xFFF, 0xFFFF}
147 };
148 /*--------------------------------------------------------------------------*/
149 static const struct saa7113config {
150 u8 reg;
151 u8 set;
152 } saa7113configPAL[] = {
153 {0x01, 0x08},
154 {0x02, 0x80},
155 {0x03, 0x33},
156 {0x04, 0x00},
157 {0x05, 0x00},
158 {0x06, 0xE9},
159 {0x07, 0x0D},
160 {0x08, 0x38},
161 {0x09, 0x00},
162 {0x0A, SAA_0A_DEFAULT},
163 {0x0B, SAA_0B_DEFAULT},
164 {0x0C, SAA_0C_DEFAULT},
165 {0x0D, SAA_0D_DEFAULT},
166 {0x0E, 0x01},
167 {0x0F, 0x36},
168 {0x10, 0x00},
169 {0x11, 0x0C},
170 {0x12, 0xE7},
171 {0x13, 0x00},
172 {0x15, 0x00},
173 {0x16, 0x00},
174 {0x40, 0x02},
175 {0x41, 0xFF},
176 {0x42, 0xFF},
177 {0x43, 0xFF},
178 {0x44, 0xFF},
179 {0x45, 0xFF},
180 {0x46, 0xFF},
181 {0x47, 0xFF},
182 {0x48, 0xFF},
183 {0x49, 0xFF},
184 {0x4A, 0xFF},
185 {0x4B, 0xFF},
186 {0x4C, 0xFF},
187 {0x4D, 0xFF},
188 {0x4E, 0xFF},
189 {0x4F, 0xFF},
190 {0x50, 0xFF},
191 {0x51, 0xFF},
192 {0x52, 0xFF},
193 {0x53, 0xFF},
194 {0x54, 0xFF},
195 {0x55, 0xFF},
196 {0x56, 0xFF},
197 {0x57, 0xFF},
198 {0x58, 0x40},
199 {0x59, 0x54},
200 {0x5A, 0x07},
201 {0x5B, 0x83},
202
203 {0xFF, 0xFF}
204 };
205 /*--------------------------------------------------------------------------*/
206 static const struct saa7113config saa7113configNTSC[] = {
207 {0x01, 0x08},
208 {0x02, 0x80},
209 {0x03, 0x33},
210 {0x04, 0x00},
211 {0x05, 0x00},
212 {0x06, 0xE9},
213 {0x07, 0x0D},
214 {0x08, 0x78},
215 {0x09, 0x00},
216 {0x0A, SAA_0A_DEFAULT},
217 {0x0B, SAA_0B_DEFAULT},
218 {0x0C, SAA_0C_DEFAULT},
219 {0x0D, SAA_0D_DEFAULT},
220 {0x0E, 0x01},
221 {0x0F, 0x36},
222 {0x10, 0x00},
223 {0x11, 0x0C},
224 {0x12, 0xE7},
225 {0x13, 0x00},
226 {0x15, 0x00},
227 {0x16, 0x00},
228 {0x40, 0x82},
229 {0x41, 0xFF},
230 {0x42, 0xFF},
231 {0x43, 0xFF},
232 {0x44, 0xFF},
233 {0x45, 0xFF},
234 {0x46, 0xFF},
235 {0x47, 0xFF},
236 {0x48, 0xFF},
237 {0x49, 0xFF},
238 {0x4A, 0xFF},
239 {0x4B, 0xFF},
240 {0x4C, 0xFF},
241 {0x4D, 0xFF},
242 {0x4E, 0xFF},
243 {0x4F, 0xFF},
244 {0x50, 0xFF},
245 {0x51, 0xFF},
246 {0x52, 0xFF},
247 {0x53, 0xFF},
248 {0x54, 0xFF},
249 {0x55, 0xFF},
250 {0x56, 0xFF},
251 {0x57, 0xFF},
252 {0x58, 0x40},
253 {0x59, 0x54},
254 {0x5A, 0x0A},
255 {0x5B, 0x83},
256
257 {0xFF, 0xFF}
258 };
259
regget(struct usb_device * pusb_device,u16 index,void * reg,int reg_size)260 static int regget(struct usb_device *pusb_device,
261 u16 index, void *reg, int reg_size)
262 {
263 int rc;
264
265 if (!pusb_device)
266 return -ENODEV;
267
268 rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0),
269 0x00,
270 (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
271 0x00,
272 index, reg, reg_size, 50000);
273
274 return rc;
275 }
276
regset(struct usb_device * pusb_device,u16 index,u16 value)277 static int regset(struct usb_device *pusb_device, u16 index, u16 value)
278 {
279 int rc;
280
281 if (!pusb_device)
282 return -ENODEV;
283
284 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
285 0x01,
286 (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
287 value, index, NULL, 0, 500);
288
289 if (rc < 0)
290 return rc;
291
292 if (easycap_readback) {
293 u16 igot = 0;
294 rc = regget(pusb_device, index, &igot, sizeof(igot));
295 igot = 0xFF & igot;
296 switch (index) {
297 case 0x000:
298 case 0x500:
299 case 0x502:
300 case 0x503:
301 case 0x504:
302 case 0x506:
303 case 0x507:
304 break;
305
306 case 0x204:
307 case 0x205:
308 case 0x350:
309 case 0x351:
310 if (igot)
311 JOT(8, "unexpected 0x%02X "
312 "for STK register 0x%03X\n",
313 igot, index);
314 break;
315
316 default:
317 if ((0xFF & value) != igot)
318 JOT(8, "unexpected 0x%02X != 0x%02X "
319 "for STK register 0x%03X\n",
320 igot, value, index);
321 break;
322 }
323 }
324
325 return rc;
326 }
327 /*--------------------------------------------------------------------------*/
328 /*
329 * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
330 */
331 /*--------------------------------------------------------------------------*/
wait_i2c(struct usb_device * p)332 static int wait_i2c(struct usb_device *p)
333 {
334 u16 get0;
335 u8 igot;
336 const int max = 2;
337 int k;
338
339 if (!p)
340 return -ENODEV;
341
342 for (k = 0; k < max; k++) {
343 GET(p, 0x0201, &igot); get0 = igot;
344 switch (get0) {
345 case 0x04:
346 case 0x01:
347 return 0;
348 case 0x00:
349 msleep(20);
350 continue;
351 default:
352 return get0 - 1;
353 }
354 }
355 return -1;
356 }
357
358 /****************************************************************************/
write_saa(struct usb_device * p,u16 reg0,u16 set0)359 int write_saa(struct usb_device *p, u16 reg0, u16 set0)
360 {
361 if (!p)
362 return -ENODEV;
363 SET(p, 0x200, 0x00);
364 SET(p, 0x204, reg0);
365 SET(p, 0x205, set0);
366 SET(p, 0x200, 0x01);
367 return wait_i2c(p);
368 }
369 /****************************************************************************/
370 /*--------------------------------------------------------------------------*/
371 /*
372 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
373 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
374 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO SET
375 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO SET
376 * REGISTER 504: TARGET ADDRESS ON VT1612A
377 */
378 /*--------------------------------------------------------------------------*/
write_vt(struct usb_device * p,u16 reg0,u16 set0)379 static int write_vt(struct usb_device *p, u16 reg0, u16 set0)
380 {
381 u8 igot;
382 u16 got502, got503;
383 u16 set502, set503;
384
385 if (!p)
386 return -ENODEV;
387 SET(p, 0x0504, reg0);
388 SET(p, 0x0500, 0x008B);
389
390 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
391 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
392
393 JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n",
394 reg0, set0, ((got503 << 8) | got502));
395
396 set502 = (0x00FF & set0);
397 set503 = ((0xFF00 & set0) >> 8);
398
399 SET(p, 0x0504, reg0);
400 SET(p, 0x0502, set502);
401 SET(p, 0x0503, set503);
402 SET(p, 0x0500, 0x008C);
403
404 return 0;
405 }
406 /****************************************************************************/
407 /*--------------------------------------------------------------------------*/
408 /*
409 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
410 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
411 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO GET
412 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO GET
413 * REGISTER 504: TARGET ADDRESS ON VT1612A
414 */
415 /*--------------------------------------------------------------------------*/
read_vt(struct usb_device * p,u16 reg0)416 static int read_vt(struct usb_device *p, u16 reg0)
417 {
418 u8 igot;
419 u16 got502, got503;
420
421 if (!p)
422 return -ENODEV;
423 SET(p, 0x0504, reg0);
424 SET(p, 0x0500, 0x008B);
425
426 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
427 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
428
429 JOT(16, "read_vt(., 0x%04X): has 0x%04X\n",
430 reg0, ((got503 << 8) | got502));
431
432 return (got503 << 8) | got502;
433 }
434 /****************************************************************************/
435 /*--------------------------------------------------------------------------*/
436 /*
437 * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
438 */
439 /*--------------------------------------------------------------------------*/
write_300(struct usb_device * p)440 static int write_300(struct usb_device *p)
441 {
442 if (!p)
443 return -ENODEV;
444 SET(p, 0x300, 0x0012);
445 SET(p, 0x350, 0x002D);
446 SET(p, 0x351, 0x0001);
447 SET(p, 0x352, 0x0000);
448 SET(p, 0x353, 0x0000);
449 SET(p, 0x300, 0x0080);
450 return 0;
451 }
452 /****************************************************************************/
453 /****************************************************************************/
setup_stk(struct usb_device * p,bool ntsc)454 int setup_stk(struct usb_device *p, bool ntsc)
455 {
456 int i;
457 const struct stk1160config *cfg;
458 if (!p)
459 return -ENODEV;
460 cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL;
461 for (i = 0; cfg[i].reg != 0xFFF; i++)
462 SET(p, cfg[i].reg, cfg[i].set);
463
464 write_300(p);
465
466 return 0;
467 }
468 /****************************************************************************/
setup_saa(struct usb_device * p,bool ntsc)469 int setup_saa(struct usb_device *p, bool ntsc)
470 {
471 int i, rc;
472 const struct saa7113config *cfg;
473 if (!p)
474 return -ENODEV;
475 cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL;
476 for (i = 0; cfg[i].reg != 0xFF; i++) {
477 rc = write_saa(p, cfg[i].reg, cfg[i].set);
478 if (rc)
479 dev_err(&p->dev,
480 "Failed to set SAA register %d", cfg[i].reg);
481 }
482 return 0;
483 }
484 /****************************************************************************/
merit_saa(struct usb_device * p)485 int merit_saa(struct usb_device *p)
486 {
487 int rc;
488
489 if (!p)
490 return -ENODEV;
491 rc = read_saa(p, 0x1F);
492 return ((0 > rc) || (0x02 & rc)) ? 1 : 0;
493 }
494 /****************************************************************************/
ready_saa(struct usb_device * p)495 int ready_saa(struct usb_device *p)
496 {
497 int j, rc, rate;
498 const int max = 5, marktime = PATIENCE/5;
499 /*--------------------------------------------------------------------------*/
500 /*
501 * RETURNS 0 FOR INTERLACED 50 Hz
502 * 1 FOR NON-INTERLACED 50 Hz
503 * 2 FOR INTERLACED 60 Hz
504 * 3 FOR NON-INTERLACED 60 Hz
505 */
506 /*--------------------------------------------------------------------------*/
507 if (!p)
508 return -ENODEV;
509 j = 0;
510 while (max > j) {
511 rc = read_saa(p, 0x1F);
512 if (0 <= rc) {
513 if (0 == (0x40 & rc))
514 break;
515 if (1 == (0x01 & rc))
516 break;
517 }
518 msleep(marktime);
519 j++;
520 }
521
522 if (max == j)
523 return -1;
524
525 if (0x20 & rc) {
526 rate = 2;
527 JOT(8, "hardware detects 60 Hz\n");
528 } else {
529 rate = 0;
530 JOT(8, "hardware detects 50 Hz\n");
531 }
532 if (0x80 & rc)
533 JOT(8, "hardware detects interlacing\n");
534 else {
535 rate++;
536 JOT(8, "hardware detects no interlacing\n");
537 }
538 return 0;
539 }
540 /****************************************************************************/
read_saa(struct usb_device * p,u16 reg0)541 int read_saa(struct usb_device *p, u16 reg0)
542 {
543 u8 igot;
544
545 if (!p)
546 return -ENODEV;
547 SET(p, 0x208, reg0);
548 SET(p, 0x200, 0x20);
549 if (0 != wait_i2c(p))
550 return -1;
551 igot = 0;
552 GET(p, 0x0209, &igot);
553 return igot;
554 }
555 /****************************************************************************/
read_stk(struct usb_device * p,u32 reg0)556 static int read_stk(struct usb_device *p, u32 reg0)
557 {
558 u8 igot;
559
560 if (!p)
561 return -ENODEV;
562 igot = 0;
563 GET(p, reg0, &igot);
564 return igot;
565 }
select_input(struct usb_device * p,int input,int mode)566 int select_input(struct usb_device *p, int input, int mode)
567 {
568 int ir;
569
570 if (!p)
571 return -ENODEV;
572 stop_100(p);
573 switch (input) {
574 case 0:
575 case 1: {
576 if (0 != write_saa(p, 0x02, 0x80))
577 SAY("ERROR: failed to set SAA register 0x02 "
578 "for input %i\n", input);
579
580 SET(p, 0x0000, 0x0098);
581 SET(p, 0x0002, 0x0078);
582 break;
583 }
584 case 2: {
585 if (0 != write_saa(p, 0x02, 0x80))
586 SAY("ERROR: failed to set SAA register 0x02 "
587 "for input %i\n", input);
588
589 SET(p, 0x0000, 0x0090);
590 SET(p, 0x0002, 0x0078);
591 break;
592 }
593 case 3: {
594 if (0 != write_saa(p, 0x02, 0x80))
595 SAY("ERROR: failed to set SAA register 0x02 "
596 " for input %i\n", input);
597
598 SET(p, 0x0000, 0x0088);
599 SET(p, 0x0002, 0x0078);
600 break;
601 }
602 case 4: {
603 if (0 != write_saa(p, 0x02, 0x80)) {
604 SAY("ERROR: failed to set SAA register 0x02 "
605 "for input %i\n", input);
606 }
607 SET(p, 0x0000, 0x0080);
608 SET(p, 0x0002, 0x0078);
609 break;
610 }
611 case 5: {
612 if (9 != mode)
613 mode = 7;
614 switch (mode) {
615 case 7: {
616 if (0 != write_saa(p, 0x02, 0x87))
617 SAY("ERROR: failed to set SAA register 0x02 "
618 "for input %i\n", input);
619
620 if (0 != write_saa(p, 0x05, 0xFF))
621 SAY("ERROR: failed to set SAA register 0x05 "
622 "for input %i\n", input);
623
624 break;
625 }
626 case 9: {
627 if (0 != write_saa(p, 0x02, 0x89))
628 SAY("ERROR: failed to set SAA register 0x02 "
629 "for input %i\n", input);
630
631 if (0 != write_saa(p, 0x05, 0x00))
632 SAY("ERROR: failed to set SAA register 0x05 "
633 "for input %i\n", input);
634
635 break;
636 }
637 default:
638 SAY("MISTAKE: bad mode: %i\n", mode);
639 return -1;
640 }
641
642 if (0 != write_saa(p, 0x04, 0x00))
643 SAY("ERROR: failed to set SAA register 0x04 "
644 "for input %i\n", input);
645
646 if (0 != write_saa(p, 0x09, 0x80))
647 SAY("ERROR: failed to set SAA register 0x09 "
648 "for input %i\n", input);
649
650 SET(p, 0x0002, 0x0093);
651 break;
652 }
653 default:
654 SAY("ERROR: bad input: %i\n", input);
655 return -1;
656 }
657
658 ir = read_stk(p, 0x00);
659 JOT(8, "STK register 0x00 has 0x%02X\n", ir);
660 ir = read_saa(p, 0x02);
661 JOT(8, "SAA register 0x02 has 0x%02X\n", ir);
662
663 start_100(p);
664
665 return 0;
666 }
667 /****************************************************************************/
set_resolution(struct usb_device * p,u16 set0,u16 set1,u16 set2,u16 set3)668 int set_resolution(struct usb_device *p,
669 u16 set0, u16 set1, u16 set2, u16 set3)
670 {
671 u16 u0x0111, u0x0113, u0x0115, u0x0117;
672
673 if (!p)
674 return -ENODEV;
675 u0x0111 = ((0xFF00 & set0) >> 8);
676 u0x0113 = ((0xFF00 & set1) >> 8);
677 u0x0115 = ((0xFF00 & set2) >> 8);
678 u0x0117 = ((0xFF00 & set3) >> 8);
679
680 SET(p, 0x0110, (0x00FF & set0));
681 SET(p, 0x0111, u0x0111);
682 SET(p, 0x0112, (0x00FF & set1));
683 SET(p, 0x0113, u0x0113);
684 SET(p, 0x0114, (0x00FF & set2));
685 SET(p, 0x0115, u0x0115);
686 SET(p, 0x0116, (0x00FF & set3));
687 SET(p, 0x0117, u0x0117);
688
689 return 0;
690 }
691 /****************************************************************************/
start_100(struct usb_device * p)692 int start_100(struct usb_device *p)
693 {
694 u16 get116, get117, get0;
695 u8 igot116, igot117, igot;
696
697 if (!p)
698 return -ENODEV;
699 GET(p, 0x0116, &igot116);
700 get116 = igot116;
701 GET(p, 0x0117, &igot117);
702 get117 = igot117;
703 SET(p, 0x0116, 0x0000);
704 SET(p, 0x0117, 0x0000);
705
706 GET(p, 0x0100, &igot);
707 get0 = igot;
708 SET(p, 0x0100, (0x80 | get0));
709
710 SET(p, 0x0116, get116);
711 SET(p, 0x0117, get117);
712
713 return 0;
714 }
715 /****************************************************************************/
stop_100(struct usb_device * p)716 int stop_100(struct usb_device *p)
717 {
718 u16 get0;
719 u8 igot;
720
721 if (!p)
722 return -ENODEV;
723 GET(p, 0x0100, &igot);
724 get0 = igot;
725 SET(p, 0x0100, (0x7F & get0));
726 return 0;
727 }
728 /****************************************************************************/
729 /****************************************************************************/
730 /*****************************************************************************/
easycap_wakeup_device(struct usb_device * pusb_device)731 int easycap_wakeup_device(struct usb_device *pusb_device)
732 {
733 if (!pusb_device)
734 return -ENODEV;
735
736 return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
737 USB_REQ_SET_FEATURE,
738 USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
739 USB_DEVICE_REMOTE_WAKEUP,
740 0, NULL, 0, 50000);
741 }
742 /*****************************************************************************/
easycap_audio_setup(struct easycap * peasycap)743 int easycap_audio_setup(struct easycap *peasycap)
744 {
745 struct usb_device *pusb_device;
746 u8 buffer[1];
747 int rc, id1, id2;
748 /*---------------------------------------------------------------------------*/
749 /*
750 * IMPORTANT:
751 * THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
752 * CAUSES MUTING IF THE VALUE 0x0100 IS SENT.
753 * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT.
754 */
755 /*---------------------------------------------------------------------------*/
756 const u8 request = 0x01;
757 const u8 requesttype = USB_DIR_OUT |
758 USB_TYPE_CLASS |
759 USB_RECIP_INTERFACE;
760 const u16 value_unmute = 0x0200;
761 const u16 index = 0x0301;
762 const u16 length = 1;
763
764 if (!peasycap)
765 return -EFAULT;
766
767 pusb_device = peasycap->pusb_device;
768 if (!pusb_device)
769 return -ENODEV;
770
771 JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",
772 requesttype, request,
773 (0x00FF & value_unmute),
774 (0xFF00 & value_unmute) >> 8,
775 (0x00FF & index),
776 (0xFF00 & index) >> 8,
777 (0x00FF & length),
778 (0xFF00 & length) >> 8);
779
780 buffer[0] = 0x01;
781
782 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
783 request, requesttype, value_unmute,
784 index, &buffer[0], length, 50000);
785
786 JOT(8, "0x%02X=buffer\n", buffer[0]);
787 if (rc != (int)length) {
788 switch (rc) {
789 case -EPIPE:
790 SAY("usb_control_msg returned -EPIPE\n");
791 break;
792 default:
793 SAY("ERROR: usb_control_msg returned %i\n", rc);
794 break;
795 }
796 }
797 /*--------------------------------------------------------------------------*/
798 /*
799 * REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
800 * REGISTER 506: ANALOGUE AUDIO ATTENTUATOR ???
801 * FOR THE CVBS+S-VIDEO HARDWARE:
802 * SETTING VALUE TO 0x0000 GIVES QUIET SOUND.
803 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
804 * FOR THE FOUR-CVBS HARDWARE:
805 * SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT.
806 * REGISTER 507: ANALOGUE AUDIO PREAMPLIFIER ON/OFF ???
807 * FOR THE CVBS-S-VIDEO HARDWARE:
808 * SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND.
809 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
810 */
811 /*--------------------------------------------------------------------------*/
812 SET(pusb_device, 0x0500, 0x0094);
813 SET(pusb_device, 0x0500, 0x008C);
814 SET(pusb_device, 0x0506, 0x0001);
815 SET(pusb_device, 0x0507, 0x0000);
816 id1 = read_vt(pusb_device, 0x007C);
817 id2 = read_vt(pusb_device, 0x007E);
818 SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2);
819 /*---------------------------------------------------------------------------*/
820 /*
821 * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
822 */
823 /*---------------------------------------------------------------------------*/
824 if (easycap_audio_gainset(pusb_device, peasycap->gain))
825 SAY("ERROR: audio_gainset() failed\n");
826 check_vt(pusb_device);
827 return 0;
828 }
829 /*****************************************************************************/
check_vt(struct usb_device * pusb_device)830 int check_vt(struct usb_device *pusb_device)
831 {
832 int igot;
833
834 if (!pusb_device)
835 return -ENODEV;
836 igot = read_vt(pusb_device, 0x0002);
837 if (0 > igot)
838 SAY("ERROR: failed to read VT1612A register 0x02\n");
839 if (0x8000 & igot)
840 SAY("register 0x%02X muted\n", 0x02);
841
842 igot = read_vt(pusb_device, 0x000E);
843 if (0 > igot)
844 SAY("ERROR: failed to read VT1612A register 0x0E\n");
845 if (0x8000 & igot)
846 SAY("register 0x%02X muted\n", 0x0E);
847
848 igot = read_vt(pusb_device, 0x0010);
849 if (0 > igot)
850 SAY("ERROR: failed to read VT1612A register 0x10\n");
851 if (0x8000 & igot)
852 SAY("register 0x%02X muted\n", 0x10);
853
854 igot = read_vt(pusb_device, 0x0012);
855 if (0 > igot)
856 SAY("ERROR: failed to read VT1612A register 0x12\n");
857 if (0x8000 & igot)
858 SAY("register 0x%02X muted\n", 0x12);
859
860 igot = read_vt(pusb_device, 0x0014);
861 if (0 > igot)
862 SAY("ERROR: failed to read VT1612A register 0x14\n");
863 if (0x8000 & igot)
864 SAY("register 0x%02X muted\n", 0x14);
865
866 igot = read_vt(pusb_device, 0x0016);
867 if (0 > igot)
868 SAY("ERROR: failed to read VT1612A register 0x16\n");
869 if (0x8000 & igot)
870 SAY("register 0x%02X muted\n", 0x16);
871
872 igot = read_vt(pusb_device, 0x0018);
873 if (0 > igot)
874 SAY("ERROR: failed to read VT1612A register 0x18\n");
875 if (0x8000 & igot)
876 SAY("register 0x%02X muted\n", 0x18);
877
878 igot = read_vt(pusb_device, 0x001C);
879 if (0 > igot)
880 SAY("ERROR: failed to read VT1612A register 0x1C\n");
881 if (0x8000 & igot)
882 SAY("register 0x%02X muted\n", 0x1C);
883
884 return 0;
885 }
886 /*****************************************************************************/
887 /*---------------------------------------------------------------------------*/
888 /* NOTE: THIS DOES INCREASE THE VOLUME DRAMATICALLY:
889 * audio_gainset(pusb_device, 0x000F);
890 *
891 * loud dB register 0x10 dB register 0x1C dB total
892 * 0 -34.5 0 -34.5
893 * .. .... . ....
894 * 15 10.5 0 10.5
895 * 16 12.0 0 12.0
896 * 17 12.0 1.5 13.5
897 * .. .... .... ....
898 * 31 12.0 22.5 34.5
899 */
900 /*---------------------------------------------------------------------------*/
easycap_audio_gainset(struct usb_device * pusb_device,s8 loud)901 int easycap_audio_gainset(struct usb_device *pusb_device, s8 loud)
902 {
903 int igot;
904 u8 tmp;
905 u16 mute;
906
907 if (!pusb_device)
908 return -ENODEV;
909 if (0 > loud)
910 loud = 0;
911 if (31 < loud)
912 loud = 31;
913
914 write_vt(pusb_device, 0x0002, 0x8000);
915 /*---------------------------------------------------------------------------*/
916 igot = read_vt(pusb_device, 0x000E);
917 if (0 > igot) {
918 SAY("ERROR: failed to read VT1612A register 0x0E\n");
919 mute = 0x0000;
920 } else
921 mute = 0x8000 & ((unsigned int)igot);
922 mute = 0;
923
924 if (16 > loud)
925 tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1));
926 else
927 tmp = 0;
928
929 JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp);
930 write_vt(pusb_device, 0x000E, (mute | tmp));
931 /*---------------------------------------------------------------------------*/
932 igot = read_vt(pusb_device, 0x0010);
933 if (0 > igot) {
934 SAY("ERROR: failed to read VT1612A register 0x10\n");
935 mute = 0x0000;
936 } else
937 mute = 0x8000 & ((unsigned int)igot);
938 mute = 0;
939
940 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n",
941 mute | tmp | (tmp << 8));
942 write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8)));
943 write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8)));
944 write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8)));
945 write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8)));
946 write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8)));
947 /*---------------------------------------------------------------------------*/
948 igot = read_vt(pusb_device, 0x001C);
949 if (0 > igot) {
950 SAY("ERROR: failed to read VT1612A register 0x1C\n");
951 mute = 0x0000;
952 } else
953 mute = 0x8000 & ((unsigned int)igot);
954 mute = 0;
955
956 if (16 <= loud)
957 tmp = 0x000F & (u8)(loud - 16);
958 else
959 tmp = 0;
960
961 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n",
962 mute | tmp | (tmp << 8));
963 write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8)));
964 write_vt(pusb_device, 0x001A, 0x0404);
965 write_vt(pusb_device, 0x0002, 0x0000);
966 return 0;
967 }
968 /*****************************************************************************/
969