easycap_low.c revision 4860c73804c6e7ef8e69f98958489bb2bea6f6d2
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/*--------------------------------------------------------------------------*/
61static 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/*--------------------------------------------------------------------------*/
106static 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/*--------------------------------------------------------------------------*/
148static 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/*--------------------------------------------------------------------------*/
205static 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
259static 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
276static 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/*--------------------------------------------------------------------------*/
331static 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/****************************************************************************/
358int 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/****************************************************************************/
398int 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/****************************************************************************/
413int 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/****************************************************************************/
428int 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/****************************************************************************/
440int 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/****************************************************************************/
453int 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/*--------------------------------------------------------------------------*/
473int
474write_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/*--------------------------------------------------------------------------*/
511int 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/*--------------------------------------------------------------------------*/
535int 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/*--------------------------------------------------------------------------*/
554int 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/****************************************************************************/
576int 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/****************************************************************************/
586int 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/*--------------------------------------------------------------------------*/
639int 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/****************************************************************************/
670int 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/****************************************************************************/
685int 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/*---------------------------------------------------------------------------*/
714int
715select_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/****************************************************************************/
817int 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/****************************************************************************/
841int 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/****************************************************************************/
865int 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/*****************************************************************************/
880int 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/*****************************************************************************/
891int
892audio_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/*****************************************************************************/
979int 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/*---------------------------------------------------------------------------*/
1050int 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/*****************************************************************************/
1118int 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