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 #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)
51 
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)
59 
60 /*--------------------------------------------------------------------------*/
61 static const struct stk1160config {
62 	int reg;
63 	int set;
64 } stk1160configPAL[256] = {
65 		{0x000, 0x0098},
66 		{0x002, 0x0093},
67 
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},
77 
78 		{0x100, 0x0033},
79 		{0x103, 0x0000},
80 		{0x104, 0x0000},
81 		{0x105, 0x0000},
82 		{0x106, 0x0000},
83 
84 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
85 /*
86  *  RESOLUTION 640x480
87 */
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 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
98 
99 		{0x202, 0x000F},
100 		{0x203, 0x004A},
101 		{0x2FF, 0x0000},
102 
103 		{0xFFF, 0xFFFF}
104 };
105 /*--------------------------------------------------------------------------*/
106 static const struct stk1160config stk1160configNTSC[256] = {
107 		{0x000, 0x0098},
108 		{0x002, 0x0093},
109 
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},
119 
120 		{0x100, 0x0033},
121 		{0x103, 0x0000},
122 		{0x104, 0x0000},
123 		{0x105, 0x0000},
124 		{0x106, 0x0000},
125 
126 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
127 /*
128  *  RESOLUTION 640x480
129 */
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 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
140 
141 		{0x202, 0x000F},
142 		{0x203, 0x004A},
143 		{0x2FF, 0x0000},
144 
145 		{0xFFF, 0xFFFF}
146 };
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},
201 
202 		{0xFF, 0xFF}
203 };
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},
255 
256 		{0xFF, 0xFF}
257 };
258 
regget(struct usb_device * pusb_device,u16 index,void * reg,int reg_size)259 static int regget(struct usb_device *pusb_device,
260 		u16 index, void *reg, int reg_size)
261 {
262 	int rc;
263 
264 	if (!pusb_device)
265 		return -ENODEV;
266 
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);
272 
273 	return rc;
274 }
275 
regset(struct usb_device * pusb_device,u16 index,u16 value)276 static int regset(struct usb_device *pusb_device, u16 index, u16 value)
277 {
278 	int rc;
279 
280 	if (!pusb_device)
281 		return -ENODEV;
282 
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);
287 
288 	if (rc < 0)
289 		return rc;
290 
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;
304 
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;
314 
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;
321 		}
322 	}
323 
324 	return rc;
325 }
326 /*--------------------------------------------------------------------------*/
327 /*
328  *  FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
329 */
330 /*--------------------------------------------------------------------------*/
wait_i2c(struct usb_device * p)331 static int wait_i2c(struct usb_device *p)
332 {
333 	u16 get0;
334 	u8 igot;
335 	const int max = 2;
336 	int k;
337 
338 	if (!p)
339 		return -ENODEV;
340 
341 	for (k = 0;  k < max;  k++) {
342 		GET(p, 0x0201, &igot);  get0 = igot;
343 		switch (get0) {
344 		case 0x04:
345 		case 0x01:
346 			return 0;
347 		case 0x00:
348 			msleep(20);
349 			continue;
350 		default:
351 			return get0 - 1;
352 		}
353 	}
354 	return -1;
355 }
356 
357 /****************************************************************************/
confirm_resolution(struct usb_device * p)358 int confirm_resolution(struct usb_device *p)
359 {
360 	u8 get0, get1, get2, get3, get4, get5, get6, get7;
361 
362 	if (!p)
363 		return -ENODEV;
364 	GET(p, 0x0110, &get0);
365 	GET(p, 0x0111, &get1);
366 	GET(p, 0x0112, &get2);
367 	GET(p, 0x0113, &get3);
368 	GET(p, 0x0114, &get4);
369 	GET(p, 0x0115, &get5);
370 	GET(p, 0x0116, &get6);
371 	GET(p, 0x0117, &get7);
372 	JOT(8,  "0x%03X, 0x%03X, "
373 		"0x%03X, 0x%03X, "
374 		"0x%03X, 0x%03X, "
375 		"0x%03X, 0x%03X\n",
376 		get0, get1, get2, get3, get4, get5, get6, get7);
377 	JOT(8,  "....cf PAL_720x526: "
378 		"0x%03X, 0x%03X, "
379 		"0x%03X, 0x%03X, "
380 		"0x%03X, 0x%03X, "
381 		"0x%03X, 0x%03X\n",
382 		0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001);
383 	JOT(8,  "....cf PAL_704x526: "
384 		"0x%03X, 0x%03X, "
385 		"0x%03X, 0x%03X, "
386 		"0x%03X, 0x%03X, "
387 		"0x%03X, 0x%03X\n",
388 		0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001);
389 	JOT(8,  "....cf VGA_640x480: "
390 		"0x%03X, 0x%03X, "
391 		"0x%03X, 0x%03X, "
392 		"0x%03X, 0x%03X, "
393 		"0x%03X, 0x%03X\n",
394 		0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001);
395 	return 0;
396 }
397 /****************************************************************************/
confirm_stream(struct usb_device * p)398 int confirm_stream(struct usb_device *p)
399 {
400 	u16 get2;
401 	u8 igot;
402 
403 	if (!p)
404 		return -ENODEV;
405 	GET(p, 0x0100, &igot);  get2 = 0x80 & igot;
406 	if (0x80 == get2)
407 		JOT(8, "confirm_stream:  OK\n");
408 	else
409 		JOT(8, "confirm_stream:  STUCK\n");
410 	return 0;
411 }
412 /****************************************************************************/
setup_stk(struct usb_device * p,bool ntsc)413 int setup_stk(struct usb_device *p, bool ntsc)
414 {
415 	int i;
416 	const struct stk1160config *cfg;
417 	if (!p)
418 		return -ENODEV;
419 	cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL;
420 	for (i = 0; cfg[i].reg != 0xFFF; i++)
421 		SET(p, cfg[i].reg, cfg[i].set);
422 
423 	write_300(p);
424 
425 	return 0;
426 }
427 /****************************************************************************/
setup_saa(struct usb_device * p,bool ntsc)428 int setup_saa(struct usb_device *p, bool ntsc)
429 {
430 	int i, ir;
431 	const struct saa7113config *cfg;
432 	if (!p)
433 		return -ENODEV;
434 	cfg = (ntsc) ?  saa7113configNTSC : saa7113configPAL;
435 	for (i = 0; cfg[i].reg != 0xFF; i++)
436 		ir = write_saa(p, cfg[i].reg, cfg[i].set);
437 	return 0;
438 }
439 /****************************************************************************/
write_000(struct usb_device * p,u16 set2,u16 set0)440 int write_000(struct usb_device *p, u16 set2, u16 set0)
441 {
442 	u8 igot0, igot2;
443 
444 	if (!p)
445 		return -ENODEV;
446 	GET(p, 0x0002, &igot2);
447 	GET(p, 0x0000, &igot0);
448 	SET(p, 0x0002, set2);
449 	SET(p, 0x0000, set0);
450 	return 0;
451 }
452 /****************************************************************************/
write_saa(struct usb_device * p,u16 reg0,u16 set0)453 int write_saa(struct usb_device *p, u16 reg0, u16 set0)
454 {
455 	if (!p)
456 		return -ENODEV;
457 	SET(p, 0x200, 0x00);
458 	SET(p, 0x204, reg0);
459 	SET(p, 0x205, set0);
460 	SET(p, 0x200, 0x01);
461 	return wait_i2c(p);
462 }
463 /****************************************************************************/
464 /*--------------------------------------------------------------------------*/
465 /*
466  *  REGISTER 500:  SETTING VALUE TO 0x008B READS FROM VT1612A (?)
467  *  REGISTER 500:  SETTING VALUE TO 0x008C WRITES TO  VT1612A
468  *  REGISTER 502:  LEAST SIGNIFICANT BYTE OF VALUE TO SET
469  *  REGISTER 503:  MOST SIGNIFICANT BYTE OF VALUE TO SET
470  *  REGISTER 504:  TARGET ADDRESS ON VT1612A
471  */
472 /*--------------------------------------------------------------------------*/
473 int
write_vt(struct usb_device * p,u16 reg0,u16 set0)474 write_vt(struct usb_device *p, u16 reg0, u16 set0)
475 {
476 	u8 igot;
477 	u16 got502, got503;
478 	u16 set502, set503;
479 
480 	if (!p)
481 		return -ENODEV;
482 	SET(p, 0x0504, reg0);
483 	SET(p, 0x0500, 0x008B);
484 
485 	GET(p, 0x0502, &igot);  got502 = (0xFF & igot);
486 	GET(p, 0x0503, &igot);  got503 = (0xFF & igot);
487 
488 	JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n",
489 				reg0, set0, ((got503 << 8) | got502));
490 
491 	set502 =  (0x00FF & set0);
492 	set503 = ((0xFF00 & set0) >> 8);
493 
494 	SET(p, 0x0504, reg0);
495 	SET(p, 0x0502, set502);
496 	SET(p, 0x0503, set503);
497 	SET(p, 0x0500, 0x008C);
498 
499 	return 0;
500 }
501 /****************************************************************************/
502 /*--------------------------------------------------------------------------*/
503 /*
504  *  REGISTER 500:  SETTING VALUE TO 0x008B READS FROM VT1612A (?)
505  *  REGISTER 500:  SETTING VALUE TO 0x008C WRITES TO  VT1612A
506  *  REGISTER 502:  LEAST SIGNIFICANT BYTE OF VALUE TO GET
507  *  REGISTER 503:  MOST SIGNIFICANT BYTE OF VALUE TO GET
508  *  REGISTER 504:  TARGET ADDRESS ON VT1612A
509  */
510 /*--------------------------------------------------------------------------*/
read_vt(struct usb_device * p,u16 reg0)511 int read_vt(struct usb_device *p, u16 reg0)
512 {
513 	u8 igot;
514 	u16 got502, got503;
515 
516 	if (!p)
517 		return -ENODEV;
518 	SET(p, 0x0504, reg0);
519 	SET(p, 0x0500, 0x008B);
520 
521 	GET(p, 0x0502, &igot);  got502 = (0xFF & igot);
522 	GET(p, 0x0503, &igot);  got503 = (0xFF & igot);
523 
524 	JOT(16, "read_vt(., 0x%04X): has 0x%04X\n",
525 			reg0, ((got503 << 8) | got502));
526 
527 	return (got503 << 8) | got502;
528 }
529 /****************************************************************************/
530 /*--------------------------------------------------------------------------*/
531 /*
532  *  THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
533  */
534 /*--------------------------------------------------------------------------*/
write_300(struct usb_device * p)535 int write_300(struct usb_device *p)
536 {
537 	if (!p)
538 		return -ENODEV;
539 	SET(p, 0x300, 0x0012);
540 	SET(p, 0x350, 0x002D);
541 	SET(p, 0x351, 0x0001);
542 	SET(p, 0x352, 0x0000);
543 	SET(p, 0x353, 0x0000);
544 	SET(p, 0x300, 0x0080);
545 	return 0;
546 }
547 /****************************************************************************/
548 /*--------------------------------------------------------------------------*/
549 /*
550  *  NOTE: THE FOLLOWING IS NOT CHECKED:
551  *  REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL.
552  */
553 /*--------------------------------------------------------------------------*/
check_saa(struct usb_device * p,bool ntsc)554 int check_saa(struct usb_device *p, bool ntsc)
555 {
556 	int i, ir, rc = 0;
557 	struct saa7113config const *cfg;
558 	if (!p)
559 		return -ENODEV;
560 
561 	cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL;
562 	for (i = 0; cfg[i].reg != 0xFF; i++) {
563 		if (0x0F == cfg[i].reg)
564 			continue;
565 		ir = read_saa(p, cfg[i].reg);
566 		if (ir != cfg[i].set) {
567 			SAY("SAA register 0x%02X has 0x%02X, expected 0x%02X\n",
568 				cfg[i].reg, ir, cfg[i].set);
569 				rc--;
570 		}
571 	}
572 
573 	return (rc < -8) ? rc : 0;
574 }
575 /****************************************************************************/
merit_saa(struct usb_device * p)576 int merit_saa(struct usb_device *p)
577 {
578 	int rc;
579 
580 	if (!p)
581 		return -ENODEV;
582 	rc = read_saa(p, 0x1F);
583 	return ((0 > rc) || (0x02 & rc)) ? 1 : 0;
584 }
585 /****************************************************************************/
ready_saa(struct usb_device * p)586 int ready_saa(struct usb_device *p)
587 {
588 	int j, rc, rate;
589 	const int max = 5, marktime = PATIENCE/5;
590 /*--------------------------------------------------------------------------*/
591 /*
592  *   RETURNS    0     FOR INTERLACED       50 Hz
593  *              1     FOR NON-INTERLACED   50 Hz
594  *              2     FOR INTERLACED       60 Hz
595  *              3     FOR NON-INTERLACED   60 Hz
596 */
597 /*--------------------------------------------------------------------------*/
598 	if (!p)
599 		return -ENODEV;
600 	j = 0;
601 	while (max > j) {
602 		rc = read_saa(p, 0x1F);
603 		if (0 <= rc) {
604 			if (0 == (0x40 & rc))
605 				break;
606 			if (1 == (0x01 & rc))
607 				break;
608 		}
609 		msleep(marktime);
610 		j++;
611 	}
612 	if (max == j)
613 		return -1;
614 	else {
615 		if (0x20 & rc) {
616 			rate = 2;
617 			JOT(8, "hardware detects 60 Hz\n");
618 		} else {
619 			rate = 0;
620 			JOT(8, "hardware detects 50 Hz\n");
621 		}
622 		if (0x80 & rc)
623 			JOT(8, "hardware detects interlacing\n");
624 		else {
625 			rate++;
626 			JOT(8, "hardware detects no interlacing\n");
627 		}
628 	}
629 	return 0;
630 }
631 /****************************************************************************/
632 /*--------------------------------------------------------------------------*/
633 /*
634  *  NOTE: THE FOLLOWING ARE NOT CHECKED:
635  *  REGISTERS 0x000, 0x002:  FUNCTIONALITY IS NOT KNOWN
636  *  REGISTER  0x100:  ACCEPT ALSO (0x80 | stk1160config....[.].set)
637  */
638 /*--------------------------------------------------------------------------*/
check_stk(struct usb_device * p,bool ntsc)639 int check_stk(struct usb_device *p, bool ntsc)
640 {
641 	int i, ir;
642 	const struct stk1160config *cfg;
643 
644 	if (!p)
645 		return -ENODEV;
646 	cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL;
647 
648 	for (i = 0; 0xFFF != cfg[i].reg; i++) {
649 		if (0x000 == cfg[i].reg || 0x002 == cfg[i].reg)
650 			continue;
651 
652 
653 		ir = read_stk(p, cfg[i].reg);
654 		if (0x100 == cfg[i].reg) {
655 			if ((ir != (0xFF & cfg[i].set)) &&
656 			    (ir != (0x80 | (0xFF & cfg[i].set))) &&
657 			    (0xFFFF != cfg[i].set)) {
658 				SAY("STK reg[0x%03X]=0x%02X expected 0x%02X\n",
659 					cfg[i].reg, ir, cfg[i].set);
660 			}
661 			continue;
662 		}
663 		if ((ir != (0xFF & cfg[i].set)) && (0xFFFF != cfg[i].set))
664 			SAY("STK register 0x%03X has 0x%02X,expected 0x%02X\n",
665 				cfg[i].reg, ir, cfg[i].set);
666 	}
667 	return 0;
668 }
669 /****************************************************************************/
read_saa(struct usb_device * p,u16 reg0)670 int read_saa(struct usb_device *p, u16 reg0)
671 {
672 	u8 igot;
673 
674 	if (!p)
675 		return -ENODEV;
676 	SET(p, 0x208, reg0);
677 	SET(p, 0x200, 0x20);
678 	if (0 != wait_i2c(p))
679 		return -1;
680 	igot = 0;
681 	GET(p, 0x0209, &igot);
682 	return igot;
683 }
684 /****************************************************************************/
read_stk(struct usb_device * p,u32 reg0)685 int read_stk(struct usb_device *p, u32 reg0)
686 {
687 	u8 igot;
688 
689 	if (!p)
690 		return -ENODEV;
691 	igot = 0;
692 	GET(p, reg0, &igot);
693 	return igot;
694 }
695 /****************************************************************************/
696 /*--------------------------------------------------------------------------*/
697 /*
698  *    HARDWARE    USERSPACE INPUT NUMBER   PHYSICAL INPUT   DRIVER input VALUE
699  *
700  *  CVBS+S-VIDEO           0 or 1              CVBS                 1
701  *   FOUR-CVBS             0 or 1              CVBS1                1
702  *   FOUR-CVBS                2                CVBS2                2
703  *   FOUR-CVBS                3                CVBS3                3
704  *   FOUR-CVBS                4                CVBS4                4
705  *  CVBS+S-VIDEO              5               S-VIDEO               5
706  *
707  *  WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED:
708  *
709  *     mode  7   => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED)
710  *     mode  9   => USE AUTOMATIC GAIN CONTROL (DEFAULT)
711  *
712 */
713 /*---------------------------------------------------------------------------*/
714 int
select_input(struct usb_device * p,int input,int mode)715 select_input(struct usb_device *p, int input, int mode)
716 {
717 	int ir;
718 
719 	if (!p)
720 		return -ENODEV;
721 	stop_100(p);
722 	switch (input) {
723 	case 0:
724 	case 1: {
725 		if (0 != write_saa(p, 0x02, 0x80))
726 			SAY("ERROR: failed to set SAA register 0x02 "
727 						"for input %i\n", input);
728 
729 		SET(p, 0x0000, 0x0098);
730 		SET(p, 0x0002, 0x0078);
731 		break;
732 	}
733 	case 2: {
734 		if (0 != write_saa(p, 0x02, 0x80))
735 			SAY("ERROR: failed to set SAA register 0x02 "
736 						"for input %i\n", input);
737 
738 		SET(p, 0x0000, 0x0090);
739 		SET(p, 0x0002, 0x0078);
740 		break;
741 	}
742 	case 3: {
743 		if (0 != write_saa(p, 0x02, 0x80))
744 			SAY("ERROR: failed to set SAA register 0x02 "
745 					" for input %i\n", input);
746 
747 		SET(p, 0x0000, 0x0088);
748 		SET(p, 0x0002, 0x0078);
749 		break;
750 	}
751 	case 4: {
752 		if (0 != write_saa(p, 0x02, 0x80)) {
753 			SAY("ERROR: failed to set SAA register 0x02 "
754 						"for input %i\n", input);
755 		}
756 		SET(p, 0x0000, 0x0080);
757 		SET(p, 0x0002, 0x0078);
758 		break;
759 	}
760 	case 5: {
761 		if (9 != mode)
762 			mode = 7;
763 		switch (mode) {
764 		case 7: {
765 			if (0 != write_saa(p, 0x02, 0x87))
766 				SAY("ERROR: failed to set SAA register 0x02 "
767 						"for input %i\n", input);
768 
769 			if (0 != write_saa(p, 0x05, 0xFF))
770 				SAY("ERROR: failed to set SAA register 0x05 "
771 						"for input %i\n", input);
772 
773 			break;
774 		}
775 		case 9: {
776 			if (0 != write_saa(p, 0x02, 0x89))
777 				SAY("ERROR: failed to set SAA register 0x02 "
778 						"for input %i\n", input);
779 
780 			if (0 != write_saa(p, 0x05, 0x00))
781 				SAY("ERROR: failed to set SAA register 0x05 "
782 						"for input %i\n", input);
783 
784 			break;
785 		}
786 		default:
787 			SAY("MISTAKE:  bad mode: %i\n", mode);
788 			return -1;
789 		}
790 
791 		if (0 != write_saa(p, 0x04, 0x00))
792 			SAY("ERROR: failed to set SAA register 0x04 "
793 					"for input %i\n", input);
794 
795 		if (0 != write_saa(p, 0x09, 0x80))
796 			SAY("ERROR: failed to set SAA register 0x09 "
797 						"for input %i\n", input);
798 
799 		SET(p, 0x0002, 0x0093);
800 		break;
801 	}
802 	default:
803 		SAY("ERROR:  bad input: %i\n", input);
804 		return -1;
805 	}
806 
807 	ir = read_stk(p, 0x00);
808 	JOT(8, "STK register 0x00 has 0x%02X\n", ir);
809 	ir = read_saa(p, 0x02);
810 	JOT(8, "SAA register 0x02 has 0x%02X\n", ir);
811 
812 	start_100(p);
813 
814 	return 0;
815 }
816 /****************************************************************************/
set_resolution(struct usb_device * p,u16 set0,u16 set1,u16 set2,u16 set3)817 int set_resolution(struct usb_device *p,
818 		   u16 set0, u16 set1, u16 set2, u16 set3)
819 {
820 	u16 u0x0111, u0x0113, u0x0115, u0x0117;
821 
822 	if (!p)
823 		return -ENODEV;
824 	u0x0111 = ((0xFF00 & set0) >> 8);
825 	u0x0113 = ((0xFF00 & set1) >> 8);
826 	u0x0115 = ((0xFF00 & set2) >> 8);
827 	u0x0117 = ((0xFF00 & set3) >> 8);
828 
829 	SET(p, 0x0110, (0x00FF & set0));
830 	SET(p, 0x0111, u0x0111);
831 	SET(p, 0x0112, (0x00FF & set1));
832 	SET(p, 0x0113, u0x0113);
833 	SET(p, 0x0114, (0x00FF & set2));
834 	SET(p, 0x0115, u0x0115);
835 	SET(p, 0x0116, (0x00FF & set3));
836 	SET(p, 0x0117, u0x0117);
837 
838 	return 0;
839 }
840 /****************************************************************************/
start_100(struct usb_device * p)841 int start_100(struct usb_device *p)
842 {
843 	u16 get116, get117, get0;
844 	u8 igot116, igot117, igot;
845 
846 	if (!p)
847 		return -ENODEV;
848 	GET(p, 0x0116, &igot116);
849 	get116 = igot116;
850 	GET(p, 0x0117, &igot117);
851 	get117 = igot117;
852 	SET(p, 0x0116, 0x0000);
853 	SET(p, 0x0117, 0x0000);
854 
855 	GET(p, 0x0100, &igot);
856 	get0 = igot;
857 	SET(p, 0x0100, (0x80 | get0));
858 
859 	SET(p, 0x0116, get116);
860 	SET(p, 0x0117, get117);
861 
862 	return 0;
863 }
864 /****************************************************************************/
stop_100(struct usb_device * p)865 int stop_100(struct usb_device *p)
866 {
867 	u16 get0;
868 	u8 igot;
869 
870 	if (!p)
871 		return -ENODEV;
872 	GET(p, 0x0100, &igot);
873 	get0 = igot;
874 	SET(p, 0x0100, (0x7F & get0));
875 	return 0;
876 }
877 /****************************************************************************/
878 /****************************************************************************/
879 /*****************************************************************************/
wakeup_device(struct usb_device * pusb_device)880 int wakeup_device(struct usb_device *pusb_device)
881 {
882 	if (!pusb_device)
883 		return -ENODEV;
884 	return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
885 			USB_REQ_SET_FEATURE,
886 			USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
887 			USB_DEVICE_REMOTE_WAKEUP,
888 			0, NULL, 0, 50000);
889 }
890 /*****************************************************************************/
891 int
audio_setup(struct easycap * peasycap)892 audio_setup(struct easycap *peasycap)
893 {
894 	struct usb_device *pusb_device;
895 	u8 buffer[1];
896 	int rc, id1, id2;
897 /*---------------------------------------------------------------------------*/
898 /*
899  *                                IMPORTANT:
900  *  THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
901  *  CAUSES MUTING IF THE VALUE 0x0100 IS SENT.
902  *  TO ENABLE AUDIO  THE VALUE 0x0200 MUST BE SENT.
903  */
904 /*---------------------------------------------------------------------------*/
905 	const u8 request = 0x01;
906 	const u8 requesttype = USB_DIR_OUT |
907 			       USB_TYPE_CLASS |
908 			       USB_RECIP_INTERFACE;
909 	const u16 value_unmute = 0x0200;
910 	const u16 index = 0x0301;
911 	const u16 length = 1;
912 
913 	if (!peasycap)
914 		return -EFAULT;
915 
916 	pusb_device = peasycap->pusb_device;
917 	if (!pusb_device)
918 		return -ENODEV;
919 
920 	JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",
921 				requesttype, request,
922 				(0x00FF & value_unmute),
923 				(0xFF00 & value_unmute) >> 8,
924 				(0x00FF & index),
925 				(0xFF00 & index) >> 8,
926 				(0x00FF & length),
927 				(0xFF00 & length) >> 8);
928 
929 	buffer[0] = 0x01;
930 
931 	rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
932 				request, requesttype, value_unmute,
933 				index, &buffer[0], length, 50000);
934 
935 	JOT(8, "0x%02X=buffer\n", buffer[0]);
936 	if (rc != (int)length) {
937 		switch (rc) {
938 		case -EPIPE:
939 			SAY("usb_control_msg returned -EPIPE\n");
940 			break;
941 		default:
942 			SAY("ERROR: usb_control_msg returned %i\n", rc);
943 			break;
944 		}
945 	}
946 /*--------------------------------------------------------------------------*/
947 /*
948  *  REGISTER 500:  SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
949  *  REGISTER 506:  ANALOGUE AUDIO ATTENTUATOR ???
950  *                 FOR THE CVBS+S-VIDEO HARDWARE:
951  *                    SETTING VALUE TO 0x0000 GIVES QUIET SOUND.
952  *                    THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
953  *                 FOR THE FOUR-CVBS HARDWARE:
954  *                    SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT.
955  *  REGISTER 507:  ANALOGUE AUDIO PREAMPLIFIER ON/OFF ???
956  *                 FOR THE CVBS-S-VIDEO HARDWARE:
957  *                    SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND.
958  *                    THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
959  */
960 /*--------------------------------------------------------------------------*/
961 	SET(pusb_device, 0x0500, 0x0094);
962 	SET(pusb_device, 0x0500, 0x008C);
963 	SET(pusb_device, 0x0506, 0x0001);
964 	SET(pusb_device, 0x0507, 0x0000);
965 	id1 = read_vt(pusb_device, 0x007C);
966 	id2 = read_vt(pusb_device, 0x007E);
967 	SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2);
968 /*---------------------------------------------------------------------------*/
969 /*
970  *  SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
971 */
972 /*---------------------------------------------------------------------------*/
973 	if (0 != audio_gainset(pusb_device, peasycap->gain))
974 		SAY("ERROR: audio_gainset() failed\n");
975 	check_vt(pusb_device);
976 	return 0;
977 }
978 /*****************************************************************************/
check_vt(struct usb_device * pusb_device)979 int check_vt(struct usb_device *pusb_device)
980 {
981 	int igot;
982 
983 	if (!pusb_device)
984 		return -ENODEV;
985 	igot = read_vt(pusb_device, 0x0002);
986 	if (0 > igot)
987 		SAY("ERROR: failed to read VT1612A register 0x02\n");
988 	if (0x8000 & igot)
989 		SAY("register 0x%02X muted\n", 0x02);
990 
991 	igot = read_vt(pusb_device, 0x000E);
992 	if (0 > igot)
993 		SAY("ERROR: failed to read VT1612A register 0x0E\n");
994 	if (0x8000 & igot)
995 		SAY("register 0x%02X muted\n", 0x0E);
996 
997 	igot = read_vt(pusb_device, 0x0010);
998 	if (0 > igot)
999 		SAY("ERROR: failed to read VT1612A register 0x10\n");
1000 	if (0x8000 & igot)
1001 		SAY("register 0x%02X muted\n", 0x10);
1002 
1003 	igot = read_vt(pusb_device, 0x0012);
1004 	if (0 > igot)
1005 		SAY("ERROR: failed to read VT1612A register 0x12\n");
1006 	if (0x8000 & igot)
1007 		SAY("register 0x%02X muted\n", 0x12);
1008 
1009 	igot = read_vt(pusb_device, 0x0014);
1010 	if (0 > igot)
1011 		SAY("ERROR: failed to read VT1612A register 0x14\n");
1012 	if (0x8000 & igot)
1013 		SAY("register 0x%02X muted\n", 0x14);
1014 
1015 	igot = read_vt(pusb_device, 0x0016);
1016 	if (0 > igot)
1017 		SAY("ERROR: failed to read VT1612A register 0x16\n");
1018 	if (0x8000 & igot)
1019 		SAY("register 0x%02X muted\n", 0x16);
1020 
1021 	igot = read_vt(pusb_device, 0x0018);
1022 	if (0 > igot)
1023 		SAY("ERROR: failed to read VT1612A register 0x18\n");
1024 	if (0x8000 & igot)
1025 		SAY("register 0x%02X muted\n", 0x18);
1026 
1027 	igot = read_vt(pusb_device, 0x001C);
1028 	if (0 > igot)
1029 		SAY("ERROR: failed to read VT1612A register 0x1C\n");
1030 	if (0x8000 & igot)
1031 		SAY("register 0x%02X muted\n", 0x1C);
1032 
1033 	return 0;
1034 }
1035 /*****************************************************************************/
1036 /*---------------------------------------------------------------------------*/
1037 /*  NOTE:  THIS DOES INCREASE THE VOLUME DRAMATICALLY:
1038  *                      audio_gainset(pusb_device, 0x000F);
1039  *
1040  *       loud        dB  register 0x10      dB register 0x1C    dB total
1041  *         0               -34.5                   0             -34.5
1042  *        ..                ....                   .              ....
1043  *        15                10.5                   0              10.5
1044  *        16                12.0                   0              12.0
1045  *        17                12.0                   1.5            13.5
1046  *        ..                ....                  ....            ....
1047  *        31                12.0                  22.5            34.5
1048 */
1049 /*---------------------------------------------------------------------------*/
audio_gainset(struct usb_device * pusb_device,s8 loud)1050 int audio_gainset(struct usb_device *pusb_device, s8 loud)
1051 {
1052 	int igot;
1053 	u8 tmp;
1054 	u16 mute;
1055 
1056 	if (!pusb_device)
1057 		return -ENODEV;
1058 	if (0 > loud)
1059 		loud = 0;
1060 	if (31 < loud)
1061 		loud = 31;
1062 
1063 	write_vt(pusb_device, 0x0002, 0x8000);
1064 /*---------------------------------------------------------------------------*/
1065 	igot = read_vt(pusb_device, 0x000E);
1066 	if (0 > igot) {
1067 		SAY("ERROR: failed to read VT1612A register 0x0E\n");
1068 		mute = 0x0000;
1069 	} else
1070 		mute = 0x8000 & ((unsigned int)igot);
1071 	mute = 0;
1072 
1073 	if (16 > loud)
1074 		tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1));
1075 	else
1076 		tmp = 0;
1077 
1078 	JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp);
1079 	write_vt(pusb_device, 0x000E, (mute | tmp));
1080 /*---------------------------------------------------------------------------*/
1081 	igot = read_vt(pusb_device, 0x0010);
1082 	if (0 > igot) {
1083 		SAY("ERROR: failed to read VT1612A register 0x10\n");
1084 		mute = 0x0000;
1085 	} else
1086 		mute = 0x8000 & ((unsigned int)igot);
1087 	mute = 0;
1088 
1089 	JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n",
1090 						mute | tmp | (tmp << 8));
1091 	write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8)));
1092 	write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8)));
1093 	write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8)));
1094 	write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8)));
1095 	write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8)));
1096 /*---------------------------------------------------------------------------*/
1097 	igot = read_vt(pusb_device, 0x001C);
1098 	if (0 > igot) {
1099 		SAY("ERROR: failed to read VT1612A register 0x1C\n");
1100 		mute = 0x0000;
1101 	} else
1102 		mute = 0x8000 & ((unsigned int)igot);
1103 	mute = 0;
1104 
1105 	if (16 <= loud)
1106 		tmp = 0x000F & (u8)(loud - 16);
1107 	else
1108 		tmp = 0;
1109 
1110 	JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n",
1111 						mute | tmp | (tmp << 8));
1112 	write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8)));
1113 	write_vt(pusb_device, 0x001A, 0x0404);
1114 	write_vt(pusb_device, 0x0002, 0x0000);
1115 	return 0;
1116 }
1117 /*****************************************************************************/
audio_gainget(struct usb_device * pusb_device)1118 int audio_gainget(struct usb_device *pusb_device)
1119 {
1120 	int igot;
1121 
1122 	if (!pusb_device)
1123 		return -ENODEV;
1124 	igot = read_vt(pusb_device, 0x001C);
1125 	if (0 > igot)
1126 		SAY("ERROR: failed to read VT1612A register 0x1C\n");
1127 	return igot;
1128 }
1129 /*****************************************************************************/
1130