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