1 /* 2 Frontend/Card driver for TwinHan DST Frontend 3 Copyright (C) 2003 Jamie Honan 4 Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22 23 #include <linux/kernel.h> 24 #include <linux/module.h> 25 #include <linux/init.h> 26 #include <linux/string.h> 27 #include <linux/slab.h> 28 #include <linux/vmalloc.h> 29 #include <linux/delay.h> 30 #include <asm/div64.h> 31 #include <media/dvb_frontend.h> 32 #include "dst_priv.h" 33 #include "dst_common.h" 34 35 static unsigned int verbose; 36 module_param(verbose, int, 0644); 37 MODULE_PARM_DESC(verbose, "verbosity level (0 to 3)"); 38 39 static unsigned int dst_addons; 40 module_param(dst_addons, int, 0644); 41 MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); 42 43 static unsigned int dst_algo; 44 module_param(dst_algo, int, 0644); 45 MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)"); 46 47 #define HAS_LOCK 1 48 #define ATTEMPT_TUNE 2 49 #define HAS_POWER 4 50 51 #define dprintk(level, fmt, arg...) do { \ 52 if (level >= verbose) \ 53 printk(KERN_DEBUG pr_fmt("%s: " fmt), \ 54 __func__, ##arg); \ 55 } while(0) 56 57 static int dst_command(struct dst_state *state, u8 *data, u8 len); 58 59 static void dst_packsize(struct dst_state *state, int psize) 60 { 61 union dst_gpio_packet bits; 62 63 bits.psize = psize; 64 bt878_device_control(state->bt, DST_IG_TS, &bits); 65 } 66 67 static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, 68 u32 outhigh, int delay) 69 { 70 union dst_gpio_packet enb; 71 union dst_gpio_packet bits; 72 int err; 73 74 enb.enb.mask = mask; 75 enb.enb.enable = enbb; 76 77 dprintk(2, "mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", 78 mask, enbb, outhigh); 79 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { 80 dprintk(2, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", 81 err, mask, enbb); 82 return -EREMOTEIO; 83 } 84 udelay(1000); 85 /* because complete disabling means no output, no need to do output packet */ 86 if (enbb == 0) 87 return 0; 88 if (delay) 89 msleep(10); 90 bits.outp.mask = enbb; 91 bits.outp.highvals = outhigh; 92 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { 93 dprintk(2, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", 94 err, enbb, outhigh); 95 return -EREMOTEIO; 96 } 97 98 return 0; 99 } 100 101 static int dst_gpio_inb(struct dst_state *state, u8 *result) 102 { 103 union dst_gpio_packet rd_packet; 104 int err; 105 106 *result = 0; 107 if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { 108 pr_err("dst_gpio_inb error (err == %i)\n", err); 109 return -EREMOTEIO; 110 } 111 *result = (u8) rd_packet.rd.value; 112 113 return 0; 114 } 115 116 int rdc_reset_state(struct dst_state *state) 117 { 118 dprintk(2, "Resetting state machine\n"); 119 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) { 120 pr_err("dst_gpio_outb ERROR !\n"); 121 return -1; 122 } 123 msleep(10); 124 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) { 125 pr_err("dst_gpio_outb ERROR !\n"); 126 msleep(10); 127 return -1; 128 } 129 130 return 0; 131 } 132 EXPORT_SYMBOL(rdc_reset_state); 133 134 static int rdc_8820_reset(struct dst_state *state) 135 { 136 dprintk(3, "Resetting DST\n"); 137 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) { 138 pr_err("dst_gpio_outb ERROR !\n"); 139 return -1; 140 } 141 udelay(1000); 142 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) { 143 pr_err("dst_gpio_outb ERROR !\n"); 144 return -1; 145 } 146 147 return 0; 148 } 149 150 static int dst_pio_enable(struct dst_state *state) 151 { 152 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) { 153 pr_err("dst_gpio_outb ERROR !\n"); 154 return -1; 155 } 156 udelay(1000); 157 158 return 0; 159 } 160 161 int dst_pio_disable(struct dst_state *state) 162 { 163 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) { 164 pr_err("dst_gpio_outb ERROR !\n"); 165 return -1; 166 } 167 if (state->type_flags & DST_TYPE_HAS_FW_1) 168 udelay(1000); 169 170 return 0; 171 } 172 EXPORT_SYMBOL(dst_pio_disable); 173 174 int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode) 175 { 176 u8 reply; 177 int i; 178 179 for (i = 0; i < 200; i++) { 180 if (dst_gpio_inb(state, &reply) < 0) { 181 pr_err("dst_gpio_inb ERROR !\n"); 182 return -1; 183 } 184 if ((reply & RDC_8820_PIO_0_ENABLE) == 0) { 185 dprintk(2, "dst wait ready after %d\n", i); 186 return 1; 187 } 188 msleep(10); 189 } 190 dprintk(1, "dst wait NOT ready after %d\n", i); 191 192 return 0; 193 } 194 EXPORT_SYMBOL(dst_wait_dst_ready); 195 196 int dst_error_recovery(struct dst_state *state) 197 { 198 dprintk(1, "Trying to return from previous errors.\n"); 199 dst_pio_disable(state); 200 msleep(10); 201 dst_pio_enable(state); 202 msleep(10); 203 204 return 0; 205 } 206 EXPORT_SYMBOL(dst_error_recovery); 207 208 int dst_error_bailout(struct dst_state *state) 209 { 210 dprintk(2, "Trying to bailout from previous error.\n"); 211 rdc_8820_reset(state); 212 dst_pio_disable(state); 213 msleep(10); 214 215 return 0; 216 } 217 EXPORT_SYMBOL(dst_error_bailout); 218 219 int dst_comm_init(struct dst_state *state) 220 { 221 dprintk(2, "Initializing DST.\n"); 222 if ((dst_pio_enable(state)) < 0) { 223 pr_err("PIO Enable Failed\n"); 224 return -1; 225 } 226 if ((rdc_reset_state(state)) < 0) { 227 pr_err("RDC 8820 State RESET Failed.\n"); 228 return -1; 229 } 230 if (state->type_flags & DST_TYPE_HAS_FW_1) 231 msleep(100); 232 else 233 msleep(5); 234 235 return 0; 236 } 237 EXPORT_SYMBOL(dst_comm_init); 238 239 int write_dst(struct dst_state *state, u8 *data, u8 len) 240 { 241 struct i2c_msg msg = { 242 .addr = state->config->demod_address, 243 .flags = 0, 244 .buf = data, 245 .len = len 246 }; 247 248 int err; 249 u8 cnt; 250 251 dprintk(1, "writing [ %*ph ]\n", len, data); 252 253 for (cnt = 0; cnt < 2; cnt++) { 254 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 255 dprintk(2, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", 256 err, len, data[0]); 257 dst_error_recovery(state); 258 continue; 259 } else 260 break; 261 } 262 if (cnt >= 2) { 263 dprintk(2, "RDC 8820 RESET\n"); 264 dst_error_bailout(state); 265 266 return -1; 267 } 268 269 return 0; 270 } 271 EXPORT_SYMBOL(write_dst); 272 273 int read_dst(struct dst_state *state, u8 *ret, u8 len) 274 { 275 struct i2c_msg msg = { 276 .addr = state->config->demod_address, 277 .flags = I2C_M_RD, 278 .buf = ret, 279 .len = len 280 }; 281 282 int err; 283 int cnt; 284 285 for (cnt = 0; cnt < 2; cnt++) { 286 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 287 dprintk(2, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", 288 err, len, ret[0]); 289 dst_error_recovery(state); 290 continue; 291 } else 292 break; 293 } 294 if (cnt >= 2) { 295 dprintk(2, "RDC 8820 RESET\n"); 296 dst_error_bailout(state); 297 298 return -1; 299 } 300 dprintk(3, "reply is %*ph\n", len, ret); 301 302 return 0; 303 } 304 EXPORT_SYMBOL(read_dst); 305 306 static int dst_set_polarization(struct dst_state *state) 307 { 308 switch (state->voltage) { 309 case SEC_VOLTAGE_13: /* Vertical */ 310 dprintk(2, "Polarization=[Vertical]\n"); 311 state->tx_tuna[8] &= ~0x40; 312 break; 313 case SEC_VOLTAGE_18: /* Horizontal */ 314 dprintk(2, "Polarization=[Horizontal]\n"); 315 state->tx_tuna[8] |= 0x40; 316 break; 317 case SEC_VOLTAGE_OFF: 318 break; 319 } 320 321 return 0; 322 } 323 324 static int dst_set_freq(struct dst_state *state, u32 freq) 325 { 326 state->frequency = freq; 327 dprintk(2, "set Frequency %u\n", freq); 328 329 if (state->dst_type == DST_TYPE_IS_SAT) { 330 freq = freq / 1000; 331 if (freq < 950 || freq > 2150) 332 return -EINVAL; 333 state->tx_tuna[2] = (freq >> 8); 334 state->tx_tuna[3] = (u8) freq; 335 state->tx_tuna[4] = 0x01; 336 state->tx_tuna[8] &= ~0x04; 337 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { 338 if (freq < 1531) 339 state->tx_tuna[8] |= 0x04; 340 } 341 } else if (state->dst_type == DST_TYPE_IS_TERR) { 342 freq = freq / 1000; 343 if (freq < 137000 || freq > 858000) 344 return -EINVAL; 345 state->tx_tuna[2] = (freq >> 16) & 0xff; 346 state->tx_tuna[3] = (freq >> 8) & 0xff; 347 state->tx_tuna[4] = (u8) freq; 348 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 349 freq = freq / 1000; 350 state->tx_tuna[2] = (freq >> 16) & 0xff; 351 state->tx_tuna[3] = (freq >> 8) & 0xff; 352 state->tx_tuna[4] = (u8) freq; 353 } else if (state->dst_type == DST_TYPE_IS_ATSC) { 354 freq = freq / 1000; 355 if (freq < 51000 || freq > 858000) 356 return -EINVAL; 357 state->tx_tuna[2] = (freq >> 16) & 0xff; 358 state->tx_tuna[3] = (freq >> 8) & 0xff; 359 state->tx_tuna[4] = (u8) freq; 360 state->tx_tuna[5] = 0x00; /* ATSC */ 361 state->tx_tuna[6] = 0x00; 362 if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG) 363 state->tx_tuna[7] = 0x00; /* Digital */ 364 } else 365 return -EINVAL; 366 367 return 0; 368 } 369 370 static int dst_set_bandwidth(struct dst_state *state, u32 bandwidth) 371 { 372 state->bandwidth = bandwidth; 373 374 if (state->dst_type != DST_TYPE_IS_TERR) 375 return -EOPNOTSUPP; 376 377 switch (bandwidth) { 378 case 6000000: 379 if (state->dst_hw_cap & DST_TYPE_HAS_CA) 380 state->tx_tuna[7] = 0x06; 381 else { 382 state->tx_tuna[6] = 0x06; 383 state->tx_tuna[7] = 0x00; 384 } 385 break; 386 case 7000000: 387 if (state->dst_hw_cap & DST_TYPE_HAS_CA) 388 state->tx_tuna[7] = 0x07; 389 else { 390 state->tx_tuna[6] = 0x07; 391 state->tx_tuna[7] = 0x00; 392 } 393 break; 394 case 8000000: 395 if (state->dst_hw_cap & DST_TYPE_HAS_CA) 396 state->tx_tuna[7] = 0x08; 397 else { 398 state->tx_tuna[6] = 0x08; 399 state->tx_tuna[7] = 0x00; 400 } 401 break; 402 default: 403 return -EINVAL; 404 } 405 406 return 0; 407 } 408 409 static int dst_set_inversion(struct dst_state *state, 410 enum fe_spectral_inversion inversion) 411 { 412 state->inversion = inversion; 413 switch (inversion) { 414 case INVERSION_OFF: /* Inversion = Normal */ 415 state->tx_tuna[8] &= ~0x80; 416 break; 417 case INVERSION_ON: 418 state->tx_tuna[8] |= 0x80; 419 break; 420 default: 421 return -EINVAL; 422 } 423 424 return 0; 425 } 426 427 static int dst_set_fec(struct dst_state *state, enum fe_code_rate fec) 428 { 429 state->fec = fec; 430 return 0; 431 } 432 433 static enum fe_code_rate dst_get_fec(struct dst_state *state) 434 { 435 return state->fec; 436 } 437 438 static int dst_set_symbolrate(struct dst_state *state, u32 srate) 439 { 440 u32 symcalc; 441 u64 sval; 442 443 state->symbol_rate = srate; 444 if (state->dst_type == DST_TYPE_IS_TERR) { 445 return -EOPNOTSUPP; 446 } 447 dprintk(2, "set symrate %u\n", srate); 448 srate /= 1000; 449 if (state->dst_type == DST_TYPE_IS_SAT) { 450 if (state->type_flags & DST_TYPE_HAS_SYMDIV) { 451 sval = srate; 452 sval <<= 20; 453 do_div(sval, 88000); 454 symcalc = (u32) sval; 455 dprintk(2, "set symcalc %u\n", symcalc); 456 state->tx_tuna[5] = (u8) (symcalc >> 12); 457 state->tx_tuna[6] = (u8) (symcalc >> 4); 458 state->tx_tuna[7] = (u8) (symcalc << 4); 459 } else { 460 state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; 461 state->tx_tuna[6] = (u8) (srate >> 8); 462 state->tx_tuna[7] = (u8) srate; 463 } 464 state->tx_tuna[8] &= ~0x20; 465 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { 466 if (srate > 8000) 467 state->tx_tuna[8] |= 0x20; 468 } 469 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 470 dprintk(3, "%s\n", state->fw_name); 471 if (!strncmp(state->fw_name, "DCTNEW", 6)) { 472 state->tx_tuna[5] = (u8) (srate >> 8); 473 state->tx_tuna[6] = (u8) srate; 474 state->tx_tuna[7] = 0x00; 475 } else if (!strncmp(state->fw_name, "DCT-CI", 6)) { 476 state->tx_tuna[5] = 0x00; 477 state->tx_tuna[6] = (u8) (srate >> 8); 478 state->tx_tuna[7] = (u8) srate; 479 } 480 } 481 return 0; 482 } 483 484 static int dst_set_modulation(struct dst_state *state, 485 enum fe_modulation modulation) 486 { 487 if (state->dst_type != DST_TYPE_IS_CABLE) 488 return -EOPNOTSUPP; 489 490 state->modulation = modulation; 491 switch (modulation) { 492 case QAM_16: 493 state->tx_tuna[8] = 0x10; 494 break; 495 case QAM_32: 496 state->tx_tuna[8] = 0x20; 497 break; 498 case QAM_64: 499 state->tx_tuna[8] = 0x40; 500 break; 501 case QAM_128: 502 state->tx_tuna[8] = 0x80; 503 break; 504 case QAM_256: 505 if (!strncmp(state->fw_name, "DCTNEW", 6)) 506 state->tx_tuna[8] = 0xff; 507 else if (!strncmp(state->fw_name, "DCT-CI", 6)) 508 state->tx_tuna[8] = 0x00; 509 break; 510 case QPSK: 511 case QAM_AUTO: 512 case VSB_8: 513 case VSB_16: 514 default: 515 return -EINVAL; 516 517 } 518 519 return 0; 520 } 521 522 static enum fe_modulation dst_get_modulation(struct dst_state *state) 523 { 524 return state->modulation; 525 } 526 527 528 u8 dst_check_sum(u8 *buf, u32 len) 529 { 530 u32 i; 531 u8 val = 0; 532 if (!len) 533 return 0; 534 for (i = 0; i < len; i++) { 535 val += buf[i]; 536 } 537 return ((~val) + 1); 538 } 539 EXPORT_SYMBOL(dst_check_sum); 540 541 static void dst_type_flags_print(struct dst_state *state) 542 { 543 u32 type_flags = state->type_flags; 544 545 pr_err("DST type flags :\n"); 546 if (type_flags & DST_TYPE_HAS_TS188) 547 pr_err(" 0x%x newtuner\n", DST_TYPE_HAS_TS188); 548 if (type_flags & DST_TYPE_HAS_NEWTUNE_2) 549 pr_err(" 0x%x newtuner 2\n", DST_TYPE_HAS_NEWTUNE_2); 550 if (type_flags & DST_TYPE_HAS_TS204) 551 pr_err(" 0x%x ts204\n", DST_TYPE_HAS_TS204); 552 if (type_flags & DST_TYPE_HAS_VLF) 553 pr_err(" 0x%x VLF\n", DST_TYPE_HAS_VLF); 554 if (type_flags & DST_TYPE_HAS_SYMDIV) 555 pr_err(" 0x%x symdiv\n", DST_TYPE_HAS_SYMDIV); 556 if (type_flags & DST_TYPE_HAS_FW_1) 557 pr_err(" 0x%x firmware version = 1\n", DST_TYPE_HAS_FW_1); 558 if (type_flags & DST_TYPE_HAS_FW_2) 559 pr_err(" 0x%x firmware version = 2\n", DST_TYPE_HAS_FW_2); 560 if (type_flags & DST_TYPE_HAS_FW_3) 561 pr_err(" 0x%x firmware version = 3\n", DST_TYPE_HAS_FW_3); 562 pr_err("\n"); 563 } 564 565 566 static int dst_type_print(struct dst_state *state, u8 type) 567 { 568 char *otype; 569 switch (type) { 570 case DST_TYPE_IS_SAT: 571 otype = "satellite"; 572 break; 573 574 case DST_TYPE_IS_TERR: 575 otype = "terrestrial"; 576 break; 577 578 case DST_TYPE_IS_CABLE: 579 otype = "cable"; 580 break; 581 582 case DST_TYPE_IS_ATSC: 583 otype = "atsc"; 584 break; 585 586 default: 587 dprintk(2, "invalid dst type %d\n", type); 588 return -EINVAL; 589 } 590 dprintk(2, "DST type: %s\n", otype); 591 592 return 0; 593 } 594 595 static struct tuner_types tuner_list[] = { 596 { 597 .tuner_type = TUNER_TYPE_L64724, 598 .tuner_name = "L 64724", 599 .board_name = "UNKNOWN", 600 .fw_name = "UNKNOWN" 601 }, 602 603 { 604 .tuner_type = TUNER_TYPE_STV0299, 605 .tuner_name = "STV 0299", 606 .board_name = "VP1020", 607 .fw_name = "DST-MOT" 608 }, 609 610 { 611 .tuner_type = TUNER_TYPE_STV0299, 612 .tuner_name = "STV 0299", 613 .board_name = "VP1020", 614 .fw_name = "DST-03T" 615 }, 616 617 { 618 .tuner_type = TUNER_TYPE_MB86A15, 619 .tuner_name = "MB 86A15", 620 .board_name = "VP1022", 621 .fw_name = "DST-03T" 622 }, 623 624 { 625 .tuner_type = TUNER_TYPE_MB86A15, 626 .tuner_name = "MB 86A15", 627 .board_name = "VP1025", 628 .fw_name = "DST-03T" 629 }, 630 631 { 632 .tuner_type = TUNER_TYPE_STV0299, 633 .tuner_name = "STV 0299", 634 .board_name = "VP1030", 635 .fw_name = "DST-CI" 636 }, 637 638 { 639 .tuner_type = TUNER_TYPE_STV0299, 640 .tuner_name = "STV 0299", 641 .board_name = "VP1030", 642 .fw_name = "DSTMCI" 643 }, 644 645 { 646 .tuner_type = TUNER_TYPE_UNKNOWN, 647 .tuner_name = "UNKNOWN", 648 .board_name = "VP2021", 649 .fw_name = "DCTNEW" 650 }, 651 652 { 653 .tuner_type = TUNER_TYPE_UNKNOWN, 654 .tuner_name = "UNKNOWN", 655 .board_name = "VP2030", 656 .fw_name = "DCT-CI" 657 }, 658 659 { 660 .tuner_type = TUNER_TYPE_UNKNOWN, 661 .tuner_name = "UNKNOWN", 662 .board_name = "VP2031", 663 .fw_name = "DCT-CI" 664 }, 665 666 { 667 .tuner_type = TUNER_TYPE_UNKNOWN, 668 .tuner_name = "UNKNOWN", 669 .board_name = "VP2040", 670 .fw_name = "DCT-CI" 671 }, 672 673 { 674 .tuner_type = TUNER_TYPE_UNKNOWN, 675 .tuner_name = "UNKNOWN", 676 .board_name = "VP3020", 677 .fw_name = "DTTFTA" 678 }, 679 680 { 681 .tuner_type = TUNER_TYPE_UNKNOWN, 682 .tuner_name = "UNKNOWN", 683 .board_name = "VP3021", 684 .fw_name = "DTTFTA" 685 }, 686 687 { 688 .tuner_type = TUNER_TYPE_TDA10046, 689 .tuner_name = "TDA10046", 690 .board_name = "VP3040", 691 .fw_name = "DTT-CI" 692 }, 693 694 { 695 .tuner_type = TUNER_TYPE_UNKNOWN, 696 .tuner_name = "UNKNOWN", 697 .board_name = "VP3051", 698 .fw_name = "DTTNXT" 699 }, 700 701 { 702 .tuner_type = TUNER_TYPE_NXT200x, 703 .tuner_name = "NXT200x", 704 .board_name = "VP3220", 705 .fw_name = "ATSCDI" 706 }, 707 708 { 709 .tuner_type = TUNER_TYPE_NXT200x, 710 .tuner_name = "NXT200x", 711 .board_name = "VP3250", 712 .fw_name = "ATSCAD" 713 }, 714 }; 715 716 /* 717 Known cards list 718 Satellite 719 ------------------- 720 200103A 721 VP-1020 DST-MOT LG(old), TS=188 722 723 VP-1020 DST-03T LG(new), TS=204 724 VP-1022 DST-03T LG(new), TS=204 725 VP-1025 DST-03T LG(new), TS=204 726 727 VP-1030 DSTMCI, LG(new), TS=188 728 VP-1032 DSTMCI, LG(new), TS=188 729 730 Cable 731 ------------------- 732 VP-2030 DCT-CI, Samsung, TS=204 733 VP-2021 DCT-CI, Unknown, TS=204 734 VP-2031 DCT-CI, Philips, TS=188 735 VP-2040 DCT-CI, Philips, TS=188, with CA daughter board 736 VP-2040 DCT-CI, Philips, TS=204, without CA daughter board 737 738 Terrestrial 739 ------------------- 740 VP-3050 DTTNXT TS=188 741 VP-3040 DTT-CI, Philips, TS=188 742 VP-3040 DTT-CI, Philips, TS=204 743 744 ATSC 745 ------------------- 746 VP-3220 ATSCDI, TS=188 747 VP-3250 ATSCAD, TS=188 748 749 */ 750 751 static struct dst_types dst_tlist[] = { 752 { 753 .device_id = "200103A", 754 .offset = 0, 755 .dst_type = DST_TYPE_IS_SAT, 756 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, 757 .dst_feature = 0, 758 .tuner_type = 0 759 }, /* obsolete */ 760 761 { 762 .device_id = "DST-020", 763 .offset = 0, 764 .dst_type = DST_TYPE_IS_SAT, 765 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, 766 .dst_feature = 0, 767 .tuner_type = 0 768 }, /* obsolete */ 769 770 { 771 .device_id = "DST-030", 772 .offset = 0, 773 .dst_type = DST_TYPE_IS_SAT, 774 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, 775 .dst_feature = 0, 776 .tuner_type = 0 777 }, /* obsolete */ 778 779 { 780 .device_id = "DST-03T", 781 .offset = 0, 782 .dst_type = DST_TYPE_IS_SAT, 783 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, 784 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 785 | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO, 786 .tuner_type = TUNER_TYPE_MULTI 787 }, 788 789 { 790 .device_id = "DST-MOT", 791 .offset = 0, 792 .dst_type = DST_TYPE_IS_SAT, 793 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, 794 .dst_feature = 0, 795 .tuner_type = 0 796 }, /* obsolete */ 797 798 { 799 .device_id = "DST-CI", 800 .offset = 1, 801 .dst_type = DST_TYPE_IS_SAT, 802 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1, 803 .dst_feature = DST_TYPE_HAS_CA, 804 .tuner_type = 0 805 }, /* An OEM board */ 806 807 { 808 .device_id = "DSTMCI", 809 .offset = 1, 810 .dst_type = DST_TYPE_IS_SAT, 811 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF, 812 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 813 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC, 814 .tuner_type = TUNER_TYPE_MULTI 815 }, 816 817 { 818 .device_id = "DSTFCI", 819 .offset = 1, 820 .dst_type = DST_TYPE_IS_SAT, 821 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, 822 .dst_feature = 0, 823 .tuner_type = 0 824 }, /* unknown to vendor */ 825 826 { 827 .device_id = "DCT-CI", 828 .offset = 1, 829 .dst_type = DST_TYPE_IS_CABLE, 830 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF, 831 .dst_feature = DST_TYPE_HAS_CA, 832 .tuner_type = 0 833 }, 834 835 { 836 .device_id = "DCTNEW", 837 .offset = 1, 838 .dst_type = DST_TYPE_IS_CABLE, 839 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE, 840 .dst_feature = 0, 841 .tuner_type = 0 842 }, 843 844 { 845 .device_id = "DTT-CI", 846 .offset = 1, 847 .dst_type = DST_TYPE_IS_TERR, 848 .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF, 849 .dst_feature = DST_TYPE_HAS_CA, 850 .tuner_type = 0 851 }, 852 853 { 854 .device_id = "DTTDIG", 855 .offset = 1, 856 .dst_type = DST_TYPE_IS_TERR, 857 .type_flags = DST_TYPE_HAS_FW_2, 858 .dst_feature = 0, 859 .tuner_type = 0 860 }, 861 862 { 863 .device_id = "DTTNXT", 864 .offset = 1, 865 .dst_type = DST_TYPE_IS_TERR, 866 .type_flags = DST_TYPE_HAS_FW_2, 867 .dst_feature = DST_TYPE_HAS_ANALOG, 868 .tuner_type = 0 869 }, 870 871 { 872 .device_id = "ATSCDI", 873 .offset = 1, 874 .dst_type = DST_TYPE_IS_ATSC, 875 .type_flags = DST_TYPE_HAS_FW_2, 876 .dst_feature = 0, 877 .tuner_type = 0 878 }, 879 880 { 881 .device_id = "ATSCAD", 882 .offset = 1, 883 .dst_type = DST_TYPE_IS_ATSC, 884 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, 885 .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG, 886 .tuner_type = 0 887 }, 888 889 { } 890 891 }; 892 893 static int dst_get_mac(struct dst_state *state) 894 { 895 u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 896 get_mac[7] = dst_check_sum(get_mac, 7); 897 if (dst_command(state, get_mac, 8) < 0) { 898 dprintk(2, "Unsupported Command\n"); 899 return -1; 900 } 901 memset(&state->mac_address, '\0', 8); 902 memcpy(&state->mac_address, &state->rxbuffer, 6); 903 pr_err("MAC Address=[%pM]\n", state->mac_address); 904 905 return 0; 906 } 907 908 static int dst_fw_ver(struct dst_state *state) 909 { 910 u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 911 get_ver[7] = dst_check_sum(get_ver, 7); 912 if (dst_command(state, get_ver, 8) < 0) { 913 dprintk(2, "Unsupported Command\n"); 914 return -1; 915 } 916 memcpy(&state->fw_version, &state->rxbuffer, 8); 917 pr_err("Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x\n", 918 state->fw_version[0] >> 4, state->fw_version[0] & 0x0f, 919 state->fw_version[1], 920 state->fw_version[5], state->fw_version[6], 921 state->fw_version[4], state->fw_version[3], state->fw_version[2]); 922 923 return 0; 924 } 925 926 static int dst_card_type(struct dst_state *state) 927 { 928 int j; 929 struct tuner_types *p_tuner_list = NULL; 930 931 u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 932 get_type[7] = dst_check_sum(get_type, 7); 933 if (dst_command(state, get_type, 8) < 0) { 934 dprintk(2, "Unsupported Command\n"); 935 return -1; 936 } 937 memset(&state->card_info, '\0', 8); 938 memcpy(&state->card_info, &state->rxbuffer, 7); 939 pr_err("Device Model=[%s]\n", &state->card_info[0]); 940 941 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { 942 if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) { 943 state->tuner_type = p_tuner_list->tuner_type; 944 pr_err("DST has [%s] tuner, tuner type=[%d]\n", 945 p_tuner_list->tuner_name, p_tuner_list->tuner_type); 946 } 947 } 948 949 return 0; 950 } 951 952 static int dst_get_vendor(struct dst_state *state) 953 { 954 u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 955 get_vendor[7] = dst_check_sum(get_vendor, 7); 956 if (dst_command(state, get_vendor, 8) < 0) { 957 dprintk(2, "Unsupported Command\n"); 958 return -1; 959 } 960 memset(&state->vendor, '\0', 8); 961 memcpy(&state->vendor, &state->rxbuffer, 7); 962 pr_err("Vendor=[%s]\n", &state->vendor[0]); 963 964 return 0; 965 } 966 967 static void debug_dst_buffer(struct dst_state *state) 968 { 969 dprintk(3, "%s: [ %*ph ]\n", __func__, 8, state->rxbuffer); 970 } 971 972 static int dst_check_stv0299(struct dst_state *state) 973 { 974 u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 975 976 check_stv0299[7] = dst_check_sum(check_stv0299, 7); 977 if (dst_command(state, check_stv0299, 8) < 0) { 978 pr_err("Cmd=[0x04] failed\n"); 979 return -1; 980 } 981 debug_dst_buffer(state); 982 983 if (memcmp(&check_stv0299, &state->rxbuffer, 8)) { 984 pr_err("Found a STV0299 NIM\n"); 985 state->tuner_type = TUNER_TYPE_STV0299; 986 return 0; 987 } 988 989 return -1; 990 } 991 992 static int dst_check_mb86a15(struct dst_state *state) 993 { 994 u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 995 996 check_mb86a15[7] = dst_check_sum(check_mb86a15, 7); 997 if (dst_command(state, check_mb86a15, 8) < 0) { 998 pr_err("Cmd=[0x10], failed\n"); 999 return -1; 1000 } 1001 debug_dst_buffer(state); 1002 1003 if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) { 1004 pr_err("Found a MB86A15 NIM\n"); 1005 state->tuner_type = TUNER_TYPE_MB86A15; 1006 return 0; 1007 } 1008 1009 return -1; 1010 } 1011 1012 static int dst_get_tuner_info(struct dst_state *state) 1013 { 1014 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1015 u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1016 1017 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); 1018 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); 1019 pr_err("DST TYpe = MULTI FE\n"); 1020 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { 1021 if (dst_command(state, get_tuner_1, 8) < 0) { 1022 dprintk(2, "Cmd=[0x13], Unsupported\n"); 1023 goto force; 1024 } 1025 } else { 1026 if (dst_command(state, get_tuner_2, 8) < 0) { 1027 dprintk(2, "Cmd=[0xb], Unsupported\n"); 1028 goto force; 1029 } 1030 } 1031 memcpy(&state->board_info, &state->rxbuffer, 8); 1032 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { 1033 pr_err("DST type has TS=188\n"); 1034 } 1035 if (state->board_info[0] == 0xbc) { 1036 if (state->dst_type != DST_TYPE_IS_ATSC) 1037 state->type_flags |= DST_TYPE_HAS_TS188; 1038 else 1039 state->type_flags |= DST_TYPE_HAS_NEWTUNE_2; 1040 1041 if (state->board_info[1] == 0x01) { 1042 state->dst_hw_cap |= DST_TYPE_HAS_DBOARD; 1043 pr_err("DST has Daughterboard\n"); 1044 } 1045 } 1046 1047 return 0; 1048 force: 1049 if (!strncmp(state->fw_name, "DCT-CI", 6)) { 1050 state->type_flags |= DST_TYPE_HAS_TS204; 1051 pr_err("Forcing [%s] to TS188\n", state->fw_name); 1052 } 1053 1054 return -1; 1055 } 1056 1057 static int dst_get_device_id(struct dst_state *state) 1058 { 1059 u8 reply; 1060 1061 int i, j; 1062 struct dst_types *p_dst_type = NULL; 1063 struct tuner_types *p_tuner_list = NULL; 1064 1065 u8 use_dst_type = 0; 1066 u32 use_type_flags = 0; 1067 1068 static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 1069 1070 state->tuner_type = 0; 1071 device_type[7] = dst_check_sum(device_type, 7); 1072 1073 if (write_dst(state, device_type, FIXED_COMM)) 1074 return -1; /* Write failed */ 1075 if ((dst_pio_disable(state)) < 0) 1076 return -1; 1077 if (read_dst(state, &reply, GET_ACK)) 1078 return -1; /* Read failure */ 1079 if (reply != ACK) { 1080 dprintk(2, "Write not Acknowledged! [Reply=0x%02x]\n", reply); 1081 return -1; /* Unack'd write */ 1082 } 1083 if (!dst_wait_dst_ready(state, DEVICE_INIT)) 1084 return -1; /* DST not ready yet */ 1085 if (read_dst(state, state->rxbuffer, FIXED_COMM)) 1086 return -1; 1087 1088 dst_pio_disable(state); 1089 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 1090 dprintk(2, "Checksum failure!\n"); 1091 return -1; /* Checksum failure */ 1092 } 1093 state->rxbuffer[7] = '\0'; 1094 1095 for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) { 1096 if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) { 1097 use_type_flags = p_dst_type->type_flags; 1098 use_dst_type = p_dst_type->dst_type; 1099 1100 /* Card capabilities */ 1101 state->dst_hw_cap = p_dst_type->dst_feature; 1102 pr_err("Recognise [%s]\n", p_dst_type->device_id); 1103 strscpy(state->fw_name, p_dst_type->device_id, 1104 sizeof(state->fw_name)); 1105 /* Multiple tuners */ 1106 if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { 1107 switch (use_dst_type) { 1108 case DST_TYPE_IS_SAT: 1109 /* STV0299 check */ 1110 if (dst_check_stv0299(state) < 0) { 1111 pr_err("Unsupported\n"); 1112 state->tuner_type = TUNER_TYPE_MB86A15; 1113 } 1114 break; 1115 default: 1116 break; 1117 } 1118 if (dst_check_mb86a15(state) < 0) 1119 pr_err("Unsupported\n"); 1120 /* Single tuner */ 1121 } else { 1122 state->tuner_type = p_dst_type->tuner_type; 1123 } 1124 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { 1125 if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) && 1126 p_tuner_list->tuner_type == state->tuner_type) { 1127 pr_err("[%s] has a [%s]\n", 1128 p_dst_type->device_id, p_tuner_list->tuner_name); 1129 } 1130 } 1131 break; 1132 } 1133 } 1134 1135 if (i >= ARRAY_SIZE(dst_tlist)) { 1136 pr_err("Unable to recognize %s or %s\n", &state->rxbuffer[0], &state->rxbuffer[1]); 1137 pr_err("please email linux-dvb@linuxtv.org with this type in"); 1138 use_dst_type = DST_TYPE_IS_SAT; 1139 use_type_flags = DST_TYPE_HAS_SYMDIV; 1140 } 1141 dst_type_print(state, use_dst_type); 1142 state->type_flags = use_type_flags; 1143 state->dst_type = use_dst_type; 1144 dst_type_flags_print(state); 1145 1146 return 0; 1147 } 1148 1149 static int dst_probe(struct dst_state *state) 1150 { 1151 mutex_init(&state->dst_mutex); 1152 if (dst_addons & DST_TYPE_HAS_CA) { 1153 if ((rdc_8820_reset(state)) < 0) { 1154 pr_err("RDC 8820 RESET Failed.\n"); 1155 return -1; 1156 } 1157 msleep(4000); 1158 } else { 1159 msleep(100); 1160 } 1161 if ((dst_comm_init(state)) < 0) { 1162 pr_err("DST Initialization Failed.\n"); 1163 return -1; 1164 } 1165 msleep(100); 1166 if (dst_get_device_id(state) < 0) { 1167 pr_err("unknown device.\n"); 1168 return -1; 1169 } 1170 if (dst_get_mac(state) < 0) { 1171 dprintk(2, "MAC: Unsupported command\n"); 1172 } 1173 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { 1174 if (dst_get_tuner_info(state) < 0) 1175 dprintk(2, "Tuner: Unsupported command\n"); 1176 } 1177 if (state->type_flags & DST_TYPE_HAS_TS204) { 1178 dst_packsize(state, 204); 1179 } 1180 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { 1181 if (dst_fw_ver(state) < 0) { 1182 dprintk(2, "FW: Unsupported command\n"); 1183 return 0; 1184 } 1185 if (dst_card_type(state) < 0) { 1186 dprintk(2, "Card: Unsupported command\n"); 1187 return 0; 1188 } 1189 if (dst_get_vendor(state) < 0) { 1190 dprintk(2, "Vendor: Unsupported command\n"); 1191 return 0; 1192 } 1193 } 1194 1195 return 0; 1196 } 1197 1198 static int dst_command(struct dst_state *state, u8 *data, u8 len) 1199 { 1200 u8 reply; 1201 1202 mutex_lock(&state->dst_mutex); 1203 if ((dst_comm_init(state)) < 0) { 1204 dprintk(1, "DST Communication Initialization Failed.\n"); 1205 goto error; 1206 } 1207 if (write_dst(state, data, len)) { 1208 dprintk(2, "Trying to recover..\n"); 1209 if ((dst_error_recovery(state)) < 0) { 1210 pr_err("Recovery Failed.\n"); 1211 goto error; 1212 } 1213 goto error; 1214 } 1215 if ((dst_pio_disable(state)) < 0) { 1216 pr_err("PIO Disable Failed.\n"); 1217 goto error; 1218 } 1219 if (state->type_flags & DST_TYPE_HAS_FW_1) 1220 mdelay(3); 1221 if (read_dst(state, &reply, GET_ACK)) { 1222 dprintk(3, "Trying to recover..\n"); 1223 if ((dst_error_recovery(state)) < 0) { 1224 dprintk(2, "Recovery Failed.\n"); 1225 goto error; 1226 } 1227 goto error; 1228 } 1229 if (reply != ACK) { 1230 dprintk(2, "write not acknowledged 0x%02x\n", reply); 1231 goto error; 1232 } 1233 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 1234 goto error; 1235 if (state->type_flags & DST_TYPE_HAS_FW_1) 1236 mdelay(3); 1237 else 1238 udelay(2000); 1239 if (!dst_wait_dst_ready(state, NO_DELAY)) 1240 goto error; 1241 if (read_dst(state, state->rxbuffer, FIXED_COMM)) { 1242 dprintk(3, "Trying to recover..\n"); 1243 if ((dst_error_recovery(state)) < 0) { 1244 dprintk(2, "Recovery failed.\n"); 1245 goto error; 1246 } 1247 goto error; 1248 } 1249 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 1250 dprintk(2, "checksum failure\n"); 1251 goto error; 1252 } 1253 mutex_unlock(&state->dst_mutex); 1254 return 0; 1255 1256 error: 1257 mutex_unlock(&state->dst_mutex); 1258 return -EIO; 1259 1260 } 1261 1262 static int dst_get_signal(struct dst_state *state) 1263 { 1264 int retval; 1265 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb }; 1266 //dprintk("%s: Getting Signal strength and other parameters\n", __func__); 1267 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) { 1268 state->decode_lock = state->decode_strength = state->decode_snr = 0; 1269 return 0; 1270 } 1271 if (0 == (state->diseq_flags & HAS_LOCK)) { 1272 state->decode_lock = state->decode_strength = state->decode_snr = 0; 1273 return 0; 1274 } 1275 if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) { 1276 retval = dst_command(state, get_signal, 8); 1277 if (retval < 0) 1278 return retval; 1279 if (state->dst_type == DST_TYPE_IS_SAT) { 1280 state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0; 1281 state->decode_strength = state->rxbuffer[5] << 8; 1282 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; 1283 } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) { 1284 state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; 1285 state->decode_strength = state->rxbuffer[4] << 8; 1286 state->decode_snr = state->rxbuffer[3] << 8; 1287 } else if (state->dst_type == DST_TYPE_IS_ATSC) { 1288 state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0; 1289 state->decode_strength = state->rxbuffer[4] << 8; 1290 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; 1291 } 1292 state->cur_jiff = jiffies; 1293 } 1294 return 0; 1295 } 1296 1297 static int dst_tone_power_cmd(struct dst_state *state) 1298 { 1299 u8 packet[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 }; 1300 1301 if (state->dst_type != DST_TYPE_IS_SAT) 1302 return -EOPNOTSUPP; 1303 packet[4] = state->tx_tuna[4]; 1304 packet[2] = state->tx_tuna[2]; 1305 packet[3] = state->tx_tuna[3]; 1306 packet[7] = dst_check_sum (packet, 7); 1307 return dst_command(state, packet, 8); 1308 } 1309 1310 static int dst_get_tuna(struct dst_state *state) 1311 { 1312 int retval; 1313 1314 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) 1315 return 0; 1316 state->diseq_flags &= ~(HAS_LOCK); 1317 if (!dst_wait_dst_ready(state, NO_DELAY)) 1318 return -EIO; 1319 if ((state->type_flags & DST_TYPE_HAS_VLF) && 1320 !(state->dst_type == DST_TYPE_IS_ATSC)) 1321 1322 retval = read_dst(state, state->rx_tuna, 10); 1323 else 1324 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); 1325 if (retval < 0) { 1326 dprintk(3, "read not successful\n"); 1327 return retval; 1328 } 1329 if ((state->type_flags & DST_TYPE_HAS_VLF) && 1330 !(state->dst_type == DST_TYPE_IS_ATSC)) { 1331 1332 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 1333 dprintk(2, "checksum failure ?\n"); 1334 return -EIO; 1335 } 1336 } else { 1337 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { 1338 dprintk(2, "checksum failure?\n"); 1339 return -EIO; 1340 } 1341 } 1342 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) 1343 return 0; 1344 if (state->dst_type == DST_TYPE_IS_SAT) { 1345 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; 1346 } else { 1347 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4]; 1348 } 1349 state->decode_freq = state->decode_freq * 1000; 1350 state->decode_lock = 1; 1351 state->diseq_flags |= HAS_LOCK; 1352 1353 return 1; 1354 } 1355 1356 static int dst_set_voltage(struct dvb_frontend *fe, 1357 enum fe_sec_voltage voltage); 1358 1359 static int dst_write_tuna(struct dvb_frontend *fe) 1360 { 1361 struct dst_state *state = fe->demodulator_priv; 1362 int retval; 1363 u8 reply; 1364 1365 dprintk(2, "type_flags 0x%x\n", state->type_flags); 1366 state->decode_freq = 0; 1367 state->decode_lock = state->decode_strength = state->decode_snr = 0; 1368 if (state->dst_type == DST_TYPE_IS_SAT) { 1369 if (!(state->diseq_flags & HAS_POWER)) 1370 dst_set_voltage(fe, SEC_VOLTAGE_13); 1371 } 1372 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 1373 mutex_lock(&state->dst_mutex); 1374 if ((dst_comm_init(state)) < 0) { 1375 dprintk(3, "DST Communication initialization failed.\n"); 1376 goto error; 1377 } 1378 // if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1379 if ((state->type_flags & DST_TYPE_HAS_VLF) && 1380 (!(state->dst_type == DST_TYPE_IS_ATSC))) { 1381 1382 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 1383 retval = write_dst(state, &state->tx_tuna[0], 10); 1384 } else { 1385 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); 1386 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM); 1387 } 1388 if (retval < 0) { 1389 dst_pio_disable(state); 1390 dprintk(3, "write not successful\n"); 1391 goto werr; 1392 } 1393 if ((dst_pio_disable(state)) < 0) { 1394 dprintk(3, "DST PIO disable failed !\n"); 1395 goto error; 1396 } 1397 if ((read_dst(state, &reply, GET_ACK) < 0)) { 1398 dprintk(3, "read verify not successful.\n"); 1399 goto error; 1400 } 1401 if (reply != ACK) { 1402 dprintk(3, "write not acknowledged 0x%02x\n", reply); 1403 goto error; 1404 } 1405 state->diseq_flags |= ATTEMPT_TUNE; 1406 retval = dst_get_tuna(state); 1407 werr: 1408 mutex_unlock(&state->dst_mutex); 1409 return retval; 1410 1411 error: 1412 mutex_unlock(&state->dst_mutex); 1413 return -EIO; 1414 } 1415 1416 /* 1417 * line22k0 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00 1418 * line22k1 0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00 1419 * line22k2 0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00 1420 * tone 0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00 1421 * data 0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00 1422 * power_off 0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 1423 * power_on 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 1424 * Diseqc 1 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec 1425 * Diseqc 2 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8 1426 * Diseqc 3 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4 1427 * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0 1428 */ 1429 1430 static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) 1431 { 1432 struct dst_state *state = fe->demodulator_priv; 1433 u8 packet[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; 1434 1435 if (state->dst_type != DST_TYPE_IS_SAT) 1436 return -EOPNOTSUPP; 1437 if (cmd->msg_len > 0 && cmd->msg_len < 5) 1438 memcpy(&packet[3], cmd->msg, cmd->msg_len); 1439 else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5) 1440 memcpy(&packet[2], cmd->msg, cmd->msg_len); 1441 else 1442 return -EINVAL; 1443 packet[7] = dst_check_sum(&packet[0], 7); 1444 return dst_command(state, packet, 8); 1445 } 1446 1447 static int dst_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) 1448 { 1449 int need_cmd, retval = 0; 1450 struct dst_state *state = fe->demodulator_priv; 1451 1452 state->voltage = voltage; 1453 if (state->dst_type != DST_TYPE_IS_SAT) 1454 return -EOPNOTSUPP; 1455 1456 need_cmd = 0; 1457 1458 switch (voltage) { 1459 case SEC_VOLTAGE_13: 1460 case SEC_VOLTAGE_18: 1461 if ((state->diseq_flags & HAS_POWER) == 0) 1462 need_cmd = 1; 1463 state->diseq_flags |= HAS_POWER; 1464 state->tx_tuna[4] = 0x01; 1465 break; 1466 case SEC_VOLTAGE_OFF: 1467 need_cmd = 1; 1468 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); 1469 state->tx_tuna[4] = 0x00; 1470 break; 1471 default: 1472 return -EINVAL; 1473 } 1474 1475 if (need_cmd) 1476 retval = dst_tone_power_cmd(state); 1477 1478 return retval; 1479 } 1480 1481 static int dst_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) 1482 { 1483 struct dst_state *state = fe->demodulator_priv; 1484 1485 state->tone = tone; 1486 if (state->dst_type != DST_TYPE_IS_SAT) 1487 return -EOPNOTSUPP; 1488 1489 switch (tone) { 1490 case SEC_TONE_OFF: 1491 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) 1492 state->tx_tuna[2] = 0x00; 1493 else 1494 state->tx_tuna[2] = 0xff; 1495 break; 1496 1497 case SEC_TONE_ON: 1498 state->tx_tuna[2] = 0x02; 1499 break; 1500 default: 1501 return -EINVAL; 1502 } 1503 return dst_tone_power_cmd(state); 1504 } 1505 1506 static int dst_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd minicmd) 1507 { 1508 struct dst_state *state = fe->demodulator_priv; 1509 1510 if (state->dst_type != DST_TYPE_IS_SAT) 1511 return -EOPNOTSUPP; 1512 state->minicmd = minicmd; 1513 switch (minicmd) { 1514 case SEC_MINI_A: 1515 state->tx_tuna[3] = 0x02; 1516 break; 1517 case SEC_MINI_B: 1518 state->tx_tuna[3] = 0xff; 1519 break; 1520 } 1521 return dst_tone_power_cmd(state); 1522 } 1523 1524 1525 static int bt8xx_dst_init(struct dvb_frontend *fe) 1526 { 1527 struct dst_state *state = fe->demodulator_priv; 1528 1529 static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 }; 1530 static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; 1531 static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; 1532 static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; 1533 static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; 1534 static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; 1535 static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; 1536 1537 state->inversion = INVERSION_OFF; 1538 state->voltage = SEC_VOLTAGE_13; 1539 state->tone = SEC_TONE_OFF; 1540 state->diseq_flags = 0; 1541 state->k22 = 0x02; 1542 state->bandwidth = 7000000; 1543 state->cur_jiff = jiffies; 1544 if (state->dst_type == DST_TYPE_IS_SAT) 1545 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); 1546 else if (state->dst_type == DST_TYPE_IS_TERR) 1547 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); 1548 else if (state->dst_type == DST_TYPE_IS_CABLE) 1549 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); 1550 else if (state->dst_type == DST_TYPE_IS_ATSC) 1551 memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner)); 1552 1553 return 0; 1554 } 1555 1556 static int dst_read_status(struct dvb_frontend *fe, enum fe_status *status) 1557 { 1558 struct dst_state *state = fe->demodulator_priv; 1559 1560 *status = 0; 1561 if (state->diseq_flags & HAS_LOCK) { 1562 // dst_get_signal(state); // don't require(?) to ask MCU 1563 if (state->decode_lock) 1564 *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI; 1565 } 1566 1567 return 0; 1568 } 1569 1570 static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 1571 { 1572 struct dst_state *state = fe->demodulator_priv; 1573 1574 int retval = dst_get_signal(state); 1575 *strength = state->decode_strength; 1576 1577 return retval; 1578 } 1579 1580 static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) 1581 { 1582 struct dst_state *state = fe->demodulator_priv; 1583 1584 int retval = dst_get_signal(state); 1585 *snr = state->decode_snr; 1586 1587 return retval; 1588 } 1589 1590 static int dst_set_frontend(struct dvb_frontend *fe) 1591 { 1592 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 1593 int retval = -EINVAL; 1594 struct dst_state *state = fe->demodulator_priv; 1595 1596 if (p != NULL) { 1597 retval = dst_set_freq(state, p->frequency); 1598 if(retval != 0) 1599 return retval; 1600 dprintk(3, "Set Frequency=[%d]\n", p->frequency); 1601 1602 if (state->dst_type == DST_TYPE_IS_SAT) { 1603 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) 1604 dst_set_inversion(state, p->inversion); 1605 dst_set_fec(state, p->fec_inner); 1606 dst_set_symbolrate(state, p->symbol_rate); 1607 dst_set_polarization(state); 1608 dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate); 1609 1610 } else if (state->dst_type == DST_TYPE_IS_TERR) 1611 dst_set_bandwidth(state, p->bandwidth_hz); 1612 else if (state->dst_type == DST_TYPE_IS_CABLE) { 1613 dst_set_fec(state, p->fec_inner); 1614 dst_set_symbolrate(state, p->symbol_rate); 1615 dst_set_modulation(state, p->modulation); 1616 } 1617 retval = dst_write_tuna(fe); 1618 } 1619 1620 return retval; 1621 } 1622 1623 static int dst_tune_frontend(struct dvb_frontend* fe, 1624 bool re_tune, 1625 unsigned int mode_flags, 1626 unsigned int *delay, 1627 enum fe_status *status) 1628 { 1629 struct dst_state *state = fe->demodulator_priv; 1630 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 1631 1632 if (re_tune) { 1633 dst_set_freq(state, p->frequency); 1634 dprintk(3, "Set Frequency=[%d]\n", p->frequency); 1635 1636 if (state->dst_type == DST_TYPE_IS_SAT) { 1637 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) 1638 dst_set_inversion(state, p->inversion); 1639 dst_set_fec(state, p->fec_inner); 1640 dst_set_symbolrate(state, p->symbol_rate); 1641 dst_set_polarization(state); 1642 dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate); 1643 1644 } else if (state->dst_type == DST_TYPE_IS_TERR) 1645 dst_set_bandwidth(state, p->bandwidth_hz); 1646 else if (state->dst_type == DST_TYPE_IS_CABLE) { 1647 dst_set_fec(state, p->fec_inner); 1648 dst_set_symbolrate(state, p->symbol_rate); 1649 dst_set_modulation(state, p->modulation); 1650 } 1651 dst_write_tuna(fe); 1652 } 1653 1654 if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) 1655 dst_read_status(fe, status); 1656 1657 *delay = HZ/10; 1658 return 0; 1659 } 1660 1661 static enum dvbfe_algo dst_get_tuning_algo(struct dvb_frontend *fe) 1662 { 1663 return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW; 1664 } 1665 1666 static int dst_get_frontend(struct dvb_frontend *fe, 1667 struct dtv_frontend_properties *p) 1668 { 1669 struct dst_state *state = fe->demodulator_priv; 1670 1671 p->frequency = state->decode_freq; 1672 if (state->dst_type == DST_TYPE_IS_SAT) { 1673 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) 1674 p->inversion = state->inversion; 1675 p->symbol_rate = state->symbol_rate; 1676 p->fec_inner = dst_get_fec(state); 1677 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1678 p->bandwidth_hz = state->bandwidth; 1679 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 1680 p->symbol_rate = state->symbol_rate; 1681 p->fec_inner = dst_get_fec(state); 1682 p->modulation = dst_get_modulation(state); 1683 } 1684 1685 return 0; 1686 } 1687 1688 static void bt8xx_dst_release(struct dvb_frontend *fe) 1689 { 1690 struct dst_state *state = fe->demodulator_priv; 1691 if (state->dst_ca) { 1692 dvb_unregister_device(state->dst_ca); 1693 #ifdef CONFIG_MEDIA_ATTACH 1694 symbol_put(dst_ca_attach); 1695 #endif 1696 } 1697 kfree(state); 1698 } 1699 1700 static const struct dvb_frontend_ops dst_dvbt_ops; 1701 static const struct dvb_frontend_ops dst_dvbs_ops; 1702 static const struct dvb_frontend_ops dst_dvbc_ops; 1703 static const struct dvb_frontend_ops dst_atsc_ops; 1704 1705 struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) 1706 { 1707 /* check if the ASIC is there */ 1708 if (dst_probe(state) < 0) { 1709 kfree(state); 1710 return NULL; 1711 } 1712 /* determine settings based on type */ 1713 /* create dvb_frontend */ 1714 switch (state->dst_type) { 1715 case DST_TYPE_IS_TERR: 1716 memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); 1717 break; 1718 case DST_TYPE_IS_CABLE: 1719 memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); 1720 break; 1721 case DST_TYPE_IS_SAT: 1722 memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); 1723 break; 1724 case DST_TYPE_IS_ATSC: 1725 memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops)); 1726 break; 1727 default: 1728 pr_err("unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n"); 1729 kfree(state); 1730 return NULL; 1731 } 1732 state->frontend.demodulator_priv = state; 1733 1734 return state; /* Manu (DST is a card not a frontend) */ 1735 } 1736 1737 EXPORT_SYMBOL(dst_attach); 1738 1739 static const struct dvb_frontend_ops dst_dvbt_ops = { 1740 .delsys = { SYS_DVBT }, 1741 .info = { 1742 .name = "DST DVB-T", 1743 .frequency_min_hz = 137 * MHz, 1744 .frequency_max_hz = 858 * MHz, 1745 .frequency_stepsize_hz = 166667, 1746 .caps = FE_CAN_FEC_AUTO | 1747 FE_CAN_QAM_AUTO | 1748 FE_CAN_QAM_16 | 1749 FE_CAN_QAM_32 | 1750 FE_CAN_QAM_64 | 1751 FE_CAN_QAM_128 | 1752 FE_CAN_QAM_256 | 1753 FE_CAN_TRANSMISSION_MODE_AUTO | 1754 FE_CAN_GUARD_INTERVAL_AUTO 1755 }, 1756 1757 .release = bt8xx_dst_release, 1758 .init = bt8xx_dst_init, 1759 .tune = dst_tune_frontend, 1760 .set_frontend = dst_set_frontend, 1761 .get_frontend = dst_get_frontend, 1762 .get_frontend_algo = dst_get_tuning_algo, 1763 .read_status = dst_read_status, 1764 .read_signal_strength = dst_read_signal_strength, 1765 .read_snr = dst_read_snr, 1766 }; 1767 1768 static const struct dvb_frontend_ops dst_dvbs_ops = { 1769 .delsys = { SYS_DVBS }, 1770 .info = { 1771 .name = "DST DVB-S", 1772 .frequency_min_hz = 950 * MHz, 1773 .frequency_max_hz = 2150 * MHz, 1774 .frequency_stepsize_hz = 1 * MHz, 1775 .frequency_tolerance_hz = 29500 * kHz, 1776 .symbol_rate_min = 1000000, 1777 .symbol_rate_max = 45000000, 1778 /* . symbol_rate_tolerance = ???,*/ 1779 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK 1780 }, 1781 1782 .release = bt8xx_dst_release, 1783 .init = bt8xx_dst_init, 1784 .tune = dst_tune_frontend, 1785 .set_frontend = dst_set_frontend, 1786 .get_frontend = dst_get_frontend, 1787 .get_frontend_algo = dst_get_tuning_algo, 1788 .read_status = dst_read_status, 1789 .read_signal_strength = dst_read_signal_strength, 1790 .read_snr = dst_read_snr, 1791 .diseqc_send_burst = dst_send_burst, 1792 .diseqc_send_master_cmd = dst_set_diseqc, 1793 .set_voltage = dst_set_voltage, 1794 .set_tone = dst_set_tone, 1795 }; 1796 1797 static const struct dvb_frontend_ops dst_dvbc_ops = { 1798 .delsys = { SYS_DVBC_ANNEX_A }, 1799 .info = { 1800 .name = "DST DVB-C", 1801 .frequency_min_hz = 51 * MHz, 1802 .frequency_max_hz = 858 * MHz, 1803 .frequency_stepsize_hz = 62500, 1804 .symbol_rate_min = 1000000, 1805 .symbol_rate_max = 45000000, 1806 .caps = FE_CAN_FEC_AUTO | 1807 FE_CAN_QAM_AUTO | 1808 FE_CAN_QAM_16 | 1809 FE_CAN_QAM_32 | 1810 FE_CAN_QAM_64 | 1811 FE_CAN_QAM_128 | 1812 FE_CAN_QAM_256 1813 }, 1814 1815 .release = bt8xx_dst_release, 1816 .init = bt8xx_dst_init, 1817 .tune = dst_tune_frontend, 1818 .set_frontend = dst_set_frontend, 1819 .get_frontend = dst_get_frontend, 1820 .get_frontend_algo = dst_get_tuning_algo, 1821 .read_status = dst_read_status, 1822 .read_signal_strength = dst_read_signal_strength, 1823 .read_snr = dst_read_snr, 1824 }; 1825 1826 static const struct dvb_frontend_ops dst_atsc_ops = { 1827 .delsys = { SYS_ATSC }, 1828 .info = { 1829 .name = "DST ATSC", 1830 .frequency_min_hz = 510 * MHz, 1831 .frequency_max_hz = 858 * MHz, 1832 .frequency_stepsize_hz = 62500, 1833 .symbol_rate_min = 1000000, 1834 .symbol_rate_max = 45000000, 1835 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB 1836 }, 1837 1838 .release = bt8xx_dst_release, 1839 .init = bt8xx_dst_init, 1840 .tune = dst_tune_frontend, 1841 .set_frontend = dst_set_frontend, 1842 .get_frontend = dst_get_frontend, 1843 .get_frontend_algo = dst_get_tuning_algo, 1844 .read_status = dst_read_status, 1845 .read_signal_strength = dst_read_signal_strength, 1846 .read_snr = dst_read_snr, 1847 }; 1848 1849 MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver"); 1850 MODULE_AUTHOR("Jamie Honan, Manu Abraham"); 1851 MODULE_LICENSE("GPL"); 1852