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