linux/drivers/media/pci/bt8xx/dst.c
<<
>>
Prefs
   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
  35static unsigned int verbose;
  36module_param(verbose, int, 0644);
  37MODULE_PARM_DESC(verbose, "verbosity level (0 to 3)");
  38
  39static unsigned int dst_addons;
  40module_param(dst_addons, int, 0644);
  41MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
  42
  43static unsigned int dst_algo;
  44module_param(dst_algo, int, 0644);
  45MODULE_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
  57static int dst_command(struct dst_state *state, u8 *data, u8 len);
  58
  59static 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
  67static 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
 101static 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
 116int 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}
 132EXPORT_SYMBOL(rdc_reset_state);
 133
 134static 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
 150static 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
 161int 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}
 172EXPORT_SYMBOL(dst_pio_disable);
 173
 174int 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}
 194EXPORT_SYMBOL(dst_wait_dst_ready);
 195
 196int 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}
 206EXPORT_SYMBOL(dst_error_recovery);
 207
 208int 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}
 217EXPORT_SYMBOL(dst_error_bailout);
 218
 219int 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}
 237EXPORT_SYMBOL(dst_comm_init);
 238
 239int 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}
 271EXPORT_SYMBOL(write_dst);
 272
 273int 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}
 304EXPORT_SYMBOL(read_dst);
 305
 306static 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
 324static 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
 370static 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
 409static 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
 427static int dst_set_fec(struct dst_state *state, enum fe_code_rate fec)
 428{
 429        state->fec = fec;
 430        return 0;
 431}
 432
 433static enum fe_code_rate dst_get_fec(struct dst_state *state)
 434{
 435        return state->fec;
 436}
 437
 438static 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
 484static 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
 522static enum fe_modulation dst_get_modulation(struct dst_state *state)
 523{
 524        return state->modulation;
 525}
 526
 527
 528u8 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}
 539EXPORT_SYMBOL(dst_check_sum);
 540
 541static 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
 566static 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
 595static 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
 751static 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
 893static 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
 908static 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
 926static 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
 952static 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
 967static void debug_dst_buffer(struct dst_state *state)
 968{
 969        dprintk(3, "%s: [ %*ph ]\n", __func__, 8, state->rxbuffer);
 970}
 971
 972static 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
 992static 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
1012static 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;
1048force:
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
1057static 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                        strncpy(&state->fw_name[0], p_dst_type->device_id, 6);
1104                        /*      Multiple tuners         */
1105                        if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
1106                                switch (use_dst_type) {
1107                                case DST_TYPE_IS_SAT:
1108                                        /*      STV0299 check   */
1109                                        if (dst_check_stv0299(state) < 0) {
1110                                                pr_err("Unsupported\n");
1111                                                state->tuner_type = TUNER_TYPE_MB86A15;
1112                                        }
1113                                        break;
1114                                default:
1115                                        break;
1116                                }
1117                                if (dst_check_mb86a15(state) < 0)
1118                                        pr_err("Unsupported\n");
1119                        /*      Single tuner            */
1120                        } else {
1121                                state->tuner_type = p_dst_type->tuner_type;
1122                        }
1123                        for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
1124                                if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
1125                                        p_tuner_list->tuner_type == state->tuner_type) {
1126                                        pr_err("[%s] has a [%s]\n",
1127                                                p_dst_type->device_id, p_tuner_list->tuner_name);
1128                                }
1129                        }
1130                        break;
1131                }
1132        }
1133
1134        if (i >= ARRAY_SIZE(dst_tlist)) {
1135                pr_err("Unable to recognize %s or %s\n", &state->rxbuffer[0], &state->rxbuffer[1]);
1136                pr_err("please email linux-dvb@linuxtv.org with this type in");
1137                use_dst_type = DST_TYPE_IS_SAT;
1138                use_type_flags = DST_TYPE_HAS_SYMDIV;
1139        }
1140        dst_type_print(state, use_dst_type);
1141        state->type_flags = use_type_flags;
1142        state->dst_type = use_dst_type;
1143        dst_type_flags_print(state);
1144
1145        return 0;
1146}
1147
1148static int dst_probe(struct dst_state *state)
1149{
1150        mutex_init(&state->dst_mutex);
1151        if (dst_addons & DST_TYPE_HAS_CA) {
1152                if ((rdc_8820_reset(state)) < 0) {
1153                        pr_err("RDC 8820 RESET Failed.\n");
1154                        return -1;
1155                }
1156                msleep(4000);
1157        } else {
1158                msleep(100);
1159        }
1160        if ((dst_comm_init(state)) < 0) {
1161                pr_err("DST Initialization Failed.\n");
1162                return -1;
1163        }
1164        msleep(100);
1165        if (dst_get_device_id(state) < 0) {
1166                pr_err("unknown device.\n");
1167                return -1;
1168        }
1169        if (dst_get_mac(state) < 0) {
1170                dprintk(2, "MAC: Unsupported command\n");
1171        }
1172        if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
1173                if (dst_get_tuner_info(state) < 0)
1174                        dprintk(2, "Tuner: Unsupported command\n");
1175        }
1176        if (state->type_flags & DST_TYPE_HAS_TS204) {
1177                dst_packsize(state, 204);
1178        }
1179        if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
1180                if (dst_fw_ver(state) < 0) {
1181                        dprintk(2, "FW: Unsupported command\n");
1182                        return 0;
1183                }
1184                if (dst_card_type(state) < 0) {
1185                        dprintk(2, "Card: Unsupported command\n");
1186                        return 0;
1187                }
1188                if (dst_get_vendor(state) < 0) {
1189                        dprintk(2, "Vendor: Unsupported command\n");
1190                        return 0;
1191                }
1192        }
1193
1194        return 0;
1195}
1196
1197static int dst_command(struct dst_state *state, u8 *data, u8 len)
1198{
1199        u8 reply;
1200
1201        mutex_lock(&state->dst_mutex);
1202        if ((dst_comm_init(state)) < 0) {
1203                dprintk(1, "DST Communication Initialization Failed.\n");
1204                goto error;
1205        }
1206        if (write_dst(state, data, len)) {
1207                dprintk(2, "Trying to recover..\n");
1208                if ((dst_error_recovery(state)) < 0) {
1209                        pr_err("Recovery Failed.\n");
1210                        goto error;
1211                }
1212                goto error;
1213        }
1214        if ((dst_pio_disable(state)) < 0) {
1215                pr_err("PIO Disable Failed.\n");
1216                goto error;
1217        }
1218        if (state->type_flags & DST_TYPE_HAS_FW_1)
1219                mdelay(3);
1220        if (read_dst(state, &reply, GET_ACK)) {
1221                dprintk(3, "Trying to recover..\n");
1222                if ((dst_error_recovery(state)) < 0) {
1223                        dprintk(2, "Recovery Failed.\n");
1224                        goto error;
1225                }
1226                goto error;
1227        }
1228        if (reply != ACK) {
1229                dprintk(2, "write not acknowledged 0x%02x\n", reply);
1230                goto error;
1231        }
1232        if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
1233                goto error;
1234        if (state->type_flags & DST_TYPE_HAS_FW_1)
1235                mdelay(3);
1236        else
1237                udelay(2000);
1238        if (!dst_wait_dst_ready(state, NO_DELAY))
1239                goto error;
1240        if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
1241                dprintk(3, "Trying to recover..\n");
1242                if ((dst_error_recovery(state)) < 0) {
1243                        dprintk(2, "Recovery failed.\n");
1244                        goto error;
1245                }
1246                goto error;
1247        }
1248        if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1249                dprintk(2, "checksum failure\n");
1250                goto error;
1251        }
1252        mutex_unlock(&state->dst_mutex);
1253        return 0;
1254
1255error:
1256        mutex_unlock(&state->dst_mutex);
1257        return -EIO;
1258
1259}
1260
1261static int dst_get_signal(struct dst_state *state)
1262{
1263        int retval;
1264        u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
1265        //dprintk("%s: Getting Signal strength and other parameters\n", __func__);
1266        if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
1267                state->decode_lock = state->decode_strength = state->decode_snr = 0;
1268                return 0;
1269        }
1270        if (0 == (state->diseq_flags & HAS_LOCK)) {
1271                state->decode_lock = state->decode_strength = state->decode_snr = 0;
1272                return 0;
1273        }
1274        if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
1275                retval = dst_command(state, get_signal, 8);
1276                if (retval < 0)
1277                        return retval;
1278                if (state->dst_type == DST_TYPE_IS_SAT) {
1279                        state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
1280                        state->decode_strength = state->rxbuffer[5] << 8;
1281                        state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1282                } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
1283                        state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
1284                        state->decode_strength = state->rxbuffer[4] << 8;
1285                        state->decode_snr = state->rxbuffer[3] << 8;
1286                } else if (state->dst_type == DST_TYPE_IS_ATSC) {
1287                        state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
1288                        state->decode_strength = state->rxbuffer[4] << 8;
1289                        state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1290                }
1291                state->cur_jiff = jiffies;
1292        }
1293        return 0;
1294}
1295
1296static int dst_tone_power_cmd(struct dst_state *state)
1297{
1298        u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
1299
1300        if (state->dst_type != DST_TYPE_IS_SAT)
1301                return -EOPNOTSUPP;
1302        paket[4] = state->tx_tuna[4];
1303        paket[2] = state->tx_tuna[2];
1304        paket[3] = state->tx_tuna[3];
1305        paket[7] = dst_check_sum (paket, 7);
1306        return dst_command(state, paket, 8);
1307}
1308
1309static int dst_get_tuna(struct dst_state *state)
1310{
1311        int retval;
1312
1313        if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
1314                return 0;
1315        state->diseq_flags &= ~(HAS_LOCK);
1316        if (!dst_wait_dst_ready(state, NO_DELAY))
1317                return -EIO;
1318        if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1319                !(state->dst_type == DST_TYPE_IS_ATSC))
1320
1321                retval = read_dst(state, state->rx_tuna, 10);
1322        else
1323                retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1324        if (retval < 0) {
1325                dprintk(3, "read not successful\n");
1326                return retval;
1327        }
1328        if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1329           !(state->dst_type == DST_TYPE_IS_ATSC)) {
1330
1331                if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1332                        dprintk(2, "checksum failure ?\n");
1333                        return -EIO;
1334                }
1335        } else {
1336                if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1337                        dprintk(2, "checksum failure?\n");
1338                        return -EIO;
1339                }
1340        }
1341        if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1342                return 0;
1343        if (state->dst_type == DST_TYPE_IS_SAT) {
1344                state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1345        } else {
1346                state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1347        }
1348        state->decode_freq = state->decode_freq * 1000;
1349        state->decode_lock = 1;
1350        state->diseq_flags |= HAS_LOCK;
1351
1352        return 1;
1353}
1354
1355static int dst_set_voltage(struct dvb_frontend *fe,
1356                           enum fe_sec_voltage voltage);
1357
1358static int dst_write_tuna(struct dvb_frontend *fe)
1359{
1360        struct dst_state *state = fe->demodulator_priv;
1361        int retval;
1362        u8 reply;
1363
1364        dprintk(2, "type_flags 0x%x\n", state->type_flags);
1365        state->decode_freq = 0;
1366        state->decode_lock = state->decode_strength = state->decode_snr = 0;
1367        if (state->dst_type == DST_TYPE_IS_SAT) {
1368                if (!(state->diseq_flags & HAS_POWER))
1369                        dst_set_voltage(fe, SEC_VOLTAGE_13);
1370        }
1371        state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1372        mutex_lock(&state->dst_mutex);
1373        if ((dst_comm_init(state)) < 0) {
1374                dprintk(3, "DST Communication initialization failed.\n");
1375                goto error;
1376        }
1377//      if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1378        if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1379                (!(state->dst_type == DST_TYPE_IS_ATSC))) {
1380
1381                state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
1382                retval = write_dst(state, &state->tx_tuna[0], 10);
1383        } else {
1384                state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
1385                retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
1386        }
1387        if (retval < 0) {
1388                dst_pio_disable(state);
1389                dprintk(3, "write not successful\n");
1390                goto werr;
1391        }
1392        if ((dst_pio_disable(state)) < 0) {
1393                dprintk(3, "DST PIO disable failed !\n");
1394                goto error;
1395        }
1396        if ((read_dst(state, &reply, GET_ACK) < 0)) {
1397                dprintk(3, "read verify not successful.\n");
1398                goto error;
1399        }
1400        if (reply != ACK) {
1401                dprintk(3, "write not acknowledged 0x%02x\n", reply);
1402                goto error;
1403        }
1404        state->diseq_flags |= ATTEMPT_TUNE;
1405        retval = dst_get_tuna(state);
1406werr:
1407        mutex_unlock(&state->dst_mutex);
1408        return retval;
1409
1410error:
1411        mutex_unlock(&state->dst_mutex);
1412        return -EIO;
1413}
1414
1415/*
1416 * line22k0    0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
1417 * line22k1    0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
1418 * line22k2    0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
1419 * tone        0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
1420 * data        0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
1421 * power_off   0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
1422 * power_on    0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
1423 * Diseqc 1    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
1424 * Diseqc 2    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
1425 * Diseqc 3    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
1426 * Diseqc 4    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
1427 */
1428
1429static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
1430{
1431        struct dst_state *state = fe->demodulator_priv;
1432        u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
1433
1434        if (state->dst_type != DST_TYPE_IS_SAT)
1435                return -EOPNOTSUPP;
1436        if (cmd->msg_len > 0 && cmd->msg_len < 5)
1437                memcpy(&paket[3], cmd->msg, cmd->msg_len);
1438        else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
1439                memcpy(&paket[2], cmd->msg, cmd->msg_len);
1440        else
1441                return -EINVAL;
1442        paket[7] = dst_check_sum(&paket[0], 7);
1443        return dst_command(state, paket, 8);
1444}
1445
1446static int dst_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
1447{
1448        int need_cmd, retval = 0;
1449        struct dst_state *state = fe->demodulator_priv;
1450
1451        state->voltage = voltage;
1452        if (state->dst_type != DST_TYPE_IS_SAT)
1453                return -EOPNOTSUPP;
1454
1455        need_cmd = 0;
1456
1457        switch (voltage) {
1458        case SEC_VOLTAGE_13:
1459        case SEC_VOLTAGE_18:
1460                if ((state->diseq_flags & HAS_POWER) == 0)
1461                        need_cmd = 1;
1462                state->diseq_flags |= HAS_POWER;
1463                state->tx_tuna[4] = 0x01;
1464                break;
1465        case SEC_VOLTAGE_OFF:
1466                need_cmd = 1;
1467                state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
1468                state->tx_tuna[4] = 0x00;
1469                break;
1470        default:
1471                return -EINVAL;
1472        }
1473
1474        if (need_cmd)
1475                retval = dst_tone_power_cmd(state);
1476
1477        return retval;
1478}
1479
1480static int dst_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
1481{
1482        struct dst_state *state = fe->demodulator_priv;
1483
1484        state->tone = tone;
1485        if (state->dst_type != DST_TYPE_IS_SAT)
1486                return -EOPNOTSUPP;
1487
1488        switch (tone) {
1489        case SEC_TONE_OFF:
1490                if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1491                    state->tx_tuna[2] = 0x00;
1492                else
1493                    state->tx_tuna[2] = 0xff;
1494                break;
1495
1496        case SEC_TONE_ON:
1497                state->tx_tuna[2] = 0x02;
1498                break;
1499        default:
1500                return -EINVAL;
1501        }
1502        return dst_tone_power_cmd(state);
1503}
1504
1505static int dst_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd minicmd)
1506{
1507        struct dst_state *state = fe->demodulator_priv;
1508
1509        if (state->dst_type != DST_TYPE_IS_SAT)
1510                return -EOPNOTSUPP;
1511        state->minicmd = minicmd;
1512        switch (minicmd) {
1513        case SEC_MINI_A:
1514                state->tx_tuna[3] = 0x02;
1515                break;
1516        case SEC_MINI_B:
1517                state->tx_tuna[3] = 0xff;
1518                break;
1519        }
1520        return dst_tone_power_cmd(state);
1521}
1522
1523
1524static int bt8xx_dst_init(struct dvb_frontend *fe)
1525{
1526        struct dst_state *state = fe->demodulator_priv;
1527
1528        static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
1529        static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
1530        static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1531        static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1532        static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1533        static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1534        static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1535
1536        state->inversion = INVERSION_OFF;
1537        state->voltage = SEC_VOLTAGE_13;
1538        state->tone = SEC_TONE_OFF;
1539        state->diseq_flags = 0;
1540        state->k22 = 0x02;
1541        state->bandwidth = 7000000;
1542        state->cur_jiff = jiffies;
1543        if (state->dst_type == DST_TYPE_IS_SAT)
1544                memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
1545        else if (state->dst_type == DST_TYPE_IS_TERR)
1546                memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
1547        else if (state->dst_type == DST_TYPE_IS_CABLE)
1548                memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
1549        else if (state->dst_type == DST_TYPE_IS_ATSC)
1550                memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
1551
1552        return 0;
1553}
1554
1555static int dst_read_status(struct dvb_frontend *fe, enum fe_status *status)
1556{
1557        struct dst_state *state = fe->demodulator_priv;
1558
1559        *status = 0;
1560        if (state->diseq_flags & HAS_LOCK) {
1561//              dst_get_signal(state);  // don't require(?) to ask MCU
1562                if (state->decode_lock)
1563                        *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
1564        }
1565
1566        return 0;
1567}
1568
1569static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1570{
1571        struct dst_state *state = fe->demodulator_priv;
1572
1573        int retval = dst_get_signal(state);
1574        *strength = state->decode_strength;
1575
1576        return retval;
1577}
1578
1579static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1580{
1581        struct dst_state *state = fe->demodulator_priv;
1582
1583        int retval = dst_get_signal(state);
1584        *snr = state->decode_snr;
1585
1586        return retval;
1587}
1588
1589static int dst_set_frontend(struct dvb_frontend *fe)
1590{
1591        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1592        int retval = -EINVAL;
1593        struct dst_state *state = fe->demodulator_priv;
1594
1595        if (p != NULL) {
1596                retval = dst_set_freq(state, p->frequency);
1597                if(retval != 0)
1598                        return retval;
1599                dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1600
1601                if (state->dst_type == DST_TYPE_IS_SAT) {
1602                        if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1603                                dst_set_inversion(state, p->inversion);
1604                        dst_set_fec(state, p->fec_inner);
1605                        dst_set_symbolrate(state, p->symbol_rate);
1606                        dst_set_polarization(state);
1607                        dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1608
1609                } else if (state->dst_type == DST_TYPE_IS_TERR)
1610                        dst_set_bandwidth(state, p->bandwidth_hz);
1611                else if (state->dst_type == DST_TYPE_IS_CABLE) {
1612                        dst_set_fec(state, p->fec_inner);
1613                        dst_set_symbolrate(state, p->symbol_rate);
1614                        dst_set_modulation(state, p->modulation);
1615                }
1616                retval = dst_write_tuna(fe);
1617        }
1618
1619        return retval;
1620}
1621
1622static int dst_tune_frontend(struct dvb_frontend* fe,
1623                            bool re_tune,
1624                            unsigned int mode_flags,
1625                            unsigned int *delay,
1626                            enum fe_status *status)
1627{
1628        struct dst_state *state = fe->demodulator_priv;
1629        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1630
1631        if (re_tune) {
1632                dst_set_freq(state, p->frequency);
1633                dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1634
1635                if (state->dst_type == DST_TYPE_IS_SAT) {
1636                        if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1637                                dst_set_inversion(state, p->inversion);
1638                        dst_set_fec(state, p->fec_inner);
1639                        dst_set_symbolrate(state, p->symbol_rate);
1640                        dst_set_polarization(state);
1641                        dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1642
1643                } else if (state->dst_type == DST_TYPE_IS_TERR)
1644                        dst_set_bandwidth(state, p->bandwidth_hz);
1645                else if (state->dst_type == DST_TYPE_IS_CABLE) {
1646                        dst_set_fec(state, p->fec_inner);
1647                        dst_set_symbolrate(state, p->symbol_rate);
1648                        dst_set_modulation(state, p->modulation);
1649                }
1650                dst_write_tuna(fe);
1651        }
1652
1653        if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1654                dst_read_status(fe, status);
1655
1656        *delay = HZ/10;
1657        return 0;
1658}
1659
1660static enum dvbfe_algo dst_get_tuning_algo(struct dvb_frontend *fe)
1661{
1662        return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
1663}
1664
1665static int dst_get_frontend(struct dvb_frontend *fe,
1666                            struct dtv_frontend_properties *p)
1667{
1668        struct dst_state *state = fe->demodulator_priv;
1669
1670        p->frequency = state->decode_freq;
1671        if (state->dst_type == DST_TYPE_IS_SAT) {
1672                if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1673                        p->inversion = state->inversion;
1674                p->symbol_rate = state->symbol_rate;
1675                p->fec_inner = dst_get_fec(state);
1676        } else if (state->dst_type == DST_TYPE_IS_TERR) {
1677                p->bandwidth_hz = state->bandwidth;
1678        } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1679                p->symbol_rate = state->symbol_rate;
1680                p->fec_inner = dst_get_fec(state);
1681                p->modulation = dst_get_modulation(state);
1682        }
1683
1684        return 0;
1685}
1686
1687static void bt8xx_dst_release(struct dvb_frontend *fe)
1688{
1689        struct dst_state *state = fe->demodulator_priv;
1690        if (state->dst_ca) {
1691                dvb_unregister_device(state->dst_ca);
1692#ifdef CONFIG_MEDIA_ATTACH
1693                symbol_put(dst_ca_attach);
1694#endif
1695        }
1696        kfree(state);
1697}
1698
1699static const struct dvb_frontend_ops dst_dvbt_ops;
1700static const struct dvb_frontend_ops dst_dvbs_ops;
1701static const struct dvb_frontend_ops dst_dvbc_ops;
1702static const struct dvb_frontend_ops dst_atsc_ops;
1703
1704struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1705{
1706        /* check if the ASIC is there */
1707        if (dst_probe(state) < 0) {
1708                kfree(state);
1709                return NULL;
1710        }
1711        /* determine settings based on type */
1712        /* create dvb_frontend */
1713        switch (state->dst_type) {
1714        case DST_TYPE_IS_TERR:
1715                memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1716                break;
1717        case DST_TYPE_IS_CABLE:
1718                memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1719                break;
1720        case DST_TYPE_IS_SAT:
1721                memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1722                break;
1723        case DST_TYPE_IS_ATSC:
1724                memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
1725                break;
1726        default:
1727                pr_err("unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n");
1728                kfree(state);
1729                return NULL;
1730        }
1731        state->frontend.demodulator_priv = state;
1732
1733        return state;                           /*      Manu (DST is a card not a frontend)     */
1734}
1735
1736EXPORT_SYMBOL(dst_attach);
1737
1738static const struct dvb_frontend_ops dst_dvbt_ops = {
1739        .delsys = { SYS_DVBT },
1740        .info = {
1741                .name = "DST DVB-T",
1742                .frequency_min_hz = 137 * MHz,
1743                .frequency_max_hz = 858 * MHz,
1744                .frequency_stepsize_hz = 166667,
1745                .caps = FE_CAN_FEC_AUTO                 |
1746                        FE_CAN_QAM_AUTO                 |
1747                        FE_CAN_QAM_16                   |
1748                        FE_CAN_QAM_32                   |
1749                        FE_CAN_QAM_64                   |
1750                        FE_CAN_QAM_128                  |
1751                        FE_CAN_QAM_256                  |
1752                        FE_CAN_TRANSMISSION_MODE_AUTO   |
1753                        FE_CAN_GUARD_INTERVAL_AUTO
1754        },
1755
1756        .release = bt8xx_dst_release,
1757        .init = bt8xx_dst_init,
1758        .tune = dst_tune_frontend,
1759        .set_frontend = dst_set_frontend,
1760        .get_frontend = dst_get_frontend,
1761        .get_frontend_algo = dst_get_tuning_algo,
1762        .read_status = dst_read_status,
1763        .read_signal_strength = dst_read_signal_strength,
1764        .read_snr = dst_read_snr,
1765};
1766
1767static const struct dvb_frontend_ops dst_dvbs_ops = {
1768        .delsys = { SYS_DVBS },
1769        .info = {
1770                .name = "DST DVB-S",
1771                .frequency_min_hz   =  950 * MHz,
1772                .frequency_max_hz   = 2150 * MHz,
1773                .frequency_stepsize_hz = 1 * MHz,
1774                .frequency_tolerance_hz = 29500 * kHz,
1775                .symbol_rate_min = 1000000,
1776                .symbol_rate_max = 45000000,
1777        /*     . symbol_rate_tolerance  =       ???,*/
1778                .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1779        },
1780
1781        .release = bt8xx_dst_release,
1782        .init = bt8xx_dst_init,
1783        .tune = dst_tune_frontend,
1784        .set_frontend = dst_set_frontend,
1785        .get_frontend = dst_get_frontend,
1786        .get_frontend_algo = dst_get_tuning_algo,
1787        .read_status = dst_read_status,
1788        .read_signal_strength = dst_read_signal_strength,
1789        .read_snr = dst_read_snr,
1790        .diseqc_send_burst = dst_send_burst,
1791        .diseqc_send_master_cmd = dst_set_diseqc,
1792        .set_voltage = dst_set_voltage,
1793        .set_tone = dst_set_tone,
1794};
1795
1796static const struct dvb_frontend_ops dst_dvbc_ops = {
1797        .delsys = { SYS_DVBC_ANNEX_A },
1798        .info = {
1799                .name = "DST DVB-C",
1800                .frequency_min_hz =  51 * MHz,
1801                .frequency_max_hz = 858 * MHz,
1802                .frequency_stepsize_hz = 62500,
1803                .symbol_rate_min = 1000000,
1804                .symbol_rate_max = 45000000,
1805                .caps = FE_CAN_FEC_AUTO |
1806                        FE_CAN_QAM_AUTO |
1807                        FE_CAN_QAM_16   |
1808                        FE_CAN_QAM_32   |
1809                        FE_CAN_QAM_64   |
1810                        FE_CAN_QAM_128  |
1811                        FE_CAN_QAM_256
1812        },
1813
1814        .release = bt8xx_dst_release,
1815        .init = bt8xx_dst_init,
1816        .tune = dst_tune_frontend,
1817        .set_frontend = dst_set_frontend,
1818        .get_frontend = dst_get_frontend,
1819        .get_frontend_algo = dst_get_tuning_algo,
1820        .read_status = dst_read_status,
1821        .read_signal_strength = dst_read_signal_strength,
1822        .read_snr = dst_read_snr,
1823};
1824
1825static const struct dvb_frontend_ops dst_atsc_ops = {
1826        .delsys = { SYS_ATSC },
1827        .info = {
1828                .name = "DST ATSC",
1829                .frequency_min_hz = 510 * MHz,
1830                .frequency_max_hz = 858 * MHz,
1831                .frequency_stepsize_hz = 62500,
1832                .symbol_rate_min = 1000000,
1833                .symbol_rate_max = 45000000,
1834                .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1835        },
1836
1837        .release = bt8xx_dst_release,
1838        .init = bt8xx_dst_init,
1839        .tune = dst_tune_frontend,
1840        .set_frontend = dst_set_frontend,
1841        .get_frontend = dst_get_frontend,
1842        .get_frontend_algo = dst_get_tuning_algo,
1843        .read_status = dst_read_status,
1844        .read_signal_strength = dst_read_signal_strength,
1845        .read_snr = dst_read_snr,
1846};
1847
1848MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
1849MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1850MODULE_LICENSE("GPL");
1851