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/*--------------------------------------------------------------------------*/
62static 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/*--------------------------------------------------------------------------*/
107static 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/*--------------------------------------------------------------------------*/
149static 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/*--------------------------------------------------------------------------*/
206static 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
260static 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
277static 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/*--------------------------------------------------------------------------*/
332static 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/****************************************************************************/
359int 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/*--------------------------------------------------------------------------*/
379static 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/*--------------------------------------------------------------------------*/
416static 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/*--------------------------------------------------------------------------*/
440static 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/****************************************************************************/
454int 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/****************************************************************************/
469int 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/****************************************************************************/
485int 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/****************************************************************************/
495int 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/****************************************************************************/
541int 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/****************************************************************************/
556static 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}
566int 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/****************************************************************************/
668int 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/****************************************************************************/
692int 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/****************************************************************************/
716int 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/*****************************************************************************/
731int 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/*****************************************************************************/
743int 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/*****************************************************************************/
830int 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/*---------------------------------------------------------------------------*/
901int 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