linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
<<
>>
Prefs
   1/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
   2 *
   3 *      This program is free software; you can redistribute it and/or modify it
   4 *      under the terms of the GNU General Public License as published by the Free
   5 *      Software Foundation, version 2.
   6 *
   7 *  Copyright (C) 2005-9 DiBcom, SA et al
   8 */
   9#include "dib0700.h"
  10
  11#include "dib3000mc.h"
  12#include "dib7000m.h"
  13#include "dib7000p.h"
  14#include "dib8000.h"
  15#include "mt2060.h"
  16#include "mt2266.h"
  17#include "tuner-xc2028.h"
  18#include "xc5000.h"
  19#include "s5h1411.h"
  20#include "dib0070.h"
  21#include "lgdt3305.h"
  22#include "mxl5007t.h"
  23
  24static int force_lna_activation;
  25module_param(force_lna_activation, int, 0644);
  26MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
  27                "if applicable for the device (default: 0=automatic/off).");
  28
  29struct dib0700_adapter_state {
  30        int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
  31};
  32
  33/* Hauppauge Nova-T 500 (aka Bristol)
  34 *  has a LNA on GPIO0 which is enabled by setting 1 */
  35static struct mt2060_config bristol_mt2060_config[2] = {
  36        {
  37                .i2c_address = 0x60,
  38                .clock_out   = 3,
  39        }, {
  40                .i2c_address = 0x61,
  41        }
  42};
  43
  44
  45static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
  46        .band_caps = BAND_VHF | BAND_UHF,
  47        .setup     = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
  48
  49        .agc1_max = 42598,
  50        .agc1_min = 17694,
  51        .agc2_max = 45875,
  52        .agc2_min = 0,
  53
  54        .agc1_pt1 = 0,
  55        .agc1_pt2 = 59,
  56
  57        .agc1_slope1 = 0,
  58        .agc1_slope2 = 69,
  59
  60        .agc2_pt1 = 0,
  61        .agc2_pt2 = 59,
  62
  63        .agc2_slope1 = 111,
  64        .agc2_slope2 = 28,
  65};
  66
  67static struct dib3000mc_config bristol_dib3000mc_config[2] = {
  68        {       .agc          = &bristol_dib3000p_mt2060_agc_config,
  69                .max_time     = 0x196,
  70                .ln_adc_level = 0x1cc7,
  71                .output_mpeg2_in_188_bytes = 1,
  72        },
  73        {       .agc          = &bristol_dib3000p_mt2060_agc_config,
  74                .max_time     = 0x196,
  75                .ln_adc_level = 0x1cc7,
  76                .output_mpeg2_in_188_bytes = 1,
  77        }
  78};
  79
  80static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
  81{
  82        struct dib0700_state *st = adap->dev->priv;
  83        if (adap->id == 0) {
  84                dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(10);
  85                dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
  86                dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
  87                dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
  88
  89                if (force_lna_activation)
  90                        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
  91                else
  92                        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
  93
  94                if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
  95                        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
  96                        return -ENODEV;
  97                }
  98        }
  99        st->mt2060_if1[adap->id] = 1220;
 100        return (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
 101                (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
 102}
 103
 104static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
 105{
 106        struct i2c_msg msg[2] = {
 107                { .addr = 0x50, .flags = 0,        .buf = &adrs, .len = 1 },
 108                { .addr = 0x50, .flags = I2C_M_RD, .buf = pval,  .len = 1 },
 109        };
 110        if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
 111        return 0;
 112}
 113
 114static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
 115{
 116        struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
 117        struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
 118        s8 a;
 119        int if1=1220;
 120        if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
 121                adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) {
 122                if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
 123        }
 124        return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id],
 125                if1) == NULL ? -ENODEV : 0;
 126}
 127
 128/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
 129
 130/* MT226x */
 131static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
 132        {
 133                BAND_UHF, // band_caps
 134
 135                /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
 136                * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
 137                (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
 138
 139                1130,  // inv_gain
 140                21,  // time_stabiliz
 141
 142                0,  // alpha_level
 143                118,  // thlock
 144
 145                0,     // wbd_inv
 146                3530,  // wbd_ref
 147                1,     // wbd_sel
 148                0,     // wbd_alpha
 149
 150                65535,  // agc1_max
 151                33770,  // agc1_min
 152                65535,  // agc2_max
 153                23592,  // agc2_min
 154
 155                0,    // agc1_pt1
 156                62,   // agc1_pt2
 157                255,  // agc1_pt3
 158                64,   // agc1_slope1
 159                64,   // agc1_slope2
 160                132,  // agc2_pt1
 161                192,  // agc2_pt2
 162                80,   // agc2_slope1
 163                80,   // agc2_slope2
 164
 165                17,  // alpha_mant
 166                27,  // alpha_exp
 167                23,  // beta_mant
 168                51,  // beta_exp
 169
 170                1,  // perform_agc_softsplit
 171        }, {
 172                BAND_VHF | BAND_LBAND, // band_caps
 173
 174                /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
 175                * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
 176                (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
 177
 178                2372, // inv_gain
 179                21,   // time_stabiliz
 180
 181                0,    // alpha_level
 182                118,  // thlock
 183
 184                0,    // wbd_inv
 185                3530, // wbd_ref
 186                1,     // wbd_sel
 187                0,    // wbd_alpha
 188
 189                65535, // agc1_max
 190                0,     // agc1_min
 191                65535, // agc2_max
 192                23592, // agc2_min
 193
 194                0,    // agc1_pt1
 195                128,  // agc1_pt2
 196                128,  // agc1_pt3
 197                128,  // agc1_slope1
 198                0,    // agc1_slope2
 199                128,  // agc2_pt1
 200                253,  // agc2_pt2
 201                81,   // agc2_slope1
 202                0,    // agc2_slope2
 203
 204                17,  // alpha_mant
 205                27,  // alpha_exp
 206                23,  // beta_mant
 207                51,  // beta_exp
 208
 209                1,  // perform_agc_softsplit
 210        }
 211};
 212
 213static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
 214        60000, 30000, // internal, sampling
 215        1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
 216        0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
 217        (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
 218        0, // ifreq
 219        20452225, // timf
 220};
 221
 222static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
 223        {       .output_mpeg2_in_188_bytes = 1,
 224                .hostbus_diversity = 1,
 225                .tuner_is_baseband = 1,
 226
 227                .agc_config_count = 2,
 228                .agc = stk7700d_7000p_mt2266_agc_config,
 229                .bw  = &stk7700d_mt2266_pll_config,
 230
 231                .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
 232                .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
 233                .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
 234        },
 235        {       .output_mpeg2_in_188_bytes = 1,
 236                .hostbus_diversity = 1,
 237                .tuner_is_baseband = 1,
 238
 239                .agc_config_count = 2,
 240                .agc = stk7700d_7000p_mt2266_agc_config,
 241                .bw  = &stk7700d_mt2266_pll_config,
 242
 243                .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
 244                .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
 245                .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
 246        }
 247};
 248
 249static struct mt2266_config stk7700d_mt2266_config[2] = {
 250        {       .i2c_address = 0x60
 251        },
 252        {       .i2c_address = 0x60
 253        }
 254};
 255
 256static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
 257{
 258        if (adap->id == 0) {
 259                dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
 260                msleep(10);
 261                dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
 262                dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
 263                dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
 264                dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
 265                msleep(10);
 266                dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
 267                msleep(10);
 268                if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
 269                                             stk7700d_dib7000p_mt2266_config)
 270                    != 0) {
 271                        err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
 272                        return -ENODEV;
 273                }
 274        }
 275
 276        adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
 277                                &stk7700d_dib7000p_mt2266_config[adap->id]);
 278
 279        return adap->fe == NULL ? -ENODEV : 0;
 280}
 281
 282static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
 283{
 284        if (adap->id == 0) {
 285                dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
 286                msleep(10);
 287                dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
 288                dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
 289                dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
 290                dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
 291                msleep(10);
 292                dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
 293                msleep(10);
 294                dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 295                if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
 296                                             stk7700d_dib7000p_mt2266_config)
 297                    != 0) {
 298                        err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
 299                        return -ENODEV;
 300                }
 301        }
 302
 303        adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
 304                                &stk7700d_dib7000p_mt2266_config[adap->id]);
 305
 306        return adap->fe == NULL ? -ENODEV : 0;
 307}
 308
 309static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
 310{
 311        struct i2c_adapter *tun_i2c;
 312        tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
 313        return dvb_attach(mt2266_attach, adap->fe, tun_i2c,
 314                &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
 315}
 316
 317/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
 318static struct dibx000_agc_config xc3028_agc_config = {
 319        BAND_VHF | BAND_UHF,       /* band_caps */
 320
 321        /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
 322         * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
 323         * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
 324        (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
 325        (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
 326
 327        712,    /* inv_gain */
 328        21,     /* time_stabiliz */
 329
 330        0,      /* alpha_level */
 331        118,    /* thlock */
 332
 333        0,      /* wbd_inv */
 334        2867,   /* wbd_ref */
 335        0,      /* wbd_sel */
 336        2,      /* wbd_alpha */
 337
 338        0,      /* agc1_max */
 339        0,      /* agc1_min */
 340        39718,  /* agc2_max */
 341        9930,   /* agc2_min */
 342        0,      /* agc1_pt1 */
 343        0,      /* agc1_pt2 */
 344        0,      /* agc1_pt3 */
 345        0,      /* agc1_slope1 */
 346        0,      /* agc1_slope2 */
 347        0,      /* agc2_pt1 */
 348        128,    /* agc2_pt2 */
 349        29,     /* agc2_slope1 */
 350        29,     /* agc2_slope2 */
 351
 352        17,     /* alpha_mant */
 353        27,     /* alpha_exp */
 354        23,     /* beta_mant */
 355        51,     /* beta_exp */
 356
 357        1,      /* perform_agc_softsplit */
 358};
 359
 360/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
 361static struct dibx000_bandwidth_config xc3028_bw_config = {
 362        60000, 30000, /* internal, sampling */
 363        1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
 364        0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
 365                          modulo */
 366        (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
 367        (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
 368        20452225, /* timf */
 369        30000000, /* xtal_hz */
 370};
 371
 372static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
 373        .output_mpeg2_in_188_bytes = 1,
 374        .tuner_is_baseband = 1,
 375
 376        .agc_config_count = 1,
 377        .agc = &xc3028_agc_config,
 378        .bw  = &xc3028_bw_config,
 379
 380        .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
 381        .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
 382        .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
 383};
 384
 385static int stk7700ph_xc3028_callback(void *ptr, int component,
 386                                     int command, int arg)
 387{
 388        struct dvb_usb_adapter *adap = ptr;
 389
 390        switch (command) {
 391        case XC2028_TUNER_RESET:
 392                /* Send the tuner in then out of reset */
 393                dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10);
 394                dib7000p_set_gpio(adap->fe, 8, 0, 1);
 395                break;
 396        case XC2028_RESET_CLK:
 397                break;
 398        default:
 399                err("%s: unknown command %d, arg %d\n", __func__,
 400                        command, arg);
 401                return -EINVAL;
 402        }
 403        return 0;
 404}
 405
 406static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
 407        .fname = XC2028_DEFAULT_FIRMWARE,
 408        .max_len = 64,
 409        .demod = XC3028_FE_DIBCOM52,
 410};
 411
 412static struct xc2028_config stk7700ph_xc3028_config = {
 413        .i2c_addr = 0x61,
 414        .ctrl = &stk7700ph_xc3028_ctrl,
 415};
 416
 417static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
 418{
 419        struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
 420
 421        if (desc->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
 422            desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
 423        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
 424        else
 425        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
 426        msleep(20);
 427        dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
 428        dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
 429        dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
 430        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
 431        msleep(10);
 432        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
 433        msleep(20);
 434        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 435        msleep(10);
 436
 437        if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
 438                                     &stk7700ph_dib7700_xc3028_config) != 0) {
 439                err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
 440                    __func__);
 441                return -ENODEV;
 442        }
 443
 444        adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
 445                &stk7700ph_dib7700_xc3028_config);
 446
 447        return adap->fe == NULL ? -ENODEV : 0;
 448}
 449
 450static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
 451{
 452        struct i2c_adapter *tun_i2c;
 453
 454        tun_i2c = dib7000p_get_i2c_master(adap->fe,
 455                DIBX000_I2C_INTERFACE_TUNER, 1);
 456
 457        stk7700ph_xc3028_config.i2c_adap = tun_i2c;
 458
 459        /* FIXME: generalize & move to common area */
 460        adap->fe->callback = stk7700ph_xc3028_callback;
 461
 462        return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
 463                == NULL ? -ENODEV : 0;
 464}
 465
 466#define DEFAULT_RC_INTERVAL 50
 467
 468static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
 469
 470/* Number of keypresses to ignore before start repeating */
 471#define RC_REPEAT_DELAY 6
 472#define RC_REPEAT_DELAY_V1_20 10
 473
 474
 475
 476/* Used by firmware versions < 1.20 (deprecated) */
 477static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
 478                                   int *state)
 479{
 480        u8 key[4];
 481        int i;
 482        struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
 483        struct dib0700_state *st = d->priv;
 484        *event = 0;
 485        *state = REMOTE_NO_KEY_PRESSED;
 486        i=dib0700_ctrl_rd(d,rc_request,2,key,4);
 487        if (i<=0) {
 488                err("RC Query Failed");
 489                return -1;
 490        }
 491
 492        /* losing half of KEY_0 events from Philipps rc5 remotes.. */
 493        if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
 494
 495        /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]);  */
 496
 497        dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
 498
 499        switch (dvb_usb_dib0700_ir_proto) {
 500        case 0: {
 501                /* NEC protocol sends repeat code as 0 0 0 FF */
 502                if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
 503                    (key[3] == 0xFF)) {
 504                        st->rc_counter++;
 505                        if (st->rc_counter > RC_REPEAT_DELAY) {
 506                                *event = d->last_event;
 507                                *state = REMOTE_KEY_PRESSED;
 508                                st->rc_counter = RC_REPEAT_DELAY;
 509                        }
 510                        return 0;
 511                }
 512                for (i=0;i<d->props.rc_key_map_size; i++) {
 513                        if (rc5_custom(&keymap[i]) == key[3-2] &&
 514                            rc5_data(&keymap[i]) == key[3-3]) {
 515                                st->rc_counter = 0;
 516                                *event = keymap[i].event;
 517                                *state = REMOTE_KEY_PRESSED;
 518                                d->last_event = keymap[i].event;
 519                                return 0;
 520                        }
 521                }
 522                break;
 523        }
 524        default: {
 525                /* RC-5 protocol changes toggle bit on new keypress */
 526                for (i = 0; i < d->props.rc_key_map_size; i++) {
 527                        if (rc5_custom(&keymap[i]) == key[3-2] &&
 528                            rc5_data(&keymap[i]) == key[3-3]) {
 529                                if (d->last_event == keymap[i].event &&
 530                                        key[3-1] == st->rc_toggle) {
 531                                        st->rc_counter++;
 532                                        /* prevents unwanted double hits */
 533                                        if (st->rc_counter > RC_REPEAT_DELAY) {
 534                                                *event = d->last_event;
 535                                                *state = REMOTE_KEY_PRESSED;
 536                                                st->rc_counter = RC_REPEAT_DELAY;
 537                                        }
 538
 539                                        return 0;
 540                                }
 541                                st->rc_counter = 0;
 542                                *event = keymap[i].event;
 543                                *state = REMOTE_KEY_PRESSED;
 544                                st->rc_toggle = key[3-1];
 545                                d->last_event = keymap[i].event;
 546                                return 0;
 547                        }
 548                }
 549                break;
 550        }
 551        }
 552        err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]);
 553        d->last_event = 0;
 554        return 0;
 555}
 556
 557/* This is the structure of the RC response packet starting in firmware 1.20 */
 558struct dib0700_rc_response {
 559        u8 report_id;
 560        u8 data_state;
 561        u8 system_msb;
 562        u8 system_lsb;
 563        u8 data;
 564        u8 not_data;
 565};
 566
 567/* This supports the new IR response format for firmware v1.20 */
 568static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
 569                                  int *state)
 570{
 571        struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
 572        struct dib0700_state *st = d->priv;
 573        struct dib0700_rc_response poll_reply;
 574        u8 buf[6];
 575        int i;
 576        int status;
 577        int actlen;
 578        int found = 0;
 579
 580        /* Set initial results in case we exit the function early */
 581        *event = 0;
 582        *state = REMOTE_NO_KEY_PRESSED;
 583
 584        /* Firmware v1.20 provides RC data via bulk endpoint 1 */
 585        status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
 586                              sizeof(buf), &actlen, 50);
 587        if (status < 0) {
 588                /* No data available (meaning no key press) */
 589                return 0;
 590        }
 591
 592        if (actlen != sizeof(buf)) {
 593                /* We didn't get back the 6 byte message we expected */
 594                err("Unexpected RC response size [%d]", actlen);
 595                return -1;
 596        }
 597
 598        poll_reply.report_id  = buf[0];
 599        poll_reply.data_state = buf[1];
 600        poll_reply.system_msb = buf[2];
 601        poll_reply.system_lsb = buf[3];
 602        poll_reply.data       = buf[4];
 603        poll_reply.not_data   = buf[5];
 604
 605        /*
 606        info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n",
 607             poll_reply.report_id, poll_reply.data_state,
 608             poll_reply.system_msb, poll_reply.system_lsb,
 609             poll_reply.data, poll_reply.not_data);
 610        */
 611
 612        if ((poll_reply.data + poll_reply.not_data) != 0xff) {
 613                /* Key failed integrity check */
 614                err("key failed integrity check: %02x %02x %02x %02x",
 615                    poll_reply.system_msb, poll_reply.system_lsb,
 616                    poll_reply.data, poll_reply.not_data);
 617                return -1;
 618        }
 619
 620        /* Find the key in the map */
 621        for (i = 0; i < d->props.rc_key_map_size; i++) {
 622                if (rc5_custom(&keymap[i]) == poll_reply.system_lsb &&
 623                    rc5_data(&keymap[i]) == poll_reply.data) {
 624                        *event = keymap[i].event;
 625                        found = 1;
 626                        break;
 627                }
 628        }
 629
 630        if (found == 0) {
 631                err("Unknown remote controller key: %02x %02x %02x %02x",
 632                    poll_reply.system_msb, poll_reply.system_lsb,
 633                    poll_reply.data, poll_reply.not_data);
 634                d->last_event = 0;
 635                return 0;
 636        }
 637
 638        if (poll_reply.data_state == 1) {
 639                /* New key hit */
 640                st->rc_counter = 0;
 641                *event = keymap[i].event;
 642                *state = REMOTE_KEY_PRESSED;
 643                d->last_event = keymap[i].event;
 644        } else if (poll_reply.data_state == 2) {
 645                /* Key repeated */
 646                st->rc_counter++;
 647
 648                /* prevents unwanted double hits */
 649                if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
 650                        *event = d->last_event;
 651                        *state = REMOTE_KEY_PRESSED;
 652                        st->rc_counter = RC_REPEAT_DELAY_V1_20;
 653                }
 654        } else {
 655                err("Unknown data state [%d]", poll_reply.data_state);
 656        }
 657
 658        return 0;
 659}
 660
 661static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 662{
 663        struct dib0700_state *st = d->priv;
 664
 665        /* Because some people may have improperly named firmware files,
 666           let's figure out whether to use the new firmware call or the legacy
 667           call based on the firmware version embedded in the file */
 668        if (st->rc_func_version == 0) {
 669                u32 hwver, romver, ramver, fwtype;
 670                int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
 671                                              &fwtype);
 672                if (ret < 0) {
 673                        err("Could not determine version info");
 674                        return -1;
 675                }
 676                if (ramver < 0x10200)
 677                        st->rc_func_version = 1;
 678                else
 679                        st->rc_func_version = 2;
 680        }
 681
 682        if (st->rc_func_version == 2)
 683                return dib0700_rc_query_v1_20(d, event, state);
 684        else
 685                return dib0700_rc_query_legacy(d, event, state);
 686}
 687
 688static struct dvb_usb_rc_key dib0700_rc_keys[] = {
 689        /* Key codes for the tiny Pinnacle remote*/
 690        { 0x0700, KEY_MUTE },
 691        { 0x0701, KEY_MENU }, /* Pinnacle logo */
 692        { 0x0739, KEY_POWER },
 693        { 0x0703, KEY_VOLUMEUP },
 694        { 0x0709, KEY_VOLUMEDOWN },
 695        { 0x0706, KEY_CHANNELUP },
 696        { 0x070c, KEY_CHANNELDOWN },
 697        { 0x070f, KEY_1 },
 698        { 0x0715, KEY_2 },
 699        { 0x0710, KEY_3 },
 700        { 0x0718, KEY_4 },
 701        { 0x071b, KEY_5 },
 702        { 0x071e, KEY_6 },
 703        { 0x0711, KEY_7 },
 704        { 0x0721, KEY_8 },
 705        { 0x0712, KEY_9 },
 706        { 0x0727, KEY_0 },
 707        { 0x0724, KEY_SCREEN }, /* 'Square' key */
 708        { 0x072a, KEY_TEXT },   /* 'T' key */
 709        { 0x072d, KEY_REWIND },
 710        { 0x0730, KEY_PLAY },
 711        { 0x0733, KEY_FASTFORWARD },
 712        { 0x0736, KEY_RECORD },
 713        { 0x073c, KEY_STOP },
 714        { 0x073f, KEY_CANCEL }, /* '?' key */
 715        /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
 716        { 0xeb01, KEY_POWER },
 717        { 0xeb02, KEY_1 },
 718        { 0xeb03, KEY_2 },
 719        { 0xeb04, KEY_3 },
 720        { 0xeb05, KEY_4 },
 721        { 0xeb06, KEY_5 },
 722        { 0xeb07, KEY_6 },
 723        { 0xeb08, KEY_7 },
 724        { 0xeb09, KEY_8 },
 725        { 0xeb0a, KEY_9 },
 726        { 0xeb0b, KEY_VIDEO },
 727        { 0xeb0c, KEY_0 },
 728        { 0xeb0d, KEY_REFRESH },
 729        { 0xeb0f, KEY_EPG },
 730        { 0xeb10, KEY_UP },
 731        { 0xeb11, KEY_LEFT },
 732        { 0xeb12, KEY_OK },
 733        { 0xeb13, KEY_RIGHT },
 734        { 0xeb14, KEY_DOWN },
 735        { 0xeb16, KEY_INFO },
 736        { 0xeb17, KEY_RED },
 737        { 0xeb18, KEY_GREEN },
 738        { 0xeb19, KEY_YELLOW },
 739        { 0xeb1a, KEY_BLUE },
 740        { 0xeb1b, KEY_CHANNELUP },
 741        { 0xeb1c, KEY_VOLUMEUP },
 742        { 0xeb1d, KEY_MUTE },
 743        { 0xeb1e, KEY_VOLUMEDOWN },
 744        { 0xeb1f, KEY_CHANNELDOWN },
 745        { 0xeb40, KEY_PAUSE },
 746        { 0xeb41, KEY_HOME },
 747        { 0xeb42, KEY_MENU }, /* DVD Menu */
 748        { 0xeb43, KEY_SUBTITLE },
 749        { 0xeb44, KEY_TEXT }, /* Teletext */
 750        { 0xeb45, KEY_DELETE },
 751        { 0xeb46, KEY_TV },
 752        { 0xeb47, KEY_DVD },
 753        { 0xeb48, KEY_STOP },
 754        { 0xeb49, KEY_VIDEO },
 755        { 0xeb4a, KEY_AUDIO }, /* Music */
 756        { 0xeb4b, KEY_SCREEN }, /* Pic */
 757        { 0xeb4c, KEY_PLAY },
 758        { 0xeb4d, KEY_BACK },
 759        { 0xeb4e, KEY_REWIND },
 760        { 0xeb4f, KEY_FASTFORWARD },
 761        { 0xeb54, KEY_PREVIOUS },
 762        { 0xeb58, KEY_RECORD },
 763        { 0xeb5c, KEY_NEXT },
 764
 765        /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
 766        { 0x1e00, KEY_0 },
 767        { 0x1e01, KEY_1 },
 768        { 0x1e02, KEY_2 },
 769        { 0x1e03, KEY_3 },
 770        { 0x1e04, KEY_4 },
 771        { 0x1e05, KEY_5 },
 772        { 0x1e06, KEY_6 },
 773        { 0x1e07, KEY_7 },
 774        { 0x1e08, KEY_8 },
 775        { 0x1e09, KEY_9 },
 776        { 0x1e0a, KEY_KPASTERISK },
 777        { 0x1e0b, KEY_RED },
 778        { 0x1e0c, KEY_RADIO },
 779        { 0x1e0d, KEY_MENU },
 780        { 0x1e0e, KEY_GRAVE }, /* # */
 781        { 0x1e0f, KEY_MUTE },
 782        { 0x1e10, KEY_VOLUMEUP },
 783        { 0x1e11, KEY_VOLUMEDOWN },
 784        { 0x1e12, KEY_CHANNEL },
 785        { 0x1e14, KEY_UP },
 786        { 0x1e15, KEY_DOWN },
 787        { 0x1e16, KEY_LEFT },
 788        { 0x1e17, KEY_RIGHT },
 789        { 0x1e18, KEY_VIDEO },
 790        { 0x1e19, KEY_AUDIO },
 791        { 0x1e1a, KEY_MEDIA },
 792        { 0x1e1b, KEY_EPG },
 793        { 0x1e1c, KEY_TV },
 794        { 0x1e1e, KEY_NEXT },
 795        { 0x1e1f, KEY_BACK },
 796        { 0x1e20, KEY_CHANNELUP },
 797        { 0x1e21, KEY_CHANNELDOWN },
 798        { 0x1e24, KEY_LAST }, /* Skip backwards */
 799        { 0x1e25, KEY_OK },
 800        { 0x1e29, KEY_BLUE},
 801        { 0x1e2e, KEY_GREEN },
 802        { 0x1e30, KEY_PAUSE },
 803        { 0x1e32, KEY_REWIND },
 804        { 0x1e34, KEY_FASTFORWARD },
 805        { 0x1e35, KEY_PLAY },
 806        { 0x1e36, KEY_STOP },
 807        { 0x1e37, KEY_RECORD },
 808        { 0x1e38, KEY_YELLOW },
 809        { 0x1e3b, KEY_GOTO },
 810        { 0x1e3d, KEY_POWER },
 811
 812        /* Key codes for the Leadtek Winfast DTV Dongle */
 813        { 0x0042, KEY_POWER },
 814        { 0x077c, KEY_TUNER },
 815        { 0x0f4e, KEY_PRINT }, /* PREVIEW */
 816        { 0x0840, KEY_SCREEN }, /* full screen toggle*/
 817        { 0x0f71, KEY_DOT }, /* frequency */
 818        { 0x0743, KEY_0 },
 819        { 0x0c41, KEY_1 },
 820        { 0x0443, KEY_2 },
 821        { 0x0b7f, KEY_3 },
 822        { 0x0e41, KEY_4 },
 823        { 0x0643, KEY_5 },
 824        { 0x097f, KEY_6 },
 825        { 0x0d7e, KEY_7 },
 826        { 0x057c, KEY_8 },
 827        { 0x0a40, KEY_9 },
 828        { 0x0e4e, KEY_CLEAR },
 829        { 0x047c, KEY_CHANNEL }, /* show channel number */
 830        { 0x0f41, KEY_LAST }, /* recall */
 831        { 0x0342, KEY_MUTE },
 832        { 0x064c, KEY_RESERVED }, /* PIP button*/
 833        { 0x0172, KEY_SHUFFLE }, /* SNAPSHOT */
 834        { 0x0c4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
 835        { 0x0b70, KEY_RECORD },
 836        { 0x037d, KEY_VOLUMEUP },
 837        { 0x017d, KEY_VOLUMEDOWN },
 838        { 0x0242, KEY_CHANNELUP },
 839        { 0x007d, KEY_CHANNELDOWN },
 840
 841        /* Key codes for Nova-TD "credit card" remote control. */
 842        { 0x1d00, KEY_0 },
 843        { 0x1d01, KEY_1 },
 844        { 0x1d02, KEY_2 },
 845        { 0x1d03, KEY_3 },
 846        { 0x1d04, KEY_4 },
 847        { 0x1d05, KEY_5 },
 848        { 0x1d06, KEY_6 },
 849        { 0x1d07, KEY_7 },
 850        { 0x1d08, KEY_8 },
 851        { 0x1d09, KEY_9 },
 852        { 0x1d0a, KEY_TEXT },
 853        { 0x1d0d, KEY_MENU },
 854        { 0x1d0f, KEY_MUTE },
 855        { 0x1d10, KEY_VOLUMEUP },
 856        { 0x1d11, KEY_VOLUMEDOWN },
 857        { 0x1d12, KEY_CHANNEL },
 858        { 0x1d14, KEY_UP },
 859        { 0x1d15, KEY_DOWN },
 860        { 0x1d16, KEY_LEFT },
 861        { 0x1d17, KEY_RIGHT },
 862        { 0x1d1c, KEY_TV },
 863        { 0x1d1e, KEY_NEXT },
 864        { 0x1d1f, KEY_BACK },
 865        { 0x1d20, KEY_CHANNELUP },
 866        { 0x1d21, KEY_CHANNELDOWN },
 867        { 0x1d24, KEY_LAST },
 868        { 0x1d25, KEY_OK },
 869        { 0x1d30, KEY_PAUSE },
 870        { 0x1d32, KEY_REWIND },
 871        { 0x1d34, KEY_FASTFORWARD },
 872        { 0x1d35, KEY_PLAY },
 873        { 0x1d36, KEY_STOP },
 874        { 0x1d37, KEY_RECORD },
 875        { 0x1d3b, KEY_GOTO },
 876        { 0x1d3d, KEY_POWER },
 877};
 878
 879/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
 880static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
 881        BAND_UHF | BAND_VHF,       // band_caps
 882
 883        /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
 884         * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
 885        (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
 886
 887        712,  // inv_gain
 888        41,  // time_stabiliz
 889
 890        0,  // alpha_level
 891        118,  // thlock
 892
 893        0,     // wbd_inv
 894        4095,  // wbd_ref
 895        0,     // wbd_sel
 896        0,     // wbd_alpha
 897
 898        42598,  // agc1_max
 899        17694,  // agc1_min
 900        45875,  // agc2_max
 901        2621,  // agc2_min
 902        0,  // agc1_pt1
 903        76,  // agc1_pt2
 904        139,  // agc1_pt3
 905        52,  // agc1_slope1
 906        59,  // agc1_slope2
 907        107,  // agc2_pt1
 908        172,  // agc2_pt2
 909        57,  // agc2_slope1
 910        70,  // agc2_slope2
 911
 912        21,  // alpha_mant
 913        25,  // alpha_exp
 914        28,  // beta_mant
 915        48,  // beta_exp
 916
 917        1,  // perform_agc_softsplit
 918        {  0,     // split_min
 919           107,   // split_max
 920           51800, // global_split_min
 921           24700  // global_split_max
 922        },
 923};
 924
 925static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
 926        BAND_UHF | BAND_VHF,
 927
 928        /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
 929         * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
 930        (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
 931
 932        712, // inv_gain
 933        41,  // time_stabiliz
 934
 935        0,   // alpha_level
 936        118, // thlock
 937
 938        0,    // wbd_inv
 939        4095, // wbd_ref
 940        0,    // wbd_sel
 941        0,    // wbd_alpha
 942
 943        42598, // agc1_max
 944        16384, // agc1_min
 945        42598, // agc2_max
 946            0, // agc2_min
 947
 948          0,   // agc1_pt1
 949        137,   // agc1_pt2
 950        255,   // agc1_pt3
 951
 952          0,   // agc1_slope1
 953        255,   // agc1_slope2
 954
 955        0,     // agc2_pt1
 956        0,     // agc2_pt2
 957
 958         0,    // agc2_slope1
 959        41,    // agc2_slope2
 960
 961        15, // alpha_mant
 962        25, // alpha_exp
 963
 964        28, // beta_mant
 965        48, // beta_exp
 966
 967        0, // perform_agc_softsplit
 968};
 969
 970static struct dibx000_bandwidth_config stk7700p_pll_config = {
 971        60000, 30000, // internal, sampling
 972        1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
 973        0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
 974        (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
 975        60258167, // ifreq
 976        20452225, // timf
 977        30000000, // xtal
 978};
 979
 980static struct dib7000m_config stk7700p_dib7000m_config = {
 981        .dvbt_mode = 1,
 982        .output_mpeg2_in_188_bytes = 1,
 983        .quartz_direct = 1,
 984
 985        .agc_config_count = 1,
 986        .agc = &stk7700p_7000m_mt2060_agc_config,
 987        .bw  = &stk7700p_pll_config,
 988
 989        .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
 990        .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
 991        .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
 992};
 993
 994static struct dib7000p_config stk7700p_dib7000p_config = {
 995        .output_mpeg2_in_188_bytes = 1,
 996
 997        .agc_config_count = 1,
 998        .agc = &stk7700p_7000p_mt2060_agc_config,
 999        .bw  = &stk7700p_pll_config,
1000
1001        .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
1002        .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
1003        .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
1004};
1005
1006static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
1007{
1008        struct dib0700_state *st = adap->dev->priv;
1009        /* unless there is no real power management in DVB - we leave the device on GPIO6 */
1010
1011        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1012        dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(50);
1013
1014        dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
1015        dib0700_set_gpio(adap->dev, GPIO9,  GPIO_OUT, 1);
1016
1017        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
1018        dib0700_ctrl_clock(adap->dev, 72, 1);
1019        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
1020
1021        dib0700_set_gpio(adap->dev,  GPIO0, GPIO_OUT, 1);
1022
1023        st->mt2060_if1[0] = 1220;
1024
1025        if (dib7000pc_detection(&adap->dev->i2c_adap)) {
1026                adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
1027                st->is_dib7000pc = 1;
1028        } else
1029                adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
1030
1031        return adap->fe == NULL ? -ENODEV : 0;
1032}
1033
1034static struct mt2060_config stk7700p_mt2060_config = {
1035        0x60
1036};
1037
1038static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
1039{
1040        struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
1041        struct dib0700_state *st = adap->dev->priv;
1042        struct i2c_adapter *tun_i2c;
1043        s8 a;
1044        int if1=1220;
1045        if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
1046                adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
1047                if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
1048        }
1049        if (st->is_dib7000pc)
1050                tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1051        else
1052                tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1053
1054        return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config,
1055                if1) == NULL ? -ENODEV : 0;
1056}
1057
1058/* DIB7070 generic */
1059static struct dibx000_agc_config dib7070_agc_config = {
1060        BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1061        /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
1062         * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1063        (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
1064
1065        600, // inv_gain
1066        10,  // time_stabiliz
1067
1068        0,  // alpha_level
1069        118,  // thlock
1070
1071        0,     // wbd_inv
1072        3530,  // wbd_ref
1073        1,     // wbd_sel
1074        5,     // wbd_alpha
1075
1076        65535,  // agc1_max
1077                0,  // agc1_min
1078
1079        65535,  // agc2_max
1080        0,      // agc2_min
1081
1082        0,      // agc1_pt1
1083        40,     // agc1_pt2
1084        183,    // agc1_pt3
1085        206,    // agc1_slope1
1086        255,    // agc1_slope2
1087        72,     // agc2_pt1
1088        152,    // agc2_pt2
1089        88,     // agc2_slope1
1090        90,     // agc2_slope2
1091
1092        17,  // alpha_mant
1093        27,  // alpha_exp
1094        23,  // beta_mant
1095        51,  // beta_exp
1096
1097        0,  // perform_agc_softsplit
1098};
1099
1100static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1101{
1102        deb_info("reset: %d", onoff);
1103        return dib7000p_set_gpio(fe, 8, 0, !onoff);
1104}
1105
1106static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1107{
1108        deb_info("sleep: %d", onoff);
1109        return dib7000p_set_gpio(fe, 9, 0, onoff);
1110}
1111
1112static struct dib0070_config dib7070p_dib0070_config[2] = {
1113        {
1114                .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1115                .reset = dib7070_tuner_reset,
1116                .sleep = dib7070_tuner_sleep,
1117                .clock_khz = 12000,
1118                .clock_pad_drive = 4,
1119                .charge_pump = 2,
1120        }, {
1121                .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1122                .reset = dib7070_tuner_reset,
1123                .sleep = dib7070_tuner_sleep,
1124                .clock_khz = 12000,
1125                .charge_pump = 2,
1126        }
1127};
1128
1129static struct dib0070_config dib7770p_dib0070_config = {
1130         .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1131         .reset = dib7070_tuner_reset,
1132         .sleep = dib7070_tuner_sleep,
1133         .clock_khz = 12000,
1134         .clock_pad_drive = 0,
1135         .flip_chip = 1,
1136};
1137
1138static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1139{
1140        struct dvb_usb_adapter *adap = fe->dvb->priv;
1141        struct dib0700_adapter_state *state = adap->priv;
1142
1143        u16 offset;
1144        u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1145        switch (band) {
1146                case BAND_VHF: offset = 950; break;
1147                case BAND_UHF:
1148                default: offset = 550; break;
1149        }
1150        deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
1151        dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1152        return state->set_param_save(fe, fep);
1153}
1154
1155static int dib7770_set_param_override(struct dvb_frontend *fe,
1156                struct dvb_frontend_parameters *fep)
1157{
1158         struct dvb_usb_adapter *adap = fe->dvb->priv;
1159         struct dib0700_adapter_state *state = adap->priv;
1160
1161         u16 offset;
1162         u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1163         switch (band) {
1164         case BAND_VHF:
1165                  dib7000p_set_gpio(fe, 0, 0, 1);
1166                  offset = 850;
1167                  break;
1168         case BAND_UHF:
1169         default:
1170                  dib7000p_set_gpio(fe, 0, 0, 0);
1171                  offset = 250;
1172                  break;
1173         }
1174         deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
1175         dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1176         return state->set_param_save(fe, fep);
1177}
1178
1179static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
1180{
1181         struct dib0700_adapter_state *st = adap->priv;
1182         struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe,
1183                         DIBX000_I2C_INTERFACE_TUNER, 1);
1184
1185         if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1186                                 &dib7770p_dib0070_config) == NULL)
1187                 return -ENODEV;
1188
1189         st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1190         adap->fe->ops.tuner_ops.set_params = dib7770_set_param_override;
1191         return 0;
1192}
1193
1194static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
1195{
1196        struct dib0700_adapter_state *st = adap->priv;
1197        struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1198
1199        if (adap->id == 0) {
1200                if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
1201                        return -ENODEV;
1202        } else {
1203                if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
1204                        return -ENODEV;
1205        }
1206
1207        st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1208        adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1209        return 0;
1210}
1211
1212static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1213        60000, 15000, // internal, sampling
1214        1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
1215        0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
1216        (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
1217        (0 << 25) | 0, // ifreq = 0.000000 MHz
1218        20452225, // timf
1219        12000000, // xtal_hz
1220};
1221
1222static struct dib7000p_config dib7070p_dib7000p_config = {
1223        .output_mpeg2_in_188_bytes = 1,
1224
1225        .agc_config_count = 1,
1226        .agc = &dib7070_agc_config,
1227        .bw  = &dib7070_bw_config_12_mhz,
1228        .tuner_is_baseband = 1,
1229        .spur_protect = 1,
1230
1231        .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1232        .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1233        .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1234
1235        .hostbus_diversity = 1,
1236};
1237
1238/* STK7070P */
1239static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
1240{
1241        struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
1242        if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
1243            p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
1244                dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1245        else
1246                dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1247        msleep(10);
1248        dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1249        dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1250        dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1251        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1252
1253        dib0700_ctrl_clock(adap->dev, 72, 1);
1254
1255        msleep(10);
1256        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1257        msleep(10);
1258        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1259
1260        if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1261                                     &dib7070p_dib7000p_config) != 0) {
1262                err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
1263                    __func__);
1264                return -ENODEV;
1265        }
1266
1267        adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1268                &dib7070p_dib7000p_config);
1269        return adap->fe == NULL ? -ENODEV : 0;
1270}
1271
1272/* DIB807x generic */
1273static struct dibx000_agc_config dib807x_agc_config[2] = {
1274        {
1275                BAND_VHF,
1276                /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1277                 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1278                 * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
1279                 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1280                 * P_agc_write=0 */
1281                (0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
1282                        (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1283                        (0 << 0), /* setup*/
1284
1285                600, /* inv_gain*/
1286                10,  /* time_stabiliz*/
1287
1288                0,  /* alpha_level*/
1289                118,  /* thlock*/
1290
1291                0,     /* wbd_inv*/
1292                3530,  /* wbd_ref*/
1293                1,     /* wbd_sel*/
1294                5,     /* wbd_alpha*/
1295
1296                65535,  /* agc1_max*/
1297                0,  /* agc1_min*/
1298
1299                65535,  /* agc2_max*/
1300                0,      /* agc2_min*/
1301
1302                0,      /* agc1_pt1*/
1303                40,     /* agc1_pt2*/
1304                183,    /* agc1_pt3*/
1305                206,    /* agc1_slope1*/
1306                255,    /* agc1_slope2*/
1307                72,     /* agc2_pt1*/
1308                152,    /* agc2_pt2*/
1309                88,     /* agc2_slope1*/
1310                90,     /* agc2_slope2*/
1311
1312                17,  /* alpha_mant*/
1313                27,  /* alpha_exp*/
1314                23,  /* beta_mant*/
1315                51,  /* beta_exp*/
1316
1317                0,  /* perform_agc_softsplit*/
1318        }, {
1319                BAND_UHF,
1320                /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1321                 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1322                 * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1323                 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1324                 * P_agc_write=0 */
1325                (0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
1326                        (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1327                        (0 << 0), /* setup */
1328
1329                600, /* inv_gain*/
1330                10,  /* time_stabiliz*/
1331
1332                0,  /* alpha_level*/
1333                118,  /* thlock*/
1334
1335                0,     /* wbd_inv*/
1336                3530,  /* wbd_ref*/
1337                1,     /* wbd_sel*/
1338                5,     /* wbd_alpha*/
1339
1340                65535,  /* agc1_max*/
1341                0,  /* agc1_min*/
1342
1343                65535,  /* agc2_max*/
1344                0,      /* agc2_min*/
1345
1346                0,      /* agc1_pt1*/
1347                40,     /* agc1_pt2*/
1348                183,    /* agc1_pt3*/
1349                206,    /* agc1_slope1*/
1350                255,    /* agc1_slope2*/
1351                72,     /* agc2_pt1*/
1352                152,    /* agc2_pt2*/
1353                88,     /* agc2_slope1*/
1354                90,     /* agc2_slope2*/
1355
1356                17,  /* alpha_mant*/
1357                27,  /* alpha_exp*/
1358                23,  /* beta_mant*/
1359                51,  /* beta_exp*/
1360
1361                0,  /* perform_agc_softsplit*/
1362        }
1363};
1364
1365static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
1366        60000, 15000, /* internal, sampling*/
1367        1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
1368        0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
1369                          ADClkSrc, modulo */
1370        (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
1371        (0 << 25) | 0, /* ifreq = 0.000000 MHz*/
1372        18179755, /* timf*/
1373        12000000, /* xtal_hz*/
1374};
1375
1376static struct dib8000_config dib807x_dib8000_config[2] = {
1377        {
1378                .output_mpeg2_in_188_bytes = 1,
1379
1380                .agc_config_count = 2,
1381                .agc = dib807x_agc_config,
1382                .pll = &dib807x_bw_config_12_mhz,
1383                .tuner_is_baseband = 1,
1384
1385                .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1386                .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1387                .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1388
1389                .hostbus_diversity = 1,
1390                .div_cfg = 1,
1391                .agc_control = &dib0070_ctrl_agc_filter,
1392                .output_mode = OUTMODE_MPEG2_FIFO,
1393                .drives = 0x2d98,
1394        }, {
1395                .output_mpeg2_in_188_bytes = 1,
1396
1397                .agc_config_count = 2,
1398                .agc = dib807x_agc_config,
1399                .pll = &dib807x_bw_config_12_mhz,
1400                .tuner_is_baseband = 1,
1401
1402                .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1403                .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1404                .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1405
1406                .hostbus_diversity = 1,
1407                .agc_control = &dib0070_ctrl_agc_filter,
1408                .output_mode = OUTMODE_MPEG2_FIFO,
1409                .drives = 0x2d98,
1410        }
1411};
1412
1413static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
1414{
1415        return dib8000_set_gpio(fe, 5, 0, !onoff);
1416}
1417
1418static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
1419{
1420        return dib8000_set_gpio(fe, 0, 0, onoff);
1421}
1422
1423static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
1424    { 240,      7},
1425    { 0xffff,   6},
1426};
1427
1428static struct dib0070_config dib807x_dib0070_config[2] = {
1429        {
1430                .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1431                .reset = dib807x_tuner_reset,
1432                .sleep = dib807x_tuner_sleep,
1433                .clock_khz = 12000,
1434                .clock_pad_drive = 4,
1435                .vga_filter = 1,
1436                .force_crystal_mode = 1,
1437                .enable_third_order_filter = 1,
1438                .charge_pump = 0,
1439                .wbd_gain = dib8070_wbd_gain_cfg,
1440                .osc_buffer_state = 0,
1441                .freq_offset_khz_uhf = -100,
1442                .freq_offset_khz_vhf = -100,
1443        }, {
1444                .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1445                .reset = dib807x_tuner_reset,
1446                .sleep = dib807x_tuner_sleep,
1447                .clock_khz = 12000,
1448                .clock_pad_drive = 2,
1449                .vga_filter = 1,
1450                .force_crystal_mode = 1,
1451                .enable_third_order_filter = 1,
1452                .charge_pump = 0,
1453                .wbd_gain = dib8070_wbd_gain_cfg,
1454                .osc_buffer_state = 0,
1455                .freq_offset_khz_uhf = -25,
1456                .freq_offset_khz_vhf = -25,
1457        }
1458};
1459
1460static int dib807x_set_param_override(struct dvb_frontend *fe,
1461                struct dvb_frontend_parameters *fep)
1462{
1463        struct dvb_usb_adapter *adap = fe->dvb->priv;
1464        struct dib0700_adapter_state *state = adap->priv;
1465
1466        u16 offset = dib0070_wbd_offset(fe);
1467        u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1468        switch (band) {
1469        case BAND_VHF:
1470                offset += 750;
1471                break;
1472        case BAND_UHF:  /* fall-thru wanted */
1473        default:
1474                offset += 250; break;
1475        }
1476        deb_info("WBD for DiB8000: %d\n", offset);
1477        dib8000_set_wbd_ref(fe, offset);
1478
1479        return state->set_param_save(fe, fep);
1480}
1481
1482static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
1483{
1484        struct dib0700_adapter_state *st = adap->priv;
1485        struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe,
1486                        DIBX000_I2C_INTERFACE_TUNER, 1);
1487
1488        if (adap->id == 0) {
1489                if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1490                                &dib807x_dib0070_config[0]) == NULL)
1491                        return -ENODEV;
1492        } else {
1493                if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1494                                &dib807x_dib0070_config[1]) == NULL)
1495                        return -ENODEV;
1496        }
1497
1498        st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1499        adap->fe->ops.tuner_ops.set_params = dib807x_set_param_override;
1500        return 0;
1501}
1502
1503
1504/* STK807x */
1505static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
1506{
1507        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1508        msleep(10);
1509        dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1510        dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1511        dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1512
1513        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1514
1515        dib0700_ctrl_clock(adap->dev, 72, 1);
1516
1517        msleep(10);
1518        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1519        msleep(10);
1520        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1521
1522        dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1523                                0x80);
1524
1525        adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1526                              &dib807x_dib8000_config[0]);
1527
1528        return adap->fe == NULL ?  -ENODEV : 0;
1529}
1530
1531/* STK807xPVR */
1532static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
1533{
1534        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1535        msleep(30);
1536        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1537        msleep(500);
1538        dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1539        dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1540        dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1541
1542        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1543
1544        dib0700_ctrl_clock(adap->dev, 72, 1);
1545
1546        msleep(10);
1547        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1548        msleep(10);
1549        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1550
1551        /* initialize IC 0 */
1552        dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
1553
1554        adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1555                              &dib807x_dib8000_config[0]);
1556
1557        return adap->fe == NULL ? -ENODEV : 0;
1558}
1559
1560static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
1561{
1562        /* initialize IC 1 */
1563        dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
1564
1565        adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
1566                              &dib807x_dib8000_config[1]);
1567
1568        return adap->fe == NULL ? -ENODEV : 0;
1569}
1570
1571
1572/* STK7070PD */
1573static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
1574        {
1575                .output_mpeg2_in_188_bytes = 1,
1576
1577                .agc_config_count = 1,
1578                .agc = &dib7070_agc_config,
1579                .bw  = &dib7070_bw_config_12_mhz,
1580                .tuner_is_baseband = 1,
1581                .spur_protect = 1,
1582
1583                .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1584                .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1585                .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1586
1587                .hostbus_diversity = 1,
1588        }, {
1589                .output_mpeg2_in_188_bytes = 1,
1590
1591                .agc_config_count = 1,
1592                .agc = &dib7070_agc_config,
1593                .bw  = &dib7070_bw_config_12_mhz,
1594                .tuner_is_baseband = 1,
1595                .spur_protect = 1,
1596
1597                .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1598                .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1599                .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1600
1601                .hostbus_diversity = 1,
1602        }
1603};
1604
1605static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
1606{
1607        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1608        msleep(10);
1609        dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1610        dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1611        dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1612        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1613
1614        dib0700_ctrl_clock(adap->dev, 72, 1);
1615
1616        msleep(10);
1617        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1618        msleep(10);
1619        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1620
1621        if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
1622                                     stk7070pd_dib7000p_config) != 0) {
1623                err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
1624                    __func__);
1625                return -ENODEV;
1626        }
1627
1628        adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
1629        return adap->fe == NULL ? -ENODEV : 0;
1630}
1631
1632static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
1633{
1634        adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
1635        return adap->fe == NULL ? -ENODEV : 0;
1636}
1637
1638/* S5H1411 */
1639static struct s5h1411_config pinnacle_801e_config = {
1640        .output_mode   = S5H1411_PARALLEL_OUTPUT,
1641        .gpio          = S5H1411_GPIO_OFF,
1642        .mpeg_timing   = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
1643        .qam_if        = S5H1411_IF_44000,
1644        .vsb_if        = S5H1411_IF_44000,
1645        .inversion     = S5H1411_INVERSION_OFF,
1646        .status_mode   = S5H1411_DEMODLOCKING
1647};
1648
1649/* Pinnacle PCTV HD Pro 801e GPIOs map:
1650   GPIO0  - currently unknown
1651   GPIO1  - xc5000 tuner reset
1652   GPIO2  - CX25843 sleep
1653   GPIO3  - currently unknown
1654   GPIO4  - currently unknown
1655   GPIO6  - currently unknown
1656   GPIO7  - currently unknown
1657   GPIO9  - currently unknown
1658   GPIO10 - CX25843 reset
1659 */
1660static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
1661{
1662        struct dib0700_state *st = adap->dev->priv;
1663
1664        /* Make use of the new i2c functions from FW 1.20 */
1665        st->fw_use_new_i2c_api = 1;
1666
1667        /* The s5h1411 requires the dib0700 to not be in master mode */
1668        st->disable_streaming_master_mode = 1;
1669
1670        /* All msleep values taken from Windows USB trace */
1671        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
1672        dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
1673        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1674        msleep(400);
1675        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1676        msleep(60);
1677        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1678        msleep(30);
1679        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1680        dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1681        dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1682        dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1683        dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
1684        msleep(30);
1685
1686        /* Put the CX25843 to sleep for now since we're in digital mode */
1687        dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
1688
1689        /* GPIOs are initialized, do the attach */
1690        adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
1691                              &adap->dev->i2c_adap);
1692        return adap->fe == NULL ? -ENODEV : 0;
1693}
1694
1695static int dib0700_xc5000_tuner_callback(void *priv, int component,
1696                                         int command, int arg)
1697{
1698        struct dvb_usb_adapter *adap = priv;
1699
1700        if (command == XC5000_TUNER_RESET) {
1701                /* Reset the tuner */
1702                dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
1703                msleep(10);
1704                dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
1705                msleep(10);
1706        } else {
1707                err("xc5000: unknown tuner callback command: %d\n", command);
1708                return -EINVAL;
1709        }
1710
1711        return 0;
1712}
1713
1714static struct xc5000_config s5h1411_xc5000_tunerconfig = {
1715        .i2c_address      = 0x64,
1716        .if_khz           = 5380,
1717};
1718
1719static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
1720{
1721        /* FIXME: generalize & move to common area */
1722        adap->fe->callback = dib0700_xc5000_tuner_callback;
1723
1724        return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
1725                          &s5h1411_xc5000_tunerconfig)
1726                == NULL ? -ENODEV : 0;
1727}
1728
1729static struct lgdt3305_config hcw_lgdt3305_config = {
1730        .i2c_addr           = 0x0e,
1731        .mpeg_mode          = LGDT3305_MPEG_PARALLEL,
1732        .tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
1733        .tpvalid_polarity   = LGDT3305_TP_VALID_LOW,
1734        .deny_i2c_rptr      = 0,
1735        .spectral_inversion = 1,
1736        .qam_if_khz         = 6000,
1737        .vsb_if_khz         = 6000,
1738        .usref_8vsb         = 0x0500,
1739};
1740
1741static struct mxl5007t_config hcw_mxl5007t_config = {
1742        .xtal_freq_hz = MxL_XTAL_25_MHZ,
1743        .if_freq_hz = MxL_IF_6_MHZ,
1744        .invert_if = 1,
1745};
1746
1747/* TIGER-ATSC map:
1748   GPIO0  - LNA_CTR  (H: LNA power enabled, L: LNA power disabled)
1749   GPIO1  - ANT_SEL  (H: VPA, L: MCX)
1750   GPIO4  - SCL2
1751   GPIO6  - EN_TUNER
1752   GPIO7  - SDA2
1753   GPIO10 - DEM_RST
1754
1755   MXL is behind LG's i2c repeater.  LG is on SCL2/SDA2 gpios on the DIB
1756 */
1757static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
1758{
1759        struct dib0700_state *st = adap->dev->priv;
1760
1761        /* Make use of the new i2c functions from FW 1.20 */
1762        st->fw_use_new_i2c_api = 1;
1763
1764        st->disable_streaming_master_mode = 1;
1765
1766        /* fe power enable */
1767        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1768        msleep(30);
1769        dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1770        msleep(30);
1771
1772        /* demod reset */
1773        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1774        msleep(30);
1775        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1776        msleep(30);
1777        dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1778        msleep(30);
1779
1780        adap->fe = dvb_attach(lgdt3305_attach,
1781                              &hcw_lgdt3305_config,
1782                              &adap->dev->i2c_adap);
1783
1784        return adap->fe == NULL ? -ENODEV : 0;
1785}
1786
1787static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
1788{
1789        return dvb_attach(mxl5007t_attach, adap->fe,
1790                          &adap->dev->i2c_adap, 0x60,
1791                          &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
1792}
1793
1794
1795/* DVB-USB and USB stuff follows */
1796struct usb_device_id dib0700_usb_id_table[] = {
1797/* 0 */ { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
1798        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
1799        { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
1800        { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
1801        { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
1802/* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
1803        { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
1804        { USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
1805        { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
1806        { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
1807/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
1808        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
1809        { USB_DEVICE(USB_VID_TERRATEC,
1810                        USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
1811        { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
1812        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
1813/* 15 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070P) },
1814        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
1815        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
1816        { USB_DEVICE(USB_VID_PINNACLE,
1817                        USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
1818        { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
1819/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
1820        { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U7000) },
1821        { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
1822        { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000) },
1823        { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3100) },
1824/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
1825        { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
1826        { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
1827        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_EXPRESSCARD_320CX) },
1828        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV72E) },
1829/* 30 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73E) },
1830        { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_EC372S) },
1831        { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
1832        { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_XXS) },
1833        { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
1834/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
1835        { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
1836        { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U8000) },
1837        { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700PH) },
1838        { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000H) },
1839/* 40 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E) },
1840        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E_SE) },
1841        { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
1842        { USB_DEVICE(USB_VID_TERRATEC,
1843                        USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
1844        { USB_DEVICE(USB_VID_SONY,      USB_PID_SONY_PLAYTV) },
1845/* 45 */{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_PD378S) },
1846        { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
1847        { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
1848        { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_MC770) },
1849        { USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DTT) },
1850/* 50 */{ USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DTT_Dlx) },
1851        { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_H) },
1852        { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_T3) },
1853        { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_T5) },
1854        { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700D) },
1855/* 55 */{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700D_2) },
1856        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73A) },
1857        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73ESE) },
1858        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV282E) },
1859        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7770P) },
1860/* 60 */{ USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_XXS_2) },
1861        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XPVR) },
1862        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XP) },
1863        { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
1864        { 0 }           /* Terminating entry */
1865};
1866MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
1867
1868#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
1869        .caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
1870        .usb_ctrl          = DEVICE_SPECIFIC, \
1871        .firmware          = "dvb-usb-dib0700-1.20.fw", \
1872        .download_firmware = dib0700_download_firmware, \
1873        .no_reconnect      = 1, \
1874        .size_of_priv      = sizeof(struct dib0700_state), \
1875        .i2c_algo          = &dib0700_i2c_algo, \
1876        .identify_state    = dib0700_identify_state
1877
1878#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
1879        .streaming_ctrl   = dib0700_streaming_ctrl, \
1880        .stream = { \
1881                .type = USB_BULK, \
1882                .count = 4, \
1883                .endpoint = ep, \
1884                .u = { \
1885                        .bulk = { \
1886                                .buffersize = 39480, \
1887                        } \
1888                } \
1889        }
1890
1891struct dvb_usb_device_properties dib0700_devices[] = {
1892        {
1893                DIB0700_DEFAULT_DEVICE_PROPERTIES,
1894
1895                .num_adapters = 1,
1896                .adapter = {
1897                        {
1898                                .frontend_attach  = stk7700p_frontend_attach,
1899                                .tuner_attach     = stk7700p_tuner_attach,
1900
1901                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1902                        },
1903                },
1904
1905                .num_device_descs = 8,
1906                .devices = {
1907                        {   "DiBcom STK7700P reference design",
1908                                { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
1909                                { NULL },
1910                        },
1911                        {   "Hauppauge Nova-T Stick",
1912                                { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
1913                                { NULL },
1914                        },
1915                        {   "AVerMedia AVerTV DVB-T Volar",
1916                                { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
1917                                { NULL },
1918                        },
1919                        {   "Compro Videomate U500",
1920                                { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
1921                                { NULL },
1922                        },
1923                        {   "Uniwill STK7700P based (Hama and others)",
1924                                { &dib0700_usb_id_table[7], NULL },
1925                                { NULL },
1926                        },
1927                        {   "Leadtek Winfast DTV Dongle (STK7700P based)",
1928                                { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
1929                                { NULL },
1930                        },
1931                        {   "AVerMedia AVerTV DVB-T Express",
1932                                { &dib0700_usb_id_table[20] },
1933                                { NULL },
1934                        },
1935                        {   "Gigabyte U7000",
1936                                { &dib0700_usb_id_table[21], NULL },
1937                                { NULL },
1938                        }
1939                },
1940
1941                .rc_interval      = DEFAULT_RC_INTERVAL,
1942                .rc_key_map       = dib0700_rc_keys,
1943                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1944                .rc_query         = dib0700_rc_query
1945        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1946
1947                .num_adapters = 2,
1948                .adapter = {
1949                        {
1950                                .frontend_attach  = bristol_frontend_attach,
1951                                .tuner_attach     = bristol_tuner_attach,
1952
1953                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1954                        }, {
1955                                .frontend_attach  = bristol_frontend_attach,
1956                                .tuner_attach     = bristol_tuner_attach,
1957
1958                                DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1959                        }
1960                },
1961
1962                .num_device_descs = 1,
1963                .devices = {
1964                        {   "Hauppauge Nova-T 500 Dual DVB-T",
1965                                { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
1966                                { NULL },
1967                        },
1968                },
1969
1970                .rc_interval      = DEFAULT_RC_INTERVAL,
1971                .rc_key_map       = dib0700_rc_keys,
1972                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1973                .rc_query         = dib0700_rc_query
1974        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1975
1976                .num_adapters = 2,
1977                .adapter = {
1978                        {
1979                                .frontend_attach  = stk7700d_frontend_attach,
1980                                .tuner_attach     = stk7700d_tuner_attach,
1981
1982                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1983                        }, {
1984                                .frontend_attach  = stk7700d_frontend_attach,
1985                                .tuner_attach     = stk7700d_tuner_attach,
1986
1987                                DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1988                        }
1989                },
1990
1991                .num_device_descs = 5,
1992                .devices = {
1993                        {   "Pinnacle PCTV 2000e",
1994                                { &dib0700_usb_id_table[11], NULL },
1995                                { NULL },
1996                        },
1997                        {   "Terratec Cinergy DT XS Diversity",
1998                                { &dib0700_usb_id_table[12], NULL },
1999                                { NULL },
2000                        },
2001                        {   "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
2002                                { &dib0700_usb_id_table[13], NULL },
2003                                { NULL },
2004                        },
2005                        {   "DiBcom STK7700D reference design",
2006                                { &dib0700_usb_id_table[14], NULL },
2007                                { NULL },
2008                        },
2009                        {   "YUAN High-Tech DiBcom STK7700D",
2010                                { &dib0700_usb_id_table[55], NULL },
2011                                { NULL },
2012                        },
2013
2014                },
2015
2016                .rc_interval      = DEFAULT_RC_INTERVAL,
2017                .rc_key_map       = dib0700_rc_keys,
2018                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2019                .rc_query         = dib0700_rc_query
2020
2021        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2022
2023                .num_adapters = 1,
2024                .adapter = {
2025                        {
2026                                .frontend_attach  = stk7700P2_frontend_attach,
2027                                .tuner_attach     = stk7700d_tuner_attach,
2028
2029                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2030                        },
2031                },
2032
2033                .num_device_descs = 3,
2034                .devices = {
2035                        {   "ASUS My Cinema U3000 Mini DVBT Tuner",
2036                                { &dib0700_usb_id_table[23], NULL },
2037                                { NULL },
2038                        },
2039                        {   "Yuan EC372S",
2040                                { &dib0700_usb_id_table[31], NULL },
2041                                { NULL },
2042                        },
2043                        {   "Terratec Cinergy T Express",
2044                                { &dib0700_usb_id_table[42], NULL },
2045                                { NULL },
2046                        }
2047                },
2048
2049                .rc_interval      = DEFAULT_RC_INTERVAL,
2050                .rc_key_map       = dib0700_rc_keys,
2051                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2052                .rc_query         = dib0700_rc_query
2053        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2054
2055                .num_adapters = 1,
2056                .adapter = {
2057                        {
2058                                .frontend_attach  = stk7070p_frontend_attach,
2059                                .tuner_attach     = dib7070p_tuner_attach,
2060
2061                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2062
2063                                .size_of_priv     = sizeof(struct dib0700_adapter_state),
2064                        },
2065                },
2066
2067                .num_device_descs = 11,
2068                .devices = {
2069                        {   "DiBcom STK7070P reference design",
2070                                { &dib0700_usb_id_table[15], NULL },
2071                                { NULL },
2072                        },
2073                        {   "Pinnacle PCTV DVB-T Flash Stick",
2074                                { &dib0700_usb_id_table[16], NULL },
2075                                { NULL },
2076                        },
2077                        {   "Artec T14BR DVB-T",
2078                                { &dib0700_usb_id_table[22], NULL },
2079                                { NULL },
2080                        },
2081                        {   "ASUS My Cinema U3100 Mini DVBT Tuner",
2082                                { &dib0700_usb_id_table[24], NULL },
2083                                { NULL },
2084                        },
2085                        {   "Hauppauge Nova-T Stick",
2086                                { &dib0700_usb_id_table[25], NULL },
2087                                { NULL },
2088                        },
2089                        {   "Hauppauge Nova-T MyTV.t",
2090                                { &dib0700_usb_id_table[26], NULL },
2091                                { NULL },
2092                        },
2093                        {   "Pinnacle PCTV 72e",
2094                                { &dib0700_usb_id_table[29], NULL },
2095                                { NULL },
2096                        },
2097                        {   "Pinnacle PCTV 73e",
2098                                { &dib0700_usb_id_table[30], NULL },
2099                                { NULL },
2100                        },
2101                        {   "Elgato EyeTV DTT",
2102                                { &dib0700_usb_id_table[49], NULL },
2103                                { NULL },
2104                        },
2105                        {   "Yuan PD378S",
2106                                { &dib0700_usb_id_table[45], NULL },
2107                                { NULL },
2108                        },
2109                        {   "Elgato EyeTV Dtt Dlx PD378S",
2110                                { &dib0700_usb_id_table[50], NULL },
2111                                { NULL },
2112                        },
2113                },
2114
2115                .rc_interval      = DEFAULT_RC_INTERVAL,
2116                .rc_key_map       = dib0700_rc_keys,
2117                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2118                .rc_query         = dib0700_rc_query
2119
2120        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2121
2122                .num_adapters = 1,
2123                .adapter = {
2124                        {
2125                                .frontend_attach  = stk7070p_frontend_attach,
2126                                .tuner_attach     = dib7070p_tuner_attach,
2127
2128                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2129
2130                                .size_of_priv     = sizeof(struct dib0700_adapter_state),
2131                        },
2132                },
2133
2134                .num_device_descs = 3,
2135                .devices = {
2136                        {   "Pinnacle PCTV 73A",
2137                                { &dib0700_usb_id_table[56], NULL },
2138                                { NULL },
2139                        },
2140                        {   "Pinnacle PCTV 73e SE",
2141                                { &dib0700_usb_id_table[57], NULL },
2142                                { NULL },
2143                        },
2144                        {   "Pinnacle PCTV 282e",
2145                                { &dib0700_usb_id_table[58], NULL },
2146                                { NULL },
2147                        },
2148                },
2149
2150                .rc_interval      = DEFAULT_RC_INTERVAL,
2151                .rc_key_map       = dib0700_rc_keys,
2152                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2153                .rc_query         = dib0700_rc_query
2154
2155        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2156
2157                .num_adapters = 2,
2158                .adapter = {
2159                        {
2160                                .frontend_attach  = stk7070pd_frontend_attach0,
2161                                .tuner_attach     = dib7070p_tuner_attach,
2162
2163                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2164
2165                                .size_of_priv     = sizeof(struct dib0700_adapter_state),
2166                        }, {
2167                                .frontend_attach  = stk7070pd_frontend_attach1,
2168                                .tuner_attach     = dib7070p_tuner_attach,
2169
2170                                DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
2171
2172                                .size_of_priv     = sizeof(struct dib0700_adapter_state),
2173                        }
2174                },
2175
2176                .num_device_descs = 6,
2177                .devices = {
2178                        {   "DiBcom STK7070PD reference design",
2179                                { &dib0700_usb_id_table[17], NULL },
2180                                { NULL },
2181                        },
2182                        {   "Pinnacle PCTV Dual DVB-T Diversity Stick",
2183                                { &dib0700_usb_id_table[18], NULL },
2184                                { NULL },
2185                        },
2186                        {   "Hauppauge Nova-TD Stick (52009)",
2187                                { &dib0700_usb_id_table[35], NULL },
2188                                { NULL },
2189                        },
2190                        {   "Hauppauge Nova-TD-500 (84xxx)",
2191                                { &dib0700_usb_id_table[36], NULL },
2192                                { NULL },
2193                        },
2194                        {  "Terratec Cinergy DT USB XS Diversity/ T5",
2195                                { &dib0700_usb_id_table[43],
2196                                        &dib0700_usb_id_table[53], NULL},
2197                                { NULL },
2198                        },
2199                        {  "Sony PlayTV",
2200                                { &dib0700_usb_id_table[44], NULL },
2201                                { NULL },
2202                        }
2203                },
2204                .rc_interval      = DEFAULT_RC_INTERVAL,
2205                .rc_key_map       = dib0700_rc_keys,
2206                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2207                .rc_query         = dib0700_rc_query
2208        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2209
2210                .num_adapters = 1,
2211                .adapter = {
2212                        {
2213                                .frontend_attach  = stk7700ph_frontend_attach,
2214                                .tuner_attach     = stk7700ph_tuner_attach,
2215
2216                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2217
2218                                .size_of_priv = sizeof(struct
2219                                                dib0700_adapter_state),
2220                        },
2221                },
2222
2223                .num_device_descs = 9,
2224                .devices = {
2225                        {   "Terratec Cinergy HT USB XE",
2226                                { &dib0700_usb_id_table[27], NULL },
2227                                { NULL },
2228                        },
2229                        {   "Pinnacle Expresscard 320cx",
2230                                { &dib0700_usb_id_table[28], NULL },
2231                                { NULL },
2232                        },
2233                        {   "Terratec Cinergy HT Express",
2234                                { &dib0700_usb_id_table[32], NULL },
2235                                { NULL },
2236                        },
2237                        {   "Gigabyte U8000-RH",
2238                                { &dib0700_usb_id_table[37], NULL },
2239                                { NULL },
2240                        },
2241                        {   "YUAN High-Tech STK7700PH",
2242                                { &dib0700_usb_id_table[38], NULL },
2243                                { NULL },
2244                        },
2245                        {   "Asus My Cinema-U3000Hybrid",
2246                                { &dib0700_usb_id_table[39], NULL },
2247                                { NULL },
2248                        },
2249                        {   "YUAN High-Tech MC770",
2250                                { &dib0700_usb_id_table[48], NULL },
2251                                { NULL },
2252                        },
2253                        {   "Leadtek WinFast DTV Dongle H",
2254                                { &dib0700_usb_id_table[51], NULL },
2255                                { NULL },
2256                        },
2257                        {   "YUAN High-Tech STK7700D",
2258                                { &dib0700_usb_id_table[54], NULL },
2259                                { NULL },
2260                        },
2261                },
2262                .rc_interval      = DEFAULT_RC_INTERVAL,
2263                .rc_key_map       = dib0700_rc_keys,
2264                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2265                .rc_query         = dib0700_rc_query
2266        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2267                .num_adapters = 1,
2268                .adapter = {
2269                        {
2270                                .frontend_attach  = s5h1411_frontend_attach,
2271                                .tuner_attach     = xc5000_tuner_attach,
2272
2273                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2274
2275                                .size_of_priv = sizeof(struct
2276                                                dib0700_adapter_state),
2277                        },
2278                },
2279
2280                .num_device_descs = 2,
2281                .devices = {
2282                        {   "Pinnacle PCTV HD Pro USB Stick",
2283                                { &dib0700_usb_id_table[40], NULL },
2284                                { NULL },
2285                        },
2286                        {   "Pinnacle PCTV HD USB Stick",
2287                                { &dib0700_usb_id_table[41], NULL },
2288                                { NULL },
2289                        },
2290                },
2291                .rc_interval      = DEFAULT_RC_INTERVAL,
2292                .rc_key_map       = dib0700_rc_keys,
2293                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2294                .rc_query         = dib0700_rc_query
2295        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2296                .num_adapters = 1,
2297                .adapter = {
2298                        {
2299                                .frontend_attach  = lgdt3305_frontend_attach,
2300                                .tuner_attach     = mxl5007t_tuner_attach,
2301
2302                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2303
2304                                .size_of_priv = sizeof(struct
2305                                                dib0700_adapter_state),
2306                        },
2307                },
2308
2309                .num_device_descs = 2,
2310                .devices = {
2311                        {   "Hauppauge ATSC MiniCard (B200)",
2312                                { &dib0700_usb_id_table[46], NULL },
2313                                { NULL },
2314                        },
2315                        {   "Hauppauge ATSC MiniCard (B210)",
2316                                { &dib0700_usb_id_table[47], NULL },
2317                                { NULL },
2318                        },
2319                },
2320        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2321
2322                .num_adapters = 1,
2323                .adapter = {
2324                        {
2325                                .frontend_attach  = stk7070p_frontend_attach,
2326                                .tuner_attach     = dib7770p_tuner_attach,
2327
2328                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2329
2330                                .size_of_priv =
2331                                        sizeof(struct dib0700_adapter_state),
2332                        },
2333                },
2334
2335                .num_device_descs = 2,
2336                .devices = {
2337                        {   "DiBcom STK7770P reference design",
2338                                { &dib0700_usb_id_table[59], NULL },
2339                                { NULL },
2340                        },
2341                        {   "Terratec Cinergy T USB XXS (HD)/ T3",
2342                                { &dib0700_usb_id_table[33],
2343                                        &dib0700_usb_id_table[52],
2344                                        &dib0700_usb_id_table[60], NULL},
2345                                { NULL },
2346                        },
2347                },
2348                .rc_interval      = DEFAULT_RC_INTERVAL,
2349                .rc_key_map       = dib0700_rc_keys,
2350                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2351                .rc_query         = dib0700_rc_query
2352        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2353                .num_adapters = 1,
2354                .adapter = {
2355                        {
2356                                .frontend_attach  = stk807x_frontend_attach,
2357                                .tuner_attach     = dib807x_tuner_attach,
2358
2359                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2360
2361                                .size_of_priv =
2362                                        sizeof(struct dib0700_adapter_state),
2363                        },
2364                },
2365
2366                .num_device_descs = 2,
2367                .devices = {
2368                        {   "DiBcom STK807xP reference design",
2369                                { &dib0700_usb_id_table[62], NULL },
2370                                { NULL },
2371                        },
2372                        {   "Prolink Pixelview SBTVD",
2373                                { &dib0700_usb_id_table[63], NULL },
2374                                { NULL },
2375                        },
2376                },
2377
2378                .rc_interval      = DEFAULT_RC_INTERVAL,
2379                .rc_key_map       = dib0700_rc_keys,
2380                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2381                .rc_query         = dib0700_rc_query
2382
2383        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2384                .num_adapters = 2,
2385                .adapter = {
2386                        {
2387                                .frontend_attach  = stk807xpvr_frontend_attach0,
2388                                .tuner_attach     = dib807x_tuner_attach,
2389
2390                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2391
2392                                .size_of_priv =
2393                                        sizeof(struct dib0700_adapter_state),
2394                        },
2395                        {
2396                                .frontend_attach  = stk807xpvr_frontend_attach1,
2397                                .tuner_attach     = dib807x_tuner_attach,
2398
2399                                DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
2400
2401                                .size_of_priv =
2402                                        sizeof(struct dib0700_adapter_state),
2403                        },
2404                },
2405
2406                .num_device_descs = 1,
2407                .devices = {
2408                        {   "DiBcom STK807xPVR reference design",
2409                                { &dib0700_usb_id_table[61], NULL },
2410                                { NULL },
2411                        },
2412                },
2413
2414                .rc_interval      = DEFAULT_RC_INTERVAL,
2415                .rc_key_map       = dib0700_rc_keys,
2416                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2417                .rc_query         = dib0700_rc_query
2418        },
2419};
2420
2421int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
2422