1/***************************************************************************** 2* * 3* * 4* easycap_low.c * 5* * 6* * 7*****************************************************************************/ 8/* 9 * 10 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org> 11 * 12 * 13 * This is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * The software is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this software; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 * 27*/ 28/*****************************************************************************/ 29/* 30 * ACKNOWLEGEMENTS AND REFERENCES 31 * ------------------------------ 32 * This driver makes use of register information contained in the Syntek 33 * Semicon DC-1125 driver hosted at 34 * http://sourceforge.net/projects/syntekdriver/. 35 * Particularly useful has been a patch to the latter driver provided by 36 * Ivor Hewitt in January 2009. The NTSC implementation is taken from the 37 * work of Ben Trask. 38*/ 39/****************************************************************************/ 40 41#include "easycap.h" 42 43 44#define GET(X, Y, Z) do { \ 45 int __rc; \ 46 *(Z) = (u16)0; \ 47 __rc = regget(X, Y, Z, sizeof(u8)); \ 48 if (0 > __rc) { \ 49 JOT(8, ":-(%i\n", __LINE__); return __rc; \ 50 } \ 51} while (0) 52 53#define SET(X, Y, Z) do { \ 54 int __rc; \ 55 __rc = regset(X, Y, Z); \ 56 if (0 > __rc) { \ 57 JOT(8, ":-(%i\n", __LINE__); return __rc; \ 58 } \ 59} while (0) 60 61/*--------------------------------------------------------------------------*/ 62static const struct stk1160config { 63 u16 reg; 64 u16 set; 65} stk1160configPAL[] = { 66 {0x000, 0x0098}, 67 {0x002, 0x0093}, 68 69 {0x001, 0x0003}, 70 {0x003, 0x0080}, 71 {0x00D, 0x0000}, 72 {0x00F, 0x0002}, 73 {0x018, 0x0010}, 74 {0x019, 0x0000}, 75 {0x01A, 0x0014}, 76 {0x01B, 0x000E}, 77 {0x01C, 0x0046}, 78 79 {0x100, 0x0033}, 80 {0x103, 0x0000}, 81 {0x104, 0x0000}, 82 {0x105, 0x0000}, 83 {0x106, 0x0000}, 84 85/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 86/* 87 * RESOLUTION 640x480 88*/ 89/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 90 {0x110, 0x0008}, 91 {0x111, 0x0000}, 92 {0x112, 0x0020}, 93 {0x113, 0x0000}, 94 {0x114, 0x0508}, 95 {0x115, 0x0005}, 96 {0x116, 0x0110}, 97 {0x117, 0x0001}, 98/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 99 100 {0x202, 0x000F}, 101 {0x203, 0x004A}, 102 {0x2FF, 0x0000}, 103 104 {0xFFF, 0xFFFF} 105}; 106/*--------------------------------------------------------------------------*/ 107static const struct stk1160config stk1160configNTSC[] = { 108 {0x000, 0x0098}, 109 {0x002, 0x0093}, 110 111 {0x001, 0x0003}, 112 {0x003, 0x0080}, 113 {0x00D, 0x0000}, 114 {0x00F, 0x0002}, 115 {0x018, 0x0010}, 116 {0x019, 0x0000}, 117 {0x01A, 0x0014}, 118 {0x01B, 0x000E}, 119 {0x01C, 0x0046}, 120 121 {0x100, 0x0033}, 122 {0x103, 0x0000}, 123 {0x104, 0x0000}, 124 {0x105, 0x0000}, 125 {0x106, 0x0000}, 126 127/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 128/* 129 * RESOLUTION 640x480 130*/ 131/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 132 {0x110, 0x0008}, 133 {0x111, 0x0000}, 134 {0x112, 0x0003}, 135 {0x113, 0x0000}, 136 {0x114, 0x0508}, 137 {0x115, 0x0005}, 138 {0x116, 0x00F3}, 139 {0x117, 0x0000}, 140/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 141 142 {0x202, 0x000F}, 143 {0x203, 0x004A}, 144 {0x2FF, 0x0000}, 145 146 {0xFFF, 0xFFFF} 147}; 148/*--------------------------------------------------------------------------*/ 149static const struct saa7113config { 150 u8 reg; 151 u8 set; 152} saa7113configPAL[] = { 153 {0x01, 0x08}, 154 {0x02, 0x80}, 155 {0x03, 0x33}, 156 {0x04, 0x00}, 157 {0x05, 0x00}, 158 {0x06, 0xE9}, 159 {0x07, 0x0D}, 160 {0x08, 0x38}, 161 {0x09, 0x00}, 162 {0x0A, SAA_0A_DEFAULT}, 163 {0x0B, SAA_0B_DEFAULT}, 164 {0x0C, SAA_0C_DEFAULT}, 165 {0x0D, SAA_0D_DEFAULT}, 166 {0x0E, 0x01}, 167 {0x0F, 0x36}, 168 {0x10, 0x00}, 169 {0x11, 0x0C}, 170 {0x12, 0xE7}, 171 {0x13, 0x00}, 172 {0x15, 0x00}, 173 {0x16, 0x00}, 174 {0x40, 0x02}, 175 {0x41, 0xFF}, 176 {0x42, 0xFF}, 177 {0x43, 0xFF}, 178 {0x44, 0xFF}, 179 {0x45, 0xFF}, 180 {0x46, 0xFF}, 181 {0x47, 0xFF}, 182 {0x48, 0xFF}, 183 {0x49, 0xFF}, 184 {0x4A, 0xFF}, 185 {0x4B, 0xFF}, 186 {0x4C, 0xFF}, 187 {0x4D, 0xFF}, 188 {0x4E, 0xFF}, 189 {0x4F, 0xFF}, 190 {0x50, 0xFF}, 191 {0x51, 0xFF}, 192 {0x52, 0xFF}, 193 {0x53, 0xFF}, 194 {0x54, 0xFF}, 195 {0x55, 0xFF}, 196 {0x56, 0xFF}, 197 {0x57, 0xFF}, 198 {0x58, 0x40}, 199 {0x59, 0x54}, 200 {0x5A, 0x07}, 201 {0x5B, 0x83}, 202 203 {0xFF, 0xFF} 204}; 205/*--------------------------------------------------------------------------*/ 206static const struct saa7113config saa7113configNTSC[] = { 207 {0x01, 0x08}, 208 {0x02, 0x80}, 209 {0x03, 0x33}, 210 {0x04, 0x00}, 211 {0x05, 0x00}, 212 {0x06, 0xE9}, 213 {0x07, 0x0D}, 214 {0x08, 0x78}, 215 {0x09, 0x00}, 216 {0x0A, SAA_0A_DEFAULT}, 217 {0x0B, SAA_0B_DEFAULT}, 218 {0x0C, SAA_0C_DEFAULT}, 219 {0x0D, SAA_0D_DEFAULT}, 220 {0x0E, 0x01}, 221 {0x0F, 0x36}, 222 {0x10, 0x00}, 223 {0x11, 0x0C}, 224 {0x12, 0xE7}, 225 {0x13, 0x00}, 226 {0x15, 0x00}, 227 {0x16, 0x00}, 228 {0x40, 0x82}, 229 {0x41, 0xFF}, 230 {0x42, 0xFF}, 231 {0x43, 0xFF}, 232 {0x44, 0xFF}, 233 {0x45, 0xFF}, 234 {0x46, 0xFF}, 235 {0x47, 0xFF}, 236 {0x48, 0xFF}, 237 {0x49, 0xFF}, 238 {0x4A, 0xFF}, 239 {0x4B, 0xFF}, 240 {0x4C, 0xFF}, 241 {0x4D, 0xFF}, 242 {0x4E, 0xFF}, 243 {0x4F, 0xFF}, 244 {0x50, 0xFF}, 245 {0x51, 0xFF}, 246 {0x52, 0xFF}, 247 {0x53, 0xFF}, 248 {0x54, 0xFF}, 249 {0x55, 0xFF}, 250 {0x56, 0xFF}, 251 {0x57, 0xFF}, 252 {0x58, 0x40}, 253 {0x59, 0x54}, 254 {0x5A, 0x0A}, 255 {0x5B, 0x83}, 256 257 {0xFF, 0xFF} 258}; 259 260static int regget(struct usb_device *pusb_device, 261 u16 index, void *reg, int reg_size) 262{ 263 int rc; 264 265 if (!pusb_device) 266 return -ENODEV; 267 268 rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), 269 0x00, 270 (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), 271 0x00, 272 index, reg, reg_size, 50000); 273 274 return rc; 275} 276 277static int regset(struct usb_device *pusb_device, u16 index, u16 value) 278{ 279 int rc; 280 281 if (!pusb_device) 282 return -ENODEV; 283 284 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), 285 0x01, 286 (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), 287 value, index, NULL, 0, 500); 288 289 if (rc < 0) 290 return rc; 291 292 if (easycap_readback) { 293 u16 igot = 0; 294 rc = regget(pusb_device, index, &igot, sizeof(igot)); 295 igot = 0xFF & igot; 296 switch (index) { 297 case 0x000: 298 case 0x500: 299 case 0x502: 300 case 0x503: 301 case 0x504: 302 case 0x506: 303 case 0x507: 304 break; 305 306 case 0x204: 307 case 0x205: 308 case 0x350: 309 case 0x351: 310 if (igot) 311 JOT(8, "unexpected 0x%02X " 312 "for STK register 0x%03X\n", 313 igot, index); 314 break; 315 316 default: 317 if ((0xFF & value) != igot) 318 JOT(8, "unexpected 0x%02X != 0x%02X " 319 "for STK register 0x%03X\n", 320 igot, value, index); 321 break; 322 } 323 } 324 325 return rc; 326} 327/*--------------------------------------------------------------------------*/ 328/* 329 * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS 330*/ 331/*--------------------------------------------------------------------------*/ 332static int wait_i2c(struct usb_device *p) 333{ 334 u16 get0; 335 u8 igot; 336 const int max = 2; 337 int k; 338 339 if (!p) 340 return -ENODEV; 341 342 for (k = 0; k < max; k++) { 343 GET(p, 0x0201, &igot); get0 = igot; 344 switch (get0) { 345 case 0x04: 346 case 0x01: 347 return 0; 348 case 0x00: 349 msleep(20); 350 continue; 351 default: 352 return get0 - 1; 353 } 354 } 355 return -1; 356} 357 358/****************************************************************************/ 359int write_saa(struct usb_device *p, u16 reg0, u16 set0) 360{ 361 if (!p) 362 return -ENODEV; 363 SET(p, 0x200, 0x00); 364 SET(p, 0x204, reg0); 365 SET(p, 0x205, set0); 366 SET(p, 0x200, 0x01); 367 return wait_i2c(p); 368} 369/****************************************************************************/ 370/*--------------------------------------------------------------------------*/ 371/* 372 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?) 373 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A 374 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO SET 375 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO SET 376 * REGISTER 504: TARGET ADDRESS ON VT1612A 377 */ 378/*--------------------------------------------------------------------------*/ 379static int write_vt(struct usb_device *p, u16 reg0, u16 set0) 380{ 381 u8 igot; 382 u16 got502, got503; 383 u16 set502, set503; 384 385 if (!p) 386 return -ENODEV; 387 SET(p, 0x0504, reg0); 388 SET(p, 0x0500, 0x008B); 389 390 GET(p, 0x0502, &igot); got502 = (0xFF & igot); 391 GET(p, 0x0503, &igot); got503 = (0xFF & igot); 392 393 JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", 394 reg0, set0, ((got503 << 8) | got502)); 395 396 set502 = (0x00FF & set0); 397 set503 = ((0xFF00 & set0) >> 8); 398 399 SET(p, 0x0504, reg0); 400 SET(p, 0x0502, set502); 401 SET(p, 0x0503, set503); 402 SET(p, 0x0500, 0x008C); 403 404 return 0; 405} 406/****************************************************************************/ 407/*--------------------------------------------------------------------------*/ 408/* 409 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?) 410 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A 411 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO GET 412 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO GET 413 * REGISTER 504: TARGET ADDRESS ON VT1612A 414 */ 415/*--------------------------------------------------------------------------*/ 416static int read_vt(struct usb_device *p, u16 reg0) 417{ 418 u8 igot; 419 u16 got502, got503; 420 421 if (!p) 422 return -ENODEV; 423 SET(p, 0x0504, reg0); 424 SET(p, 0x0500, 0x008B); 425 426 GET(p, 0x0502, &igot); got502 = (0xFF & igot); 427 GET(p, 0x0503, &igot); got503 = (0xFF & igot); 428 429 JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", 430 reg0, ((got503 << 8) | got502)); 431 432 return (got503 << 8) | got502; 433} 434/****************************************************************************/ 435/*--------------------------------------------------------------------------*/ 436/* 437 * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO. 438 */ 439/*--------------------------------------------------------------------------*/ 440static int write_300(struct usb_device *p) 441{ 442 if (!p) 443 return -ENODEV; 444 SET(p, 0x300, 0x0012); 445 SET(p, 0x350, 0x002D); 446 SET(p, 0x351, 0x0001); 447 SET(p, 0x352, 0x0000); 448 SET(p, 0x353, 0x0000); 449 SET(p, 0x300, 0x0080); 450 return 0; 451} 452/****************************************************************************/ 453/****************************************************************************/ 454int setup_stk(struct usb_device *p, bool ntsc) 455{ 456 int i; 457 const struct stk1160config *cfg; 458 if (!p) 459 return -ENODEV; 460 cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; 461 for (i = 0; cfg[i].reg != 0xFFF; i++) 462 SET(p, cfg[i].reg, cfg[i].set); 463 464 write_300(p); 465 466 return 0; 467} 468/****************************************************************************/ 469int setup_saa(struct usb_device *p, bool ntsc) 470{ 471 int i, rc; 472 const struct saa7113config *cfg; 473 if (!p) 474 return -ENODEV; 475 cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; 476 for (i = 0; cfg[i].reg != 0xFF; i++) { 477 rc = write_saa(p, cfg[i].reg, cfg[i].set); 478 if (rc) 479 dev_err(&p->dev, 480 "Failed to set SAA register %d", cfg[i].reg); 481 } 482 return 0; 483} 484/****************************************************************************/ 485int merit_saa(struct usb_device *p) 486{ 487 int rc; 488 489 if (!p) 490 return -ENODEV; 491 rc = read_saa(p, 0x1F); 492 return ((0 > rc) || (0x02 & rc)) ? 1 : 0; 493} 494/****************************************************************************/ 495int ready_saa(struct usb_device *p) 496{ 497 int j, rc, rate; 498 const int max = 5, marktime = PATIENCE/5; 499/*--------------------------------------------------------------------------*/ 500/* 501 * RETURNS 0 FOR INTERLACED 50 Hz 502 * 1 FOR NON-INTERLACED 50 Hz 503 * 2 FOR INTERLACED 60 Hz 504 * 3 FOR NON-INTERLACED 60 Hz 505*/ 506/*--------------------------------------------------------------------------*/ 507 if (!p) 508 return -ENODEV; 509 j = 0; 510 while (max > j) { 511 rc = read_saa(p, 0x1F); 512 if (0 <= rc) { 513 if (0 == (0x40 & rc)) 514 break; 515 if (1 == (0x01 & rc)) 516 break; 517 } 518 msleep(marktime); 519 j++; 520 } 521 522 if (max == j) 523 return -1; 524 525 if (0x20 & rc) { 526 rate = 2; 527 JOT(8, "hardware detects 60 Hz\n"); 528 } else { 529 rate = 0; 530 JOT(8, "hardware detects 50 Hz\n"); 531 } 532 if (0x80 & rc) 533 JOT(8, "hardware detects interlacing\n"); 534 else { 535 rate++; 536 JOT(8, "hardware detects no interlacing\n"); 537 } 538 return 0; 539} 540/****************************************************************************/ 541int read_saa(struct usb_device *p, u16 reg0) 542{ 543 u8 igot; 544 545 if (!p) 546 return -ENODEV; 547 SET(p, 0x208, reg0); 548 SET(p, 0x200, 0x20); 549 if (0 != wait_i2c(p)) 550 return -1; 551 igot = 0; 552 GET(p, 0x0209, &igot); 553 return igot; 554} 555/****************************************************************************/ 556static int read_stk(struct usb_device *p, u32 reg0) 557{ 558 u8 igot; 559 560 if (!p) 561 return -ENODEV; 562 igot = 0; 563 GET(p, reg0, &igot); 564 return igot; 565} 566int select_input(struct usb_device *p, int input, int mode) 567{ 568 int ir; 569 570 if (!p) 571 return -ENODEV; 572 stop_100(p); 573 switch (input) { 574 case 0: 575 case 1: { 576 if (0 != write_saa(p, 0x02, 0x80)) 577 SAY("ERROR: failed to set SAA register 0x02 " 578 "for input %i\n", input); 579 580 SET(p, 0x0000, 0x0098); 581 SET(p, 0x0002, 0x0078); 582 break; 583 } 584 case 2: { 585 if (0 != write_saa(p, 0x02, 0x80)) 586 SAY("ERROR: failed to set SAA register 0x02 " 587 "for input %i\n", input); 588 589 SET(p, 0x0000, 0x0090); 590 SET(p, 0x0002, 0x0078); 591 break; 592 } 593 case 3: { 594 if (0 != write_saa(p, 0x02, 0x80)) 595 SAY("ERROR: failed to set SAA register 0x02 " 596 " for input %i\n", input); 597 598 SET(p, 0x0000, 0x0088); 599 SET(p, 0x0002, 0x0078); 600 break; 601 } 602 case 4: { 603 if (0 != write_saa(p, 0x02, 0x80)) { 604 SAY("ERROR: failed to set SAA register 0x02 " 605 "for input %i\n", input); 606 } 607 SET(p, 0x0000, 0x0080); 608 SET(p, 0x0002, 0x0078); 609 break; 610 } 611 case 5: { 612 if (9 != mode) 613 mode = 7; 614 switch (mode) { 615 case 7: { 616 if (0 != write_saa(p, 0x02, 0x87)) 617 SAY("ERROR: failed to set SAA register 0x02 " 618 "for input %i\n", input); 619 620 if (0 != write_saa(p, 0x05, 0xFF)) 621 SAY("ERROR: failed to set SAA register 0x05 " 622 "for input %i\n", input); 623 624 break; 625 } 626 case 9: { 627 if (0 != write_saa(p, 0x02, 0x89)) 628 SAY("ERROR: failed to set SAA register 0x02 " 629 "for input %i\n", input); 630 631 if (0 != write_saa(p, 0x05, 0x00)) 632 SAY("ERROR: failed to set SAA register 0x05 " 633 "for input %i\n", input); 634 635 break; 636 } 637 default: 638 SAY("MISTAKE: bad mode: %i\n", mode); 639 return -1; 640 } 641 642 if (0 != write_saa(p, 0x04, 0x00)) 643 SAY("ERROR: failed to set SAA register 0x04 " 644 "for input %i\n", input); 645 646 if (0 != write_saa(p, 0x09, 0x80)) 647 SAY("ERROR: failed to set SAA register 0x09 " 648 "for input %i\n", input); 649 650 SET(p, 0x0002, 0x0093); 651 break; 652 } 653 default: 654 SAY("ERROR: bad input: %i\n", input); 655 return -1; 656 } 657 658 ir = read_stk(p, 0x00); 659 JOT(8, "STK register 0x00 has 0x%02X\n", ir); 660 ir = read_saa(p, 0x02); 661 JOT(8, "SAA register 0x02 has 0x%02X\n", ir); 662 663 start_100(p); 664 665 return 0; 666} 667/****************************************************************************/ 668int set_resolution(struct usb_device *p, 669 u16 set0, u16 set1, u16 set2, u16 set3) 670{ 671 u16 u0x0111, u0x0113, u0x0115, u0x0117; 672 673 if (!p) 674 return -ENODEV; 675 u0x0111 = ((0xFF00 & set0) >> 8); 676 u0x0113 = ((0xFF00 & set1) >> 8); 677 u0x0115 = ((0xFF00 & set2) >> 8); 678 u0x0117 = ((0xFF00 & set3) >> 8); 679 680 SET(p, 0x0110, (0x00FF & set0)); 681 SET(p, 0x0111, u0x0111); 682 SET(p, 0x0112, (0x00FF & set1)); 683 SET(p, 0x0113, u0x0113); 684 SET(p, 0x0114, (0x00FF & set2)); 685 SET(p, 0x0115, u0x0115); 686 SET(p, 0x0116, (0x00FF & set3)); 687 SET(p, 0x0117, u0x0117); 688 689 return 0; 690} 691/****************************************************************************/ 692int start_100(struct usb_device *p) 693{ 694 u16 get116, get117, get0; 695 u8 igot116, igot117, igot; 696 697 if (!p) 698 return -ENODEV; 699 GET(p, 0x0116, &igot116); 700 get116 = igot116; 701 GET(p, 0x0117, &igot117); 702 get117 = igot117; 703 SET(p, 0x0116, 0x0000); 704 SET(p, 0x0117, 0x0000); 705 706 GET(p, 0x0100, &igot); 707 get0 = igot; 708 SET(p, 0x0100, (0x80 | get0)); 709 710 SET(p, 0x0116, get116); 711 SET(p, 0x0117, get117); 712 713 return 0; 714} 715/****************************************************************************/ 716int stop_100(struct usb_device *p) 717{ 718 u16 get0; 719 u8 igot; 720 721 if (!p) 722 return -ENODEV; 723 GET(p, 0x0100, &igot); 724 get0 = igot; 725 SET(p, 0x0100, (0x7F & get0)); 726 return 0; 727} 728/****************************************************************************/ 729/****************************************************************************/ 730/*****************************************************************************/ 731int easycap_wakeup_device(struct usb_device *pusb_device) 732{ 733 if (!pusb_device) 734 return -ENODEV; 735 736 return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), 737 USB_REQ_SET_FEATURE, 738 USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, 739 USB_DEVICE_REMOTE_WAKEUP, 740 0, NULL, 0, 50000); 741} 742/*****************************************************************************/ 743int easycap_audio_setup(struct easycap *peasycap) 744{ 745 struct usb_device *pusb_device; 746 u8 buffer[1]; 747 int rc, id1, id2; 748/*---------------------------------------------------------------------------*/ 749/* 750 * IMPORTANT: 751 * THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) 752 * CAUSES MUTING IF THE VALUE 0x0100 IS SENT. 753 * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT. 754 */ 755/*---------------------------------------------------------------------------*/ 756 const u8 request = 0x01; 757 const u8 requesttype = USB_DIR_OUT | 758 USB_TYPE_CLASS | 759 USB_RECIP_INTERFACE; 760 const u16 value_unmute = 0x0200; 761 const u16 index = 0x0301; 762 const u16 length = 1; 763 764 if (!peasycap) 765 return -EFAULT; 766 767 pusb_device = peasycap->pusb_device; 768 if (!pusb_device) 769 return -ENODEV; 770 771 JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", 772 requesttype, request, 773 (0x00FF & value_unmute), 774 (0xFF00 & value_unmute) >> 8, 775 (0x00FF & index), 776 (0xFF00 & index) >> 8, 777 (0x00FF & length), 778 (0xFF00 & length) >> 8); 779 780 buffer[0] = 0x01; 781 782 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), 783 request, requesttype, value_unmute, 784 index, &buffer[0], length, 50000); 785 786 JOT(8, "0x%02X=buffer\n", buffer[0]); 787 if (rc != (int)length) { 788 switch (rc) { 789 case -EPIPE: 790 SAY("usb_control_msg returned -EPIPE\n"); 791 break; 792 default: 793 SAY("ERROR: usb_control_msg returned %i\n", rc); 794 break; 795 } 796 } 797/*--------------------------------------------------------------------------*/ 798/* 799 * REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ??? 800 * REGISTER 506: ANALOGUE AUDIO ATTENTUATOR ??? 801 * FOR THE CVBS+S-VIDEO HARDWARE: 802 * SETTING VALUE TO 0x0000 GIVES QUIET SOUND. 803 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT. 804 * FOR THE FOUR-CVBS HARDWARE: 805 * SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT. 806 * REGISTER 507: ANALOGUE AUDIO PREAMPLIFIER ON/OFF ??? 807 * FOR THE CVBS-S-VIDEO HARDWARE: 808 * SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND. 809 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT. 810 */ 811/*--------------------------------------------------------------------------*/ 812 SET(pusb_device, 0x0500, 0x0094); 813 SET(pusb_device, 0x0500, 0x008C); 814 SET(pusb_device, 0x0506, 0x0001); 815 SET(pusb_device, 0x0507, 0x0000); 816 id1 = read_vt(pusb_device, 0x007C); 817 id2 = read_vt(pusb_device, 0x007E); 818 SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2); 819/*---------------------------------------------------------------------------*/ 820/* 821 * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN. 822*/ 823/*---------------------------------------------------------------------------*/ 824 if (easycap_audio_gainset(pusb_device, peasycap->gain)) 825 SAY("ERROR: audio_gainset() failed\n"); 826 check_vt(pusb_device); 827 return 0; 828} 829/*****************************************************************************/ 830int check_vt(struct usb_device *pusb_device) 831{ 832 int igot; 833 834 if (!pusb_device) 835 return -ENODEV; 836 igot = read_vt(pusb_device, 0x0002); 837 if (0 > igot) 838 SAY("ERROR: failed to read VT1612A register 0x02\n"); 839 if (0x8000 & igot) 840 SAY("register 0x%02X muted\n", 0x02); 841 842 igot = read_vt(pusb_device, 0x000E); 843 if (0 > igot) 844 SAY("ERROR: failed to read VT1612A register 0x0E\n"); 845 if (0x8000 & igot) 846 SAY("register 0x%02X muted\n", 0x0E); 847 848 igot = read_vt(pusb_device, 0x0010); 849 if (0 > igot) 850 SAY("ERROR: failed to read VT1612A register 0x10\n"); 851 if (0x8000 & igot) 852 SAY("register 0x%02X muted\n", 0x10); 853 854 igot = read_vt(pusb_device, 0x0012); 855 if (0 > igot) 856 SAY("ERROR: failed to read VT1612A register 0x12\n"); 857 if (0x8000 & igot) 858 SAY("register 0x%02X muted\n", 0x12); 859 860 igot = read_vt(pusb_device, 0x0014); 861 if (0 > igot) 862 SAY("ERROR: failed to read VT1612A register 0x14\n"); 863 if (0x8000 & igot) 864 SAY("register 0x%02X muted\n", 0x14); 865 866 igot = read_vt(pusb_device, 0x0016); 867 if (0 > igot) 868 SAY("ERROR: failed to read VT1612A register 0x16\n"); 869 if (0x8000 & igot) 870 SAY("register 0x%02X muted\n", 0x16); 871 872 igot = read_vt(pusb_device, 0x0018); 873 if (0 > igot) 874 SAY("ERROR: failed to read VT1612A register 0x18\n"); 875 if (0x8000 & igot) 876 SAY("register 0x%02X muted\n", 0x18); 877 878 igot = read_vt(pusb_device, 0x001C); 879 if (0 > igot) 880 SAY("ERROR: failed to read VT1612A register 0x1C\n"); 881 if (0x8000 & igot) 882 SAY("register 0x%02X muted\n", 0x1C); 883 884 return 0; 885} 886/*****************************************************************************/ 887/*---------------------------------------------------------------------------*/ 888/* NOTE: THIS DOES INCREASE THE VOLUME DRAMATICALLY: 889 * audio_gainset(pusb_device, 0x000F); 890 * 891 * loud dB register 0x10 dB register 0x1C dB total 892 * 0 -34.5 0 -34.5 893 * .. .... . .... 894 * 15 10.5 0 10.5 895 * 16 12.0 0 12.0 896 * 17 12.0 1.5 13.5 897 * .. .... .... .... 898 * 31 12.0 22.5 34.5 899*/ 900/*---------------------------------------------------------------------------*/ 901int easycap_audio_gainset(struct usb_device *pusb_device, s8 loud) 902{ 903 int igot; 904 u8 tmp; 905 u16 mute; 906 907 if (!pusb_device) 908 return -ENODEV; 909 if (0 > loud) 910 loud = 0; 911 if (31 < loud) 912 loud = 31; 913 914 write_vt(pusb_device, 0x0002, 0x8000); 915/*---------------------------------------------------------------------------*/ 916 igot = read_vt(pusb_device, 0x000E); 917 if (0 > igot) { 918 SAY("ERROR: failed to read VT1612A register 0x0E\n"); 919 mute = 0x0000; 920 } else 921 mute = 0x8000 & ((unsigned int)igot); 922 mute = 0; 923 924 if (16 > loud) 925 tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1)); 926 else 927 tmp = 0; 928 929 JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp); 930 write_vt(pusb_device, 0x000E, (mute | tmp)); 931/*---------------------------------------------------------------------------*/ 932 igot = read_vt(pusb_device, 0x0010); 933 if (0 > igot) { 934 SAY("ERROR: failed to read VT1612A register 0x10\n"); 935 mute = 0x0000; 936 } else 937 mute = 0x8000 & ((unsigned int)igot); 938 mute = 0; 939 940 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n", 941 mute | tmp | (tmp << 8)); 942 write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8))); 943 write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8))); 944 write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8))); 945 write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8))); 946 write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8))); 947/*---------------------------------------------------------------------------*/ 948 igot = read_vt(pusb_device, 0x001C); 949 if (0 > igot) { 950 SAY("ERROR: failed to read VT1612A register 0x1C\n"); 951 mute = 0x0000; 952 } else 953 mute = 0x8000 & ((unsigned int)igot); 954 mute = 0; 955 956 if (16 <= loud) 957 tmp = 0x000F & (u8)(loud - 16); 958 else 959 tmp = 0; 960 961 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n", 962 mute | tmp | (tmp << 8)); 963 write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8))); 964 write_vt(pusb_device, 0x001A, 0x0404); 965 write_vt(pusb_device, 0x0002, 0x0000); 966 return 0; 967} 968/*****************************************************************************/ 969