]> Pileus Git - ~andy/linux/blob - drivers/staging/media/easycap/easycap_low.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
[~andy/linux] / drivers / staging / media / easycap / easycap_low.c
1 /*****************************************************************************
2 *                                                                            *
3 *                                                                            *
4 *  easycap_low.c                                                             *
5 *                                                                            *
6 *                                                                            *
7 *****************************************************************************/
8 /*
9  *
10  *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
11  *
12  *
13  *  This is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  The software is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this software; if not, write to the Free Software
25  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27 */
28 /*****************************************************************************/
29 /*
30  *  ACKNOWLEGEMENTS AND REFERENCES
31  *  ------------------------------
32  *  This driver makes use of register information contained in the Syntek
33  *  Semicon DC-1125 driver hosted at
34  *               http://sourceforge.net/projects/syntekdriver/.
35  *  Particularly useful has been a patch to the latter driver provided by
36  *  Ivor Hewitt in January 2009.  The NTSC implementation is taken from the
37  *  work of Ben Trask.
38 */
39 /****************************************************************************/
40
41 #include "easycap.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
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
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 /*--------------------------------------------------------------------------*/
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 /****************************************************************************/
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 /*--------------------------------------------------------------------------*/
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 /*--------------------------------------------------------------------------*/
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 /*--------------------------------------------------------------------------*/
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 /****************************************************************************/
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 /****************************************************************************/
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 /****************************************************************************/
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 /****************************************************************************/
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 /****************************************************************************/
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 /****************************************************************************/
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 }
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 /****************************************************************************/
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 /****************************************************************************/
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 /****************************************************************************/
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 /*****************************************************************************/
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 /*****************************************************************************/
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 /*****************************************************************************/
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 /*---------------------------------------------------------------------------*/
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 /*****************************************************************************/