linux/drivers/media/usb/dvb-usb/cxusb.c
<<
>>
Prefs
   1/* DVB USB compliant linux driver for Conexant USB reference design.
   2 *
   3 * The Conexant reference design I saw on their website was only for analogue
   4 * capturing (using the cx25842). The box I took to write this driver (reverse
   5 * engineered) is the one labeled Medion MD95700. In addition to the cx25842
   6 * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
   7 * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
   8 *
   9 * Maybe it is a little bit premature to call this driver cxusb, but I assume
  10 * the USB protocol is identical or at least inherited from the reference
  11 * design, so it can be reused for the "analogue-only" device (if it will
  12 * appear at all).
  13 *
  14 * TODO: Use the cx25840-driver for the analogue part
  15 *
  16 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@posteo.de)
  17 * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org)
  18 * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
  19 *
  20 *   This program is free software; you can redistribute it and/or modify it
  21 *   under the terms of the GNU General Public License as published by the Free
  22 *   Software Foundation, version 2.
  23 *
  24 * see Documentation/dvb/README.dvb-usb for more information
  25 */
  26#include <media/tuner.h>
  27#include <linux/vmalloc.h>
  28#include <linux/slab.h>
  29
  30#include "cxusb.h"
  31
  32#include "cx22702.h"
  33#include "lgdt330x.h"
  34#include "mt352.h"
  35#include "mt352_priv.h"
  36#include "zl10353.h"
  37#include "tuner-xc2028.h"
  38#include "tuner-simple.h"
  39#include "mxl5005s.h"
  40#include "max2165.h"
  41#include "dib7000p.h"
  42#include "dib0070.h"
  43#include "lgs8gxx.h"
  44#include "atbm8830.h"
  45#include "si2168.h"
  46#include "si2157.h"
  47
  48/* debug */
  49static int dvb_usb_cxusb_debug;
  50module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
  51MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
  52
  53DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  54
  55#define deb_info(args...)   dprintk(dvb_usb_cxusb_debug, 0x03, args)
  56#define deb_i2c(args...)    dprintk(dvb_usb_cxusb_debug, 0x02, args)
  57
  58static int cxusb_ctrl_msg(struct dvb_usb_device *d,
  59                          u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
  60{
  61        struct cxusb_state *st = d->priv;
  62        int ret, wo;
  63
  64        if (1 + wlen > MAX_XFER_SIZE) {
  65                warn("i2c wr: len=%d is too big!\n", wlen);
  66                return -EOPNOTSUPP;
  67        }
  68
  69        wo = (rbuf == NULL || rlen == 0); /* write-only */
  70
  71        mutex_lock(&d->data_mutex);
  72        st->data[0] = cmd;
  73        memcpy(&st->data[1], wbuf, wlen);
  74        if (wo)
  75                ret = dvb_usb_generic_write(d, st->data, 1 + wlen);
  76        else
  77                ret = dvb_usb_generic_rw(d, st->data, 1 + wlen,
  78                                         rbuf, rlen, 0);
  79
  80        mutex_unlock(&d->data_mutex);
  81        return ret;
  82}
  83
  84/* GPIO */
  85static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
  86{
  87        struct cxusb_state *st = d->priv;
  88        u8 o[2], i;
  89
  90        if (st->gpio_write_state[GPIO_TUNER] == onoff)
  91                return;
  92
  93        o[0] = GPIO_TUNER;
  94        o[1] = onoff;
  95        cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
  96
  97        if (i != 0x01)
  98                deb_info("gpio_write failed.\n");
  99
 100        st->gpio_write_state[GPIO_TUNER] = onoff;
 101}
 102
 103static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
 104                                 u8 newval)
 105{
 106        u8 o[2], gpio_state;
 107        int rc;
 108
 109        o[0] = 0xff & ~changemask;      /* mask of bits to keep */
 110        o[1] = newval & changemask;     /* new values for bits  */
 111
 112        rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
 113        if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
 114                deb_info("bluebird_gpio_write failed.\n");
 115
 116        return rc < 0 ? rc : gpio_state;
 117}
 118
 119static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
 120{
 121        cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
 122        msleep(5);
 123        cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
 124}
 125
 126static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
 127{
 128        cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
 129}
 130
 131static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
 132                u8 addr, int onoff)
 133{
 134        u8  o[2] = {addr, onoff};
 135        u8  i;
 136        int rc;
 137
 138        rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
 139
 140        if (rc < 0)
 141                return rc;
 142        if (i == 0x01)
 143                return 0;
 144        else {
 145                deb_info("gpio_write failed.\n");
 146                return -EIO;
 147        }
 148}
 149
 150/* I2C */
 151static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 152                          int num)
 153{
 154        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 155        int ret;
 156        int i;
 157
 158        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 159                return -EAGAIN;
 160
 161        for (i = 0; i < num; i++) {
 162
 163                if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_MEDION)
 164                        switch (msg[i].addr) {
 165                        case 0x63:
 166                                cxusb_gpio_tuner(d, 0);
 167                                break;
 168                        default:
 169                                cxusb_gpio_tuner(d, 1);
 170                                break;
 171                        }
 172
 173                if (msg[i].flags & I2C_M_RD) {
 174                        /* read only */
 175                        u8 obuf[3], ibuf[MAX_XFER_SIZE];
 176
 177                        if (1 + msg[i].len > sizeof(ibuf)) {
 178                                warn("i2c rd: len=%d is too big!\n",
 179                                     msg[i].len);
 180                                ret = -EOPNOTSUPP;
 181                                goto unlock;
 182                        }
 183                        obuf[0] = 0;
 184                        obuf[1] = msg[i].len;
 185                        obuf[2] = msg[i].addr;
 186                        if (cxusb_ctrl_msg(d, CMD_I2C_READ,
 187                                           obuf, 3,
 188                                           ibuf, 1+msg[i].len) < 0) {
 189                                warn("i2c read failed");
 190                                break;
 191                        }
 192                        memcpy(msg[i].buf, &ibuf[1], msg[i].len);
 193                } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
 194                           msg[i].addr == msg[i+1].addr) {
 195                        /* write to then read from same address */
 196                        u8 obuf[MAX_XFER_SIZE], ibuf[MAX_XFER_SIZE];
 197
 198                        if (3 + msg[i].len > sizeof(obuf)) {
 199                                warn("i2c wr: len=%d is too big!\n",
 200                                     msg[i].len);
 201                                ret = -EOPNOTSUPP;
 202                                goto unlock;
 203                        }
 204                        if (1 + msg[i + 1].len > sizeof(ibuf)) {
 205                                warn("i2c rd: len=%d is too big!\n",
 206                                     msg[i + 1].len);
 207                                ret = -EOPNOTSUPP;
 208                                goto unlock;
 209                        }
 210                        obuf[0] = msg[i].len;
 211                        obuf[1] = msg[i+1].len;
 212                        obuf[2] = msg[i].addr;
 213                        memcpy(&obuf[3], msg[i].buf, msg[i].len);
 214
 215                        if (cxusb_ctrl_msg(d, CMD_I2C_READ,
 216                                           obuf, 3+msg[i].len,
 217                                           ibuf, 1+msg[i+1].len) < 0)
 218                                break;
 219
 220                        if (ibuf[0] != 0x08)
 221                                deb_i2c("i2c read may have failed\n");
 222
 223                        memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
 224
 225                        i++;
 226                } else {
 227                        /* write only */
 228                        u8 obuf[MAX_XFER_SIZE], ibuf;
 229
 230                        if (2 + msg[i].len > sizeof(obuf)) {
 231                                warn("i2c wr: len=%d is too big!\n",
 232                                     msg[i].len);
 233                                ret = -EOPNOTSUPP;
 234                                goto unlock;
 235                        }
 236                        obuf[0] = msg[i].addr;
 237                        obuf[1] = msg[i].len;
 238                        memcpy(&obuf[2], msg[i].buf, msg[i].len);
 239
 240                        if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
 241                                           2+msg[i].len, &ibuf,1) < 0)
 242                                break;
 243                        if (ibuf != 0x08)
 244                                deb_i2c("i2c write may have failed\n");
 245                }
 246        }
 247
 248        if (i == num)
 249                ret = num;
 250        else
 251                ret = -EREMOTEIO;
 252
 253unlock:
 254        mutex_unlock(&d->i2c_mutex);
 255        return ret;
 256}
 257
 258static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
 259{
 260        return I2C_FUNC_I2C;
 261}
 262
 263static struct i2c_algorithm cxusb_i2c_algo = {
 264        .master_xfer   = cxusb_i2c_xfer,
 265        .functionality = cxusb_i2c_func,
 266};
 267
 268static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
 269{
 270        u8 b = 0;
 271        if (onoff)
 272                return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
 273        else
 274                return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
 275}
 276
 277static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
 278{
 279        int ret;
 280        if (!onoff)
 281                return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
 282        if (d->state == DVB_USB_STATE_INIT &&
 283            usb_set_interface(d->udev, 0, 0) < 0)
 284                err("set interface failed");
 285        do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
 286                   !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
 287                   !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
 288        if (!ret) {
 289                /* FIXME: We don't know why, but we need to configure the
 290                 * lgdt3303 with the register settings below on resume */
 291                int i;
 292                u8 buf, bufs[] = {
 293                        0x0e, 0x2, 0x00, 0x7f,
 294                        0x0e, 0x2, 0x02, 0xfe,
 295                        0x0e, 0x2, 0x02, 0x01,
 296                        0x0e, 0x2, 0x00, 0x03,
 297                        0x0e, 0x2, 0x0d, 0x40,
 298                        0x0e, 0x2, 0x0e, 0x87,
 299                        0x0e, 0x2, 0x0f, 0x8e,
 300                        0x0e, 0x2, 0x10, 0x01,
 301                        0x0e, 0x2, 0x14, 0xd7,
 302                        0x0e, 0x2, 0x47, 0x88,
 303                };
 304                msleep(20);
 305                for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
 306                        ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
 307                                             bufs+i, 4, &buf, 1);
 308                        if (ret)
 309                                break;
 310                        if (buf != 0x8)
 311                                return -EREMOTEIO;
 312                }
 313        }
 314        return ret;
 315}
 316
 317static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
 318{
 319        u8 b = 0;
 320        if (onoff)
 321                return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
 322        else
 323                return 0;
 324}
 325
 326static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
 327{
 328        int rc = 0;
 329
 330        rc = cxusb_power_ctrl(d, onoff);
 331        if (!onoff)
 332                cxusb_nano2_led(d, 0);
 333
 334        return rc;
 335}
 336
 337static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
 338{
 339        int ret;
 340        u8  b;
 341        ret = cxusb_power_ctrl(d, onoff);
 342        if (!onoff)
 343                return ret;
 344
 345        msleep(128);
 346        cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
 347        msleep(100);
 348        return ret;
 349}
 350
 351static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 352{
 353        u8 buf[2] = { 0x03, 0x00 };
 354        if (onoff)
 355                cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
 356        else
 357                cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
 358
 359        return 0;
 360}
 361
 362static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 363{
 364        if (onoff)
 365                cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
 366        else
 367                cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
 368                               NULL, 0, NULL, 0);
 369        return 0;
 370}
 371
 372static int cxusb_read_status(struct dvb_frontend *fe,
 373                                  enum fe_status *status)
 374{
 375        struct dvb_usb_adapter *adap = (struct dvb_usb_adapter *)fe->dvb->priv;
 376        struct cxusb_state *state = (struct cxusb_state *)adap->dev->priv;
 377        int ret;
 378
 379        ret = state->fe_read_status(fe, status);
 380
 381        /* it need resync slave fifo when signal change from unlock to lock.*/
 382        if ((*status & FE_HAS_LOCK) && (!state->last_lock)) {
 383                mutex_lock(&state->stream_mutex);
 384                cxusb_streaming_ctrl(adap, 1);
 385                mutex_unlock(&state->stream_mutex);
 386        }
 387
 388        state->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0;
 389        return ret;
 390}
 391
 392static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
 393{
 394        int       ep = d->props.generic_bulk_ctrl_endpoint;
 395        const int timeout = 100;
 396        const int junk_len = 32;
 397        u8        *junk;
 398        int       rd_count;
 399
 400        /* Discard remaining data in video pipe */
 401        junk = kmalloc(junk_len, GFP_KERNEL);
 402        if (!junk)
 403                return;
 404        while (1) {
 405                if (usb_bulk_msg(d->udev,
 406                        usb_rcvbulkpipe(d->udev, ep),
 407                        junk, junk_len, &rd_count, timeout) < 0)
 408                        break;
 409                if (!rd_count)
 410                        break;
 411        }
 412        kfree(junk);
 413}
 414
 415static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
 416{
 417        struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream;
 418        const int timeout = 100;
 419        const int junk_len = p->u.bulk.buffersize;
 420        u8        *junk;
 421        int       rd_count;
 422
 423        /* Discard remaining data in video pipe */
 424        junk = kmalloc(junk_len, GFP_KERNEL);
 425        if (!junk)
 426                return;
 427        while (1) {
 428                if (usb_bulk_msg(d->udev,
 429                        usb_rcvbulkpipe(d->udev, p->endpoint),
 430                        junk, junk_len, &rd_count, timeout) < 0)
 431                        break;
 432                if (!rd_count)
 433                        break;
 434        }
 435        kfree(junk);
 436}
 437
 438static int cxusb_d680_dmb_streaming_ctrl(
 439                struct dvb_usb_adapter *adap, int onoff)
 440{
 441        if (onoff) {
 442                u8 buf[2] = { 0x03, 0x00 };
 443                cxusb_d680_dmb_drain_video(adap->dev);
 444                return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
 445                        buf, sizeof(buf), NULL, 0);
 446        } else {
 447                int ret = cxusb_ctrl_msg(adap->dev,
 448                        CMD_STREAMING_OFF, NULL, 0, NULL, 0);
 449                return ret;
 450        }
 451}
 452
 453static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 454{
 455        struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
 456        u8 ircode[4];
 457        int i;
 458
 459        cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
 460
 461        *event = 0;
 462        *state = REMOTE_NO_KEY_PRESSED;
 463
 464        for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
 465                if (rc5_custom(&keymap[i]) == ircode[2] &&
 466                    rc5_data(&keymap[i]) == ircode[3]) {
 467                        *event = keymap[i].keycode;
 468                        *state = REMOTE_KEY_PRESSED;
 469
 470                        return 0;
 471                }
 472        }
 473
 474        return 0;
 475}
 476
 477static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
 478                                    int *state)
 479{
 480        struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
 481        u8 ircode[4];
 482        int i;
 483        struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
 484                               .buf = ircode, .len = 4 };
 485
 486        *event = 0;
 487        *state = REMOTE_NO_KEY_PRESSED;
 488
 489        if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
 490                return 0;
 491
 492        for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
 493                if (rc5_custom(&keymap[i]) == ircode[1] &&
 494                    rc5_data(&keymap[i]) == ircode[2]) {
 495                        *event = keymap[i].keycode;
 496                        *state = REMOTE_KEY_PRESSED;
 497
 498                        return 0;
 499                }
 500        }
 501
 502        return 0;
 503}
 504
 505static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
 506                int *state)
 507{
 508        struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
 509        u8 ircode[2];
 510        int i;
 511
 512        *event = 0;
 513        *state = REMOTE_NO_KEY_PRESSED;
 514
 515        if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
 516                return 0;
 517
 518        for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
 519                if (rc5_custom(&keymap[i]) == ircode[0] &&
 520                    rc5_data(&keymap[i]) == ircode[1]) {
 521                        *event = keymap[i].keycode;
 522                        *state = REMOTE_KEY_PRESSED;
 523
 524                        return 0;
 525                }
 526        }
 527
 528        return 0;
 529}
 530
 531static struct rc_map_table rc_map_dvico_mce_table[] = {
 532        { 0xfe02, KEY_TV },
 533        { 0xfe0e, KEY_MP3 },
 534        { 0xfe1a, KEY_DVD },
 535        { 0xfe1e, KEY_FAVORITES },
 536        { 0xfe16, KEY_SETUP },
 537        { 0xfe46, KEY_POWER2 },
 538        { 0xfe0a, KEY_EPG },
 539        { 0xfe49, KEY_BACK },
 540        { 0xfe4d, KEY_MENU },
 541        { 0xfe51, KEY_UP },
 542        { 0xfe5b, KEY_LEFT },
 543        { 0xfe5f, KEY_RIGHT },
 544        { 0xfe53, KEY_DOWN },
 545        { 0xfe5e, KEY_OK },
 546        { 0xfe59, KEY_INFO },
 547        { 0xfe55, KEY_TAB },
 548        { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
 549        { 0xfe12, KEY_NEXTSONG },       /* Skip */
 550        { 0xfe42, KEY_ENTER      },     /* Windows/Start */
 551        { 0xfe15, KEY_VOLUMEUP },
 552        { 0xfe05, KEY_VOLUMEDOWN },
 553        { 0xfe11, KEY_CHANNELUP },
 554        { 0xfe09, KEY_CHANNELDOWN },
 555        { 0xfe52, KEY_CAMERA },
 556        { 0xfe5a, KEY_TUNER },  /* Live */
 557        { 0xfe19, KEY_OPEN },
 558        { 0xfe0b, KEY_1 },
 559        { 0xfe17, KEY_2 },
 560        { 0xfe1b, KEY_3 },
 561        { 0xfe07, KEY_4 },
 562        { 0xfe50, KEY_5 },
 563        { 0xfe54, KEY_6 },
 564        { 0xfe48, KEY_7 },
 565        { 0xfe4c, KEY_8 },
 566        { 0xfe58, KEY_9 },
 567        { 0xfe13, KEY_ANGLE },  /* Aspect */
 568        { 0xfe03, KEY_0 },
 569        { 0xfe1f, KEY_ZOOM },
 570        { 0xfe43, KEY_REWIND },
 571        { 0xfe47, KEY_PLAYPAUSE },
 572        { 0xfe4f, KEY_FASTFORWARD },
 573        { 0xfe57, KEY_MUTE },
 574        { 0xfe0d, KEY_STOP },
 575        { 0xfe01, KEY_RECORD },
 576        { 0xfe4e, KEY_POWER },
 577};
 578
 579static struct rc_map_table rc_map_dvico_portable_table[] = {
 580        { 0xfc02, KEY_SETUP },       /* Profile */
 581        { 0xfc43, KEY_POWER2 },
 582        { 0xfc06, KEY_EPG },
 583        { 0xfc5a, KEY_BACK },
 584        { 0xfc05, KEY_MENU },
 585        { 0xfc47, KEY_INFO },
 586        { 0xfc01, KEY_TAB },
 587        { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
 588        { 0xfc49, KEY_VOLUMEUP },
 589        { 0xfc09, KEY_VOLUMEDOWN },
 590        { 0xfc54, KEY_CHANNELUP },
 591        { 0xfc0b, KEY_CHANNELDOWN },
 592        { 0xfc16, KEY_CAMERA },
 593        { 0xfc40, KEY_TUNER },  /* ATV/DTV */
 594        { 0xfc45, KEY_OPEN },
 595        { 0xfc19, KEY_1 },
 596        { 0xfc18, KEY_2 },
 597        { 0xfc1b, KEY_3 },
 598        { 0xfc1a, KEY_4 },
 599        { 0xfc58, KEY_5 },
 600        { 0xfc59, KEY_6 },
 601        { 0xfc15, KEY_7 },
 602        { 0xfc14, KEY_8 },
 603        { 0xfc17, KEY_9 },
 604        { 0xfc44, KEY_ANGLE },  /* Aspect */
 605        { 0xfc55, KEY_0 },
 606        { 0xfc07, KEY_ZOOM },
 607        { 0xfc0a, KEY_REWIND },
 608        { 0xfc08, KEY_PLAYPAUSE },
 609        { 0xfc4b, KEY_FASTFORWARD },
 610        { 0xfc5b, KEY_MUTE },
 611        { 0xfc04, KEY_STOP },
 612        { 0xfc56, KEY_RECORD },
 613        { 0xfc57, KEY_POWER },
 614        { 0xfc41, KEY_UNKNOWN },    /* INPUT */
 615        { 0xfc00, KEY_UNKNOWN },    /* HD */
 616};
 617
 618static struct rc_map_table rc_map_d680_dmb_table[] = {
 619        { 0x0038, KEY_UNKNOWN },        /* TV/AV */
 620        { 0x080c, KEY_ZOOM },
 621        { 0x0800, KEY_0 },
 622        { 0x0001, KEY_1 },
 623        { 0x0802, KEY_2 },
 624        { 0x0003, KEY_3 },
 625        { 0x0804, KEY_4 },
 626        { 0x0005, KEY_5 },
 627        { 0x0806, KEY_6 },
 628        { 0x0007, KEY_7 },
 629        { 0x0808, KEY_8 },
 630        { 0x0009, KEY_9 },
 631        { 0x000a, KEY_MUTE },
 632        { 0x0829, KEY_BACK },
 633        { 0x0012, KEY_CHANNELUP },
 634        { 0x0813, KEY_CHANNELDOWN },
 635        { 0x002b, KEY_VOLUMEUP },
 636        { 0x082c, KEY_VOLUMEDOWN },
 637        { 0x0020, KEY_UP },
 638        { 0x0821, KEY_DOWN },
 639        { 0x0011, KEY_LEFT },
 640        { 0x0810, KEY_RIGHT },
 641        { 0x000d, KEY_OK },
 642        { 0x081f, KEY_RECORD },
 643        { 0x0017, KEY_PLAYPAUSE },
 644        { 0x0816, KEY_PLAYPAUSE },
 645        { 0x000b, KEY_STOP },
 646        { 0x0827, KEY_FASTFORWARD },
 647        { 0x0026, KEY_REWIND },
 648        { 0x081e, KEY_UNKNOWN },    /* Time Shift */
 649        { 0x000e, KEY_UNKNOWN },    /* Snapshot */
 650        { 0x082d, KEY_UNKNOWN },    /* Mouse Cursor */
 651        { 0x000f, KEY_UNKNOWN },    /* Minimize/Maximize */
 652        { 0x0814, KEY_UNKNOWN },    /* Shuffle */
 653        { 0x0025, KEY_POWER },
 654};
 655
 656static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
 657{
 658        static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };
 659        static u8 reset []         = { RESET,      0x80 };
 660        static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
 661        static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
 662        static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
 663        static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
 664
 665        mt352_write(fe, clock_config,   sizeof(clock_config));
 666        udelay(200);
 667        mt352_write(fe, reset,          sizeof(reset));
 668        mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
 669
 670        mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
 671        mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
 672        mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
 673
 674        return 0;
 675}
 676
 677static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
 678{       /* used in both lgz201 and th7579 */
 679        static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x29 };
 680        static u8 reset []         = { RESET,      0x80 };
 681        static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
 682        static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
 683        static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
 684        static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
 685
 686        mt352_write(fe, clock_config,   sizeof(clock_config));
 687        udelay(200);
 688        mt352_write(fe, reset,          sizeof(reset));
 689        mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
 690
 691        mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
 692        mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
 693        mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
 694        return 0;
 695}
 696
 697static struct cx22702_config cxusb_cx22702_config = {
 698        .demod_address = 0x63,
 699        .output_mode = CX22702_PARALLEL_OUTPUT,
 700};
 701
 702static struct lgdt330x_config cxusb_lgdt3303_config = {
 703        .demod_address = 0x0e,
 704        .demod_chip    = LGDT3303,
 705};
 706
 707static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
 708        .demod_address       = 0x0e,
 709        .demod_chip          = LGDT3303,
 710        .clock_polarity_flip = 2,
 711};
 712
 713static struct mt352_config cxusb_dee1601_config = {
 714        .demod_address = 0x0f,
 715        .demod_init    = cxusb_dee1601_demod_init,
 716};
 717
 718static struct zl10353_config cxusb_zl10353_dee1601_config = {
 719        .demod_address = 0x0f,
 720        .parallel_ts = 1,
 721};
 722
 723static struct mt352_config cxusb_mt352_config = {
 724        /* used in both lgz201 and th7579 */
 725        .demod_address = 0x0f,
 726        .demod_init    = cxusb_mt352_demod_init,
 727};
 728
 729static struct zl10353_config cxusb_zl10353_xc3028_config = {
 730        .demod_address = 0x0f,
 731        .if2 = 45600,
 732        .no_tuner = 1,
 733        .parallel_ts = 1,
 734};
 735
 736static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
 737        .demod_address = 0x0f,
 738        .if2 = 45600,
 739        .no_tuner = 1,
 740        .parallel_ts = 1,
 741        .disable_i2c_gate_ctrl = 1,
 742};
 743
 744static struct mt352_config cxusb_mt352_xc3028_config = {
 745        .demod_address = 0x0f,
 746        .if2 = 4560,
 747        .no_tuner = 1,
 748        .demod_init = cxusb_mt352_demod_init,
 749};
 750
 751/* FIXME: needs tweaking */
 752static struct mxl5005s_config aver_a868r_tuner = {
 753        .i2c_address     = 0x63,
 754        .if_freq         = 6000000UL,
 755        .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
 756        .agc_mode        = MXL_SINGLE_AGC,
 757        .tracking_filter = MXL_TF_C,
 758        .rssi_enable     = MXL_RSSI_ENABLE,
 759        .cap_select      = MXL_CAP_SEL_ENABLE,
 760        .div_out         = MXL_DIV_OUT_4,
 761        .clock_out       = MXL_CLOCK_OUT_DISABLE,
 762        .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
 763        .top             = MXL5005S_TOP_25P2,
 764        .mod_mode        = MXL_DIGITAL_MODE,
 765        .if_mode         = MXL_ZERO_IF,
 766        .AgcMasterByte   = 0x00,
 767};
 768
 769/* FIXME: needs tweaking */
 770static struct mxl5005s_config d680_dmb_tuner = {
 771        .i2c_address     = 0x63,
 772        .if_freq         = 36125000UL,
 773        .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
 774        .agc_mode        = MXL_SINGLE_AGC,
 775        .tracking_filter = MXL_TF_C,
 776        .rssi_enable     = MXL_RSSI_ENABLE,
 777        .cap_select      = MXL_CAP_SEL_ENABLE,
 778        .div_out         = MXL_DIV_OUT_4,
 779        .clock_out       = MXL_CLOCK_OUT_DISABLE,
 780        .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
 781        .top             = MXL5005S_TOP_25P2,
 782        .mod_mode        = MXL_DIGITAL_MODE,
 783        .if_mode         = MXL_ZERO_IF,
 784        .AgcMasterByte   = 0x00,
 785};
 786
 787static struct max2165_config mygica_d689_max2165_cfg = {
 788        .i2c_address = 0x60,
 789        .osc_clk = 20
 790};
 791
 792/* Callbacks for DVB USB */
 793static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
 794{
 795        dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
 796                   &adap->dev->i2c_adap, 0x61,
 797                   TUNER_PHILIPS_FMD1216ME_MK3);
 798        return 0;
 799}
 800
 801static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
 802{
 803        dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61,
 804                   NULL, DVB_PLL_THOMSON_DTT7579);
 805        return 0;
 806}
 807
 808static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
 809{
 810        dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201);
 811        return 0;
 812}
 813
 814static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
 815{
 816        dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
 817                   NULL, DVB_PLL_THOMSON_DTT7579);
 818        return 0;
 819}
 820
 821static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
 822{
 823        dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
 824                   &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
 825        return 0;
 826}
 827
 828static int dvico_bluebird_xc2028_callback(void *ptr, int component,
 829                                          int command, int arg)
 830{
 831        struct dvb_usb_adapter *adap = ptr;
 832        struct dvb_usb_device *d = adap->dev;
 833
 834        switch (command) {
 835        case XC2028_TUNER_RESET:
 836                deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
 837                cxusb_bluebird_gpio_pulse(d, 0x01, 1);
 838                break;
 839        case XC2028_RESET_CLK:
 840                deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
 841                break;
 842        default:
 843                deb_info("%s: unknown command %d, arg %d\n", __func__,
 844                         command, arg);
 845                return -EINVAL;
 846        }
 847
 848        return 0;
 849}
 850
 851static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
 852{
 853        struct dvb_frontend      *fe;
 854        struct xc2028_config      cfg = {
 855                .i2c_adap  = &adap->dev->i2c_adap,
 856                .i2c_addr  = 0x61,
 857        };
 858        static struct xc2028_ctrl ctl = {
 859                .fname       = XC2028_DEFAULT_FIRMWARE,
 860                .max_len     = 64,
 861                .demod       = XC3028_FE_ZARLINK456,
 862        };
 863
 864        /* FIXME: generalize & move to common area */
 865        adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback;
 866
 867        fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg);
 868        if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
 869                return -EIO;
 870
 871        fe->ops.tuner_ops.set_config(fe, &ctl);
 872
 873        return 0;
 874}
 875
 876static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
 877{
 878        dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
 879                   &adap->dev->i2c_adap, &aver_a868r_tuner);
 880        return 0;
 881}
 882
 883static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
 884{
 885        struct dvb_frontend *fe;
 886        fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
 887                        &adap->dev->i2c_adap, &d680_dmb_tuner);
 888        return (fe == NULL) ? -EIO : 0;
 889}
 890
 891static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
 892{
 893        struct dvb_frontend *fe;
 894        fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe,
 895                        &adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
 896        return (fe == NULL) ? -EIO : 0;
 897}
 898
 899static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
 900{
 901        u8 b;
 902        if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
 903                err("set interface failed");
 904
 905        cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
 906
 907        adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
 908                                         &adap->dev->i2c_adap);
 909        if ((adap->fe_adap[0].fe) != NULL)
 910                return 0;
 911
 912        return -EIO;
 913}
 914
 915static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
 916{
 917        if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
 918                err("set interface failed");
 919
 920        cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
 921
 922        adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach,
 923                                         &cxusb_lgdt3303_config,
 924                                         &adap->dev->i2c_adap);
 925        if ((adap->fe_adap[0].fe) != NULL)
 926                return 0;
 927
 928        return -EIO;
 929}
 930
 931static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
 932{
 933        adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
 934                              &adap->dev->i2c_adap);
 935        if (adap->fe_adap[0].fe != NULL)
 936                return 0;
 937
 938        return -EIO;
 939}
 940
 941static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
 942{
 943        /* used in both lgz201 and th7579 */
 944        if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
 945                err("set interface failed");
 946
 947        cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
 948
 949        adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
 950                                         &adap->dev->i2c_adap);
 951        if ((adap->fe_adap[0].fe) != NULL)
 952                return 0;
 953
 954        return -EIO;
 955}
 956
 957static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
 958{
 959        if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
 960                err("set interface failed");
 961
 962        cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
 963
 964        adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
 965                                         &adap->dev->i2c_adap);
 966        if ((adap->fe_adap[0].fe) != NULL)
 967                return 0;
 968
 969        adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
 970                                         &cxusb_zl10353_dee1601_config,
 971                                         &adap->dev->i2c_adap);
 972        if ((adap->fe_adap[0].fe) != NULL)
 973                return 0;
 974
 975        return -EIO;
 976}
 977
 978static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
 979{
 980        u8 ircode[4];
 981        int i;
 982        struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
 983                               .buf = ircode, .len = 4 };
 984
 985        if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
 986                err("set interface failed");
 987
 988        cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
 989
 990        /* reset the tuner and demodulator */
 991        cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
 992        cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
 993        cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
 994
 995        adap->fe_adap[0].fe =
 996                dvb_attach(zl10353_attach,
 997                           &cxusb_zl10353_xc3028_config_no_i2c_gate,
 998                           &adap->dev->i2c_adap);
 999        if ((adap->fe_adap[0].fe) == NULL)
1000                return -EIO;
1001
1002        /* try to determine if there is no IR decoder on the I2C bus */
1003        for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
1004                msleep(20);
1005                if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
1006                        goto no_IR;
1007                if (ircode[0] == 0 && ircode[1] == 0)
1008                        continue;
1009                if (ircode[2] + ircode[3] != 0xff) {
1010no_IR:
1011                        adap->dev->props.rc.legacy.rc_map_table = NULL;
1012                        info("No IR receiver detected on this device.");
1013                        break;
1014                }
1015        }
1016
1017        return 0;
1018}
1019
1020static struct dibx000_agc_config dib7070_agc_config = {
1021        .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1022
1023        /*
1024         * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
1025         * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1026         * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
1027         */
1028        .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
1029                 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1030        .inv_gain = 600,
1031        .time_stabiliz = 10,
1032        .alpha_level = 0,
1033        .thlock = 118,
1034        .wbd_inv = 0,
1035        .wbd_ref = 3530,
1036        .wbd_sel = 1,
1037        .wbd_alpha = 5,
1038        .agc1_max = 65535,
1039        .agc1_min = 0,
1040        .agc2_max = 65535,
1041        .agc2_min = 0,
1042        .agc1_pt1 = 0,
1043        .agc1_pt2 = 40,
1044        .agc1_pt3 = 183,
1045        .agc1_slope1 = 206,
1046        .agc1_slope2 = 255,
1047        .agc2_pt1 = 72,
1048        .agc2_pt2 = 152,
1049        .agc2_slope1 = 88,
1050        .agc2_slope2 = 90,
1051        .alpha_mant = 17,
1052        .alpha_exp = 27,
1053        .beta_mant = 23,
1054        .beta_exp = 51,
1055        .perform_agc_softsplit = 0,
1056};
1057
1058static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1059        .internal = 60000,
1060        .sampling = 15000,
1061        .pll_prediv = 1,
1062        .pll_ratio = 20,
1063        .pll_range = 3,
1064        .pll_reset = 1,
1065        .pll_bypass = 0,
1066        .enable_refdiv = 0,
1067        .bypclk_div = 0,
1068        .IO_CLK_en_core = 1,
1069        .ADClkSrc = 1,
1070        .modulo = 2,
1071        /* refsel, sel, freq_15k */
1072        .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
1073        .ifreq = (0 << 25) | 0,
1074        .timf = 20452225,
1075        .xtal_hz = 12000000,
1076};
1077
1078static struct dib7000p_config cxusb_dualdig4_rev2_config = {
1079        .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
1080        .output_mpeg2_in_188_bytes = 1,
1081
1082        .agc_config_count = 1,
1083        .agc = &dib7070_agc_config,
1084        .bw  = &dib7070_bw_config_12_mhz,
1085        .tuner_is_baseband = 1,
1086        .spur_protect = 1,
1087
1088        .gpio_dir = 0xfcef,
1089        .gpio_val = 0x0110,
1090
1091        .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1092
1093        .hostbus_diversity = 1,
1094};
1095
1096struct dib0700_adapter_state {
1097        int (*set_param_save)(struct dvb_frontend *);
1098        struct dib7000p_ops dib7000p_ops;
1099};
1100
1101static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
1102{
1103        struct dib0700_adapter_state *state = adap->priv;
1104
1105        if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1106                err("set interface failed");
1107
1108        cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1109
1110        cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1111
1112        if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
1113                return -ENODEV;
1114
1115        if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1116                                       &cxusb_dualdig4_rev2_config) < 0) {
1117                printk(KERN_WARNING "Unable to enumerate dib7000p\n");
1118                return -ENODEV;
1119        }
1120
1121        adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80,
1122                                              &cxusb_dualdig4_rev2_config);
1123        if (adap->fe_adap[0].fe == NULL)
1124                return -EIO;
1125
1126        return 0;
1127}
1128
1129static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1130{
1131        struct dvb_usb_adapter *adap = fe->dvb->priv;
1132        struct dib0700_adapter_state *state = adap->priv;
1133
1134        return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff);
1135}
1136
1137static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1138{
1139        return 0;
1140}
1141
1142static struct dib0070_config dib7070p_dib0070_config = {
1143        .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1144        .reset = dib7070_tuner_reset,
1145        .sleep = dib7070_tuner_sleep,
1146        .clock_khz = 12000,
1147};
1148
1149static int dib7070_set_param_override(struct dvb_frontend *fe)
1150{
1151        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1152        struct dvb_usb_adapter *adap = fe->dvb->priv;
1153        struct dib0700_adapter_state *state = adap->priv;
1154
1155        u16 offset;
1156        u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
1157        switch (band) {
1158        case BAND_VHF: offset = 950; break;
1159        default:
1160        case BAND_UHF: offset = 550; break;
1161        }
1162
1163        state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1164
1165        return state->set_param_save(fe);
1166}
1167
1168static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
1169{
1170        struct dib0700_adapter_state *st = adap->priv;
1171        struct i2c_adapter *tun_i2c;
1172
1173        /*
1174         * No need to call dvb7000p_attach here, as it was called
1175         * already, as frontend_attach method is called first, and
1176         * tuner_attach is only called on sucess.
1177         */
1178        tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe,
1179                                        DIBX000_I2C_INTERFACE_TUNER, 1);
1180
1181        if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
1182            &dib7070p_dib0070_config) == NULL)
1183                return -ENODEV;
1184
1185        st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1186        adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1187        return 0;
1188}
1189
1190static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
1191{
1192        if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1193                err("set interface failed");
1194
1195        cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1196
1197        /* reset the tuner and demodulator */
1198        cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
1199        cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
1200        cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1201
1202        adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
1203                                         &cxusb_zl10353_xc3028_config,
1204                                         &adap->dev->i2c_adap);
1205        if ((adap->fe_adap[0].fe) != NULL)
1206                return 0;
1207
1208        adap->fe_adap[0].fe = dvb_attach(mt352_attach,
1209                                         &cxusb_mt352_xc3028_config,
1210                                         &adap->dev->i2c_adap);
1211        if ((adap->fe_adap[0].fe) != NULL)
1212                return 0;
1213
1214        return -EIO;
1215}
1216
1217static struct lgs8gxx_config d680_lgs8gl5_cfg = {
1218        .prod = LGS8GXX_PROD_LGS8GL5,
1219        .demod_address = 0x19,
1220        .serial_ts = 0,
1221        .ts_clk_pol = 0,
1222        .ts_clk_gated = 1,
1223        .if_clk_freq = 30400, /* 30.4 MHz */
1224        .if_freq = 5725, /* 5.725 MHz */
1225        .if_neg_center = 0,
1226        .ext_adc = 0,
1227        .adc_signed = 0,
1228        .if_neg_edge = 0,
1229};
1230
1231static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1232{
1233        struct dvb_usb_device *d = adap->dev;
1234        int n;
1235
1236        /* Select required USB configuration */
1237        if (usb_set_interface(d->udev, 0, 0) < 0)
1238                err("set interface failed");
1239
1240        /* Unblock all USB pipes */
1241        usb_clear_halt(d->udev,
1242                usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1243        usb_clear_halt(d->udev,
1244                usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1245        usb_clear_halt(d->udev,
1246                usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
1247
1248        /* Drain USB pipes to avoid hang after reboot */
1249        for (n = 0;  n < 5;  n++) {
1250                cxusb_d680_dmb_drain_message(d);
1251                cxusb_d680_dmb_drain_video(d);
1252                msleep(200);
1253        }
1254
1255        /* Reset the tuner */
1256        if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1257                err("clear tuner gpio failed");
1258                return -EIO;
1259        }
1260        msleep(100);
1261        if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1262                err("set tuner gpio failed");
1263                return -EIO;
1264        }
1265        msleep(100);
1266
1267        /* Attach frontend */
1268        adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
1269        if (adap->fe_adap[0].fe == NULL)
1270                return -EIO;
1271
1272        return 0;
1273}
1274
1275static struct atbm8830_config mygica_d689_atbm8830_cfg = {
1276        .prod = ATBM8830_PROD_8830,
1277        .demod_address = 0x40,
1278        .serial_ts = 0,
1279        .ts_sampling_edge = 1,
1280        .ts_clk_gated = 0,
1281        .osc_clk_freq = 30400, /* in kHz */
1282        .if_freq = 0, /* zero IF */
1283        .zif_swap_iq = 1,
1284        .agc_min = 0x2E,
1285        .agc_max = 0x90,
1286        .agc_hold_loop = 0,
1287};
1288
1289static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
1290{
1291        struct dvb_usb_device *d = adap->dev;
1292
1293        /* Select required USB configuration */
1294        if (usb_set_interface(d->udev, 0, 0) < 0)
1295                err("set interface failed");
1296
1297        /* Unblock all USB pipes */
1298        usb_clear_halt(d->udev,
1299                usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1300        usb_clear_halt(d->udev,
1301                usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1302        usb_clear_halt(d->udev,
1303                usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
1304
1305
1306        /* Reset the tuner */
1307        if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1308                err("clear tuner gpio failed");
1309                return -EIO;
1310        }
1311        msleep(100);
1312        if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1313                err("set tuner gpio failed");
1314                return -EIO;
1315        }
1316        msleep(100);
1317
1318        /* Attach frontend */
1319        adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
1320                &d->i2c_adap);
1321        if (adap->fe_adap[0].fe == NULL)
1322                return -EIO;
1323
1324        return 0;
1325}
1326
1327static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap)
1328{
1329        struct dvb_usb_device *d = adap->dev;
1330        struct cxusb_state *st = d->priv;
1331        struct i2c_adapter *adapter;
1332        struct i2c_client *client_demod;
1333        struct i2c_client *client_tuner;
1334        struct i2c_board_info info;
1335        struct si2168_config si2168_config;
1336        struct si2157_config si2157_config;
1337
1338        /* Select required USB configuration */
1339        if (usb_set_interface(d->udev, 0, 0) < 0)
1340                err("set interface failed");
1341
1342        /* Unblock all USB pipes */
1343        usb_clear_halt(d->udev,
1344                usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1345        usb_clear_halt(d->udev,
1346                usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1347        usb_clear_halt(d->udev,
1348                usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
1349
1350        /* attach frontend */
1351        si2168_config.i2c_adapter = &adapter;
1352        si2168_config.fe = &adap->fe_adap[0].fe;
1353        si2168_config.ts_mode = SI2168_TS_PARALLEL;
1354        si2168_config.ts_clock_inv = 1;
1355        memset(&info, 0, sizeof(struct i2c_board_info));
1356        strlcpy(info.type, "si2168", I2C_NAME_SIZE);
1357        info.addr = 0x64;
1358        info.platform_data = &si2168_config;
1359        request_module(info.type);
1360        client_demod = i2c_new_device(&d->i2c_adap, &info);
1361        if (client_demod == NULL || client_demod->dev.driver == NULL)
1362                return -ENODEV;
1363
1364        if (!try_module_get(client_demod->dev.driver->owner)) {
1365                i2c_unregister_device(client_demod);
1366                return -ENODEV;
1367        }
1368
1369        st->i2c_client_demod = client_demod;
1370
1371        /* attach tuner */
1372        memset(&si2157_config, 0, sizeof(si2157_config));
1373        si2157_config.fe = adap->fe_adap[0].fe;
1374        si2157_config.if_port = 1;
1375        memset(&info, 0, sizeof(struct i2c_board_info));
1376        strlcpy(info.type, "si2157", I2C_NAME_SIZE);
1377        info.addr = 0x60;
1378        info.platform_data = &si2157_config;
1379        request_module(info.type);
1380        client_tuner = i2c_new_device(adapter, &info);
1381        if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
1382                module_put(client_demod->dev.driver->owner);
1383                i2c_unregister_device(client_demod);
1384                return -ENODEV;
1385        }
1386        if (!try_module_get(client_tuner->dev.driver->owner)) {
1387                i2c_unregister_device(client_tuner);
1388                module_put(client_demod->dev.driver->owner);
1389                i2c_unregister_device(client_demod);
1390                return -ENODEV;
1391        }
1392
1393        st->i2c_client_tuner = client_tuner;
1394
1395        /* hook fe: need to resync the slave fifo when signal locks. */
1396        mutex_init(&st->stream_mutex);
1397        st->last_lock = 0;
1398        st->fe_read_status = adap->fe_adap[0].fe->ops.read_status;
1399        adap->fe_adap[0].fe->ops.read_status = cxusb_read_status;
1400
1401        return 0;
1402}
1403
1404/*
1405 * DViCO has shipped two devices with the same USB ID, but only one of them
1406 * needs a firmware download.  Check the device class details to see if they
1407 * have non-default values to decide whether the device is actually cold or
1408 * not, and forget a match if it turns out we selected the wrong device.
1409 */
1410static int bluebird_fx2_identify_state(struct usb_device *udev,
1411                                       struct dvb_usb_device_properties *props,
1412                                       struct dvb_usb_device_description **desc,
1413                                       int *cold)
1414{
1415        int wascold = *cold;
1416
1417        *cold = udev->descriptor.bDeviceClass == 0xff &&
1418                udev->descriptor.bDeviceSubClass == 0xff &&
1419                udev->descriptor.bDeviceProtocol == 0xff;
1420
1421        if (*cold && !wascold)
1422                *desc = NULL;
1423
1424        return 0;
1425}
1426
1427/*
1428 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
1429 * firmware file before download.
1430 */
1431
1432static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
1433static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
1434                                                  const struct firmware *fw)
1435{
1436        int pos;
1437
1438        for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
1439                int idoff = dvico_firmware_id_offsets[pos];
1440
1441                if (fw->size < idoff + 4)
1442                        continue;
1443
1444                if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
1445                    fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
1446                        struct firmware new_fw;
1447                        u8 *new_fw_data = vmalloc(fw->size);
1448                        int ret;
1449
1450                        if (!new_fw_data)
1451                                return -ENOMEM;
1452
1453                        memcpy(new_fw_data, fw->data, fw->size);
1454                        new_fw.size = fw->size;
1455                        new_fw.data = new_fw_data;
1456
1457                        new_fw_data[idoff + 2] =
1458                                le16_to_cpu(udev->descriptor.idProduct) + 1;
1459                        new_fw_data[idoff + 3] =
1460                                le16_to_cpu(udev->descriptor.idProduct) >> 8;
1461
1462                        ret = usb_cypress_load_firmware(udev, &new_fw,
1463                                                        CYPRESS_FX2);
1464                        vfree(new_fw_data);
1465                        return ret;
1466                }
1467        }
1468
1469        return -EINVAL;
1470}
1471
1472/* DVB USB Driver stuff */
1473static struct dvb_usb_device_properties cxusb_medion_properties;
1474static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
1475static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
1476static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
1477static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
1478static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
1479static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
1480static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
1481static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
1482static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
1483static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
1484static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
1485static struct dvb_usb_device_properties cxusb_mygica_t230_properties;
1486
1487static int cxusb_probe(struct usb_interface *intf,
1488                       const struct usb_device_id *id)
1489{
1490        if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
1491                                     THIS_MODULE, NULL, adapter_nr) ||
1492            0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
1493                                     THIS_MODULE, NULL, adapter_nr) ||
1494            0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
1495                                     THIS_MODULE, NULL, adapter_nr) ||
1496            0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
1497                                     THIS_MODULE, NULL, adapter_nr) ||
1498            0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
1499                                     THIS_MODULE, NULL, adapter_nr) ||
1500            0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
1501                                     THIS_MODULE, NULL, adapter_nr) ||
1502            0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
1503                                     THIS_MODULE, NULL, adapter_nr) ||
1504            0 == dvb_usb_device_init(intf,
1505                                &cxusb_bluebird_nano2_needsfirmware_properties,
1506                                     THIS_MODULE, NULL, adapter_nr) ||
1507            0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
1508                                     THIS_MODULE, NULL, adapter_nr) ||
1509            0 == dvb_usb_device_init(intf,
1510                                     &cxusb_bluebird_dualdig4_rev2_properties,
1511                                     THIS_MODULE, NULL, adapter_nr) ||
1512            0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
1513                                     THIS_MODULE, NULL, adapter_nr) ||
1514            0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
1515                                     THIS_MODULE, NULL, adapter_nr) ||
1516            0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties,
1517                                     THIS_MODULE, NULL, adapter_nr) ||
1518            0)
1519                return 0;
1520
1521        return -EINVAL;
1522}
1523
1524static void cxusb_disconnect(struct usb_interface *intf)
1525{
1526        struct dvb_usb_device *d = usb_get_intfdata(intf);
1527        struct cxusb_state *st = d->priv;
1528        struct i2c_client *client;
1529
1530        /* remove I2C client for tuner */
1531        client = st->i2c_client_tuner;
1532        if (client) {
1533                module_put(client->dev.driver->owner);
1534                i2c_unregister_device(client);
1535        }
1536
1537        /* remove I2C client for demodulator */
1538        client = st->i2c_client_demod;
1539        if (client) {
1540                module_put(client->dev.driver->owner);
1541                i2c_unregister_device(client);
1542        }
1543
1544        dvb_usb_device_exit(intf);
1545}
1546
1547enum cxusb_table_index {
1548        MEDION_MD95700,
1549        DVICO_BLUEBIRD_LG064F_COLD,
1550        DVICO_BLUEBIRD_LG064F_WARM,
1551        DVICO_BLUEBIRD_DUAL_1_COLD,
1552        DVICO_BLUEBIRD_DUAL_1_WARM,
1553        DVICO_BLUEBIRD_LGZ201_COLD,
1554        DVICO_BLUEBIRD_LGZ201_WARM,
1555        DVICO_BLUEBIRD_TH7579_COLD,
1556        DVICO_BLUEBIRD_TH7579_WARM,
1557        DIGITALNOW_BLUEBIRD_DUAL_1_COLD,
1558        DIGITALNOW_BLUEBIRD_DUAL_1_WARM,
1559        DVICO_BLUEBIRD_DUAL_2_COLD,
1560        DVICO_BLUEBIRD_DUAL_2_WARM,
1561        DVICO_BLUEBIRD_DUAL_4,
1562        DVICO_BLUEBIRD_DVB_T_NANO_2,
1563        DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM,
1564        AVERMEDIA_VOLAR_A868R,
1565        DVICO_BLUEBIRD_DUAL_4_REV_2,
1566        CONEXANT_D680_DMB,
1567        MYGICA_D689,
1568        MYGICA_T230,
1569        NR__cxusb_table_index
1570};
1571
1572static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = {
1573        [MEDION_MD95700] = {
1574                USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700)
1575        },
1576        [DVICO_BLUEBIRD_LG064F_COLD] = {
1577                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD)
1578        },
1579        [DVICO_BLUEBIRD_LG064F_WARM] = {
1580                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM)
1581        },
1582        [DVICO_BLUEBIRD_DUAL_1_COLD] = {
1583                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD)
1584        },
1585        [DVICO_BLUEBIRD_DUAL_1_WARM] = {
1586                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM)
1587        },
1588        [DVICO_BLUEBIRD_LGZ201_COLD] = {
1589                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD)
1590        },
1591        [DVICO_BLUEBIRD_LGZ201_WARM] = {
1592                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM)
1593        },
1594        [DVICO_BLUEBIRD_TH7579_COLD] = {
1595                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD)
1596        },
1597        [DVICO_BLUEBIRD_TH7579_WARM] = {
1598                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM)
1599        },
1600        [DIGITALNOW_BLUEBIRD_DUAL_1_COLD] = {
1601                USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD)
1602        },
1603        [DIGITALNOW_BLUEBIRD_DUAL_1_WARM] = {
1604                USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM)
1605        },
1606        [DVICO_BLUEBIRD_DUAL_2_COLD] = {
1607                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD)
1608        },
1609        [DVICO_BLUEBIRD_DUAL_2_WARM] = {
1610                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM)
1611        },
1612        [DVICO_BLUEBIRD_DUAL_4] = {
1613                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4)
1614        },
1615        [DVICO_BLUEBIRD_DVB_T_NANO_2] = {
1616                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2)
1617        },
1618        [DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM] = {
1619                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM)
1620        },
1621        [AVERMEDIA_VOLAR_A868R] = {
1622                USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R)
1623        },
1624        [DVICO_BLUEBIRD_DUAL_4_REV_2] = {
1625                USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2)
1626        },
1627        [CONEXANT_D680_DMB] = {
1628                USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB)
1629        },
1630        [MYGICA_D689] = {
1631                USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689)
1632        },
1633        [MYGICA_T230] = {
1634                USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230)
1635        },
1636        {}              /* Terminating entry */
1637};
1638MODULE_DEVICE_TABLE (usb, cxusb_table);
1639
1640static struct dvb_usb_device_properties cxusb_medion_properties = {
1641        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1642
1643        .usb_ctrl = CYPRESS_FX2,
1644
1645        .size_of_priv     = sizeof(struct cxusb_state),
1646
1647        .num_adapters = 1,
1648        .adapter = {
1649                {
1650                .num_frontends = 1,
1651                .fe = {{
1652                        .streaming_ctrl   = cxusb_streaming_ctrl,
1653                        .frontend_attach  = cxusb_cx22702_frontend_attach,
1654                        .tuner_attach     = cxusb_fmd1216me_tuner_attach,
1655                        /* parameter for the MPEG2-data transfer */
1656                                        .stream = {
1657                                                .type = USB_BULK,
1658                                .count = 5,
1659                                .endpoint = 0x02,
1660                                .u = {
1661                                        .bulk = {
1662                                                .buffersize = 8192,
1663                                        }
1664                                }
1665                        },
1666                }},
1667                },
1668        },
1669        .power_ctrl       = cxusb_power_ctrl,
1670
1671        .i2c_algo         = &cxusb_i2c_algo,
1672
1673        .generic_bulk_ctrl_endpoint = 0x01,
1674
1675        .num_device_descs = 1,
1676        .devices = {
1677                {   "Medion MD95700 (MDUSBTV-HYBRID)",
1678                        { NULL },
1679                        { &cxusb_table[MEDION_MD95700], NULL },
1680                },
1681        }
1682};
1683
1684static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
1685        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1686
1687        .usb_ctrl          = DEVICE_SPECIFIC,
1688        .firmware          = "dvb-usb-bluebird-01.fw",
1689        .download_firmware = bluebird_patch_dvico_firmware_download,
1690        /* use usb alt setting 0 for EP4 transfer (dvb-t),
1691           use usb alt setting 7 for EP2 transfer (atsc) */
1692
1693        .size_of_priv     = sizeof(struct cxusb_state),
1694
1695        .num_adapters = 1,
1696        .adapter = {
1697                {
1698                .num_frontends = 1,
1699                .fe = {{
1700                        .streaming_ctrl   = cxusb_streaming_ctrl,
1701                        .frontend_attach  = cxusb_lgdt3303_frontend_attach,
1702                        .tuner_attach     = cxusb_lgh064f_tuner_attach,
1703
1704                        /* parameter for the MPEG2-data transfer */
1705                                        .stream = {
1706                                                .type = USB_BULK,
1707                                .count = 5,
1708                                .endpoint = 0x02,
1709                                .u = {
1710                                        .bulk = {
1711                                                .buffersize = 8192,
1712                                        }
1713                                }
1714                        },
1715                }},
1716                },
1717        },
1718
1719        .power_ctrl       = cxusb_bluebird_power_ctrl,
1720
1721        .i2c_algo         = &cxusb_i2c_algo,
1722
1723        .rc.legacy = {
1724                .rc_interval      = 100,
1725                .rc_map_table     = rc_map_dvico_portable_table,
1726                .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
1727                .rc_query         = cxusb_rc_query,
1728        },
1729
1730        .generic_bulk_ctrl_endpoint = 0x01,
1731
1732        .num_device_descs = 1,
1733        .devices = {
1734                {   "DViCO FusionHDTV5 USB Gold",
1735                        { &cxusb_table[DVICO_BLUEBIRD_LG064F_COLD], NULL },
1736                        { &cxusb_table[DVICO_BLUEBIRD_LG064F_WARM], NULL },
1737                },
1738        }
1739};
1740
1741static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
1742        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1743
1744        .usb_ctrl          = DEVICE_SPECIFIC,
1745        .firmware          = "dvb-usb-bluebird-01.fw",
1746        .download_firmware = bluebird_patch_dvico_firmware_download,
1747        /* use usb alt setting 0 for EP4 transfer (dvb-t),
1748           use usb alt setting 7 for EP2 transfer (atsc) */
1749
1750        .size_of_priv     = sizeof(struct cxusb_state),
1751
1752        .num_adapters = 1,
1753        .adapter = {
1754                {
1755                .num_frontends = 1,
1756                .fe = {{
1757                        .streaming_ctrl   = cxusb_streaming_ctrl,
1758                        .frontend_attach  = cxusb_dee1601_frontend_attach,
1759                        .tuner_attach     = cxusb_dee1601_tuner_attach,
1760                        /* parameter for the MPEG2-data transfer */
1761                        .stream = {
1762                                .type = USB_BULK,
1763                                .count = 5,
1764                                .endpoint = 0x04,
1765                                .u = {
1766                                        .bulk = {
1767                                                .buffersize = 8192,
1768                                        }
1769                                }
1770                        },
1771                }},
1772                },
1773        },
1774
1775        .power_ctrl       = cxusb_bluebird_power_ctrl,
1776
1777        .i2c_algo         = &cxusb_i2c_algo,
1778
1779        .rc.legacy = {
1780                .rc_interval      = 150,
1781                .rc_map_table     = rc_map_dvico_mce_table,
1782                .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
1783                .rc_query         = cxusb_rc_query,
1784        },
1785
1786        .generic_bulk_ctrl_endpoint = 0x01,
1787
1788        .num_device_descs = 3,
1789        .devices = {
1790                {   "DViCO FusionHDTV DVB-T Dual USB",
1791                        { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_COLD], NULL },
1792                        { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_WARM], NULL },
1793                },
1794                {   "DigitalNow DVB-T Dual USB",
1795                        { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_COLD],  NULL },
1796                        { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_WARM], NULL },
1797                },
1798                {   "DViCO FusionHDTV DVB-T Dual Digital 2",
1799                        { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_COLD], NULL },
1800                        { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_WARM], NULL },
1801                },
1802        }
1803};
1804
1805static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
1806        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1807
1808        .usb_ctrl          = DEVICE_SPECIFIC,
1809        .firmware          = "dvb-usb-bluebird-01.fw",
1810        .download_firmware = bluebird_patch_dvico_firmware_download,
1811        /* use usb alt setting 0 for EP4 transfer (dvb-t),
1812           use usb alt setting 7 for EP2 transfer (atsc) */
1813
1814        .size_of_priv     = sizeof(struct cxusb_state),
1815
1816        .num_adapters = 2,
1817        .adapter = {
1818                {
1819                .num_frontends = 1,
1820                .fe = {{
1821                        .streaming_ctrl   = cxusb_streaming_ctrl,
1822                        .frontend_attach  = cxusb_mt352_frontend_attach,
1823                        .tuner_attach     = cxusb_lgz201_tuner_attach,
1824
1825                        /* parameter for the MPEG2-data transfer */
1826                        .stream = {
1827                                .type = USB_BULK,
1828                                .count = 5,
1829                                .endpoint = 0x04,
1830                                .u = {
1831                                        .bulk = {
1832                                                .buffersize = 8192,
1833                                        }
1834                                }
1835                        },
1836                }},
1837                },
1838        },
1839        .power_ctrl       = cxusb_bluebird_power_ctrl,
1840
1841        .i2c_algo         = &cxusb_i2c_algo,
1842
1843        .rc.legacy = {
1844                .rc_interval      = 100,
1845                .rc_map_table     = rc_map_dvico_portable_table,
1846                .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
1847                .rc_query         = cxusb_rc_query,
1848        },
1849
1850        .generic_bulk_ctrl_endpoint = 0x01,
1851        .num_device_descs = 1,
1852        .devices = {
1853                {   "DViCO FusionHDTV DVB-T USB (LGZ201)",
1854                        { &cxusb_table[DVICO_BLUEBIRD_LGZ201_COLD], NULL },
1855                        { &cxusb_table[DVICO_BLUEBIRD_LGZ201_WARM], NULL },
1856                },
1857        }
1858};
1859
1860static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
1861        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1862
1863        .usb_ctrl          = DEVICE_SPECIFIC,
1864        .firmware          = "dvb-usb-bluebird-01.fw",
1865        .download_firmware = bluebird_patch_dvico_firmware_download,
1866        /* use usb alt setting 0 for EP4 transfer (dvb-t),
1867           use usb alt setting 7 for EP2 transfer (atsc) */
1868
1869        .size_of_priv     = sizeof(struct cxusb_state),
1870
1871        .num_adapters = 1,
1872        .adapter = {
1873                {
1874                .num_frontends = 1,
1875                .fe = {{
1876                        .streaming_ctrl   = cxusb_streaming_ctrl,
1877                        .frontend_attach  = cxusb_mt352_frontend_attach,
1878                        .tuner_attach     = cxusb_dtt7579_tuner_attach,
1879
1880                        /* parameter for the MPEG2-data transfer */
1881                        .stream = {
1882                                .type = USB_BULK,
1883                                .count = 5,
1884                                .endpoint = 0x04,
1885                                .u = {
1886                                        .bulk = {
1887                                                .buffersize = 8192,
1888                                        }
1889                                }
1890                        },
1891                }},
1892                },
1893        },
1894        .power_ctrl       = cxusb_bluebird_power_ctrl,
1895
1896        .i2c_algo         = &cxusb_i2c_algo,
1897
1898        .rc.legacy = {
1899                .rc_interval      = 100,
1900                .rc_map_table     = rc_map_dvico_portable_table,
1901                .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
1902                .rc_query         = cxusb_rc_query,
1903        },
1904
1905        .generic_bulk_ctrl_endpoint = 0x01,
1906
1907        .num_device_descs = 1,
1908        .devices = {
1909                {   "DViCO FusionHDTV DVB-T USB (TH7579)",
1910                        { &cxusb_table[DVICO_BLUEBIRD_TH7579_COLD], NULL },
1911                        { &cxusb_table[DVICO_BLUEBIRD_TH7579_WARM], NULL },
1912                },
1913        }
1914};
1915
1916static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1917        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1918
1919        .usb_ctrl         = CYPRESS_FX2,
1920
1921        .size_of_priv     = sizeof(struct cxusb_state),
1922
1923        .num_adapters = 1,
1924        .adapter = {
1925                {
1926                .num_frontends = 1,
1927                .fe = {{
1928                        .streaming_ctrl   = cxusb_streaming_ctrl,
1929                        .frontend_attach  = cxusb_dualdig4_frontend_attach,
1930                        .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
1931                        /* parameter for the MPEG2-data transfer */
1932                        .stream = {
1933                                .type = USB_BULK,
1934                                .count = 5,
1935                                .endpoint = 0x02,
1936                                .u = {
1937                                        .bulk = {
1938                                                .buffersize = 8192,
1939                                        }
1940                                }
1941                        },
1942                }},
1943                },
1944        },
1945
1946        .power_ctrl       = cxusb_power_ctrl,
1947
1948        .i2c_algo         = &cxusb_i2c_algo,
1949
1950        .generic_bulk_ctrl_endpoint = 0x01,
1951
1952        .rc.legacy = {
1953                .rc_interval      = 100,
1954                .rc_map_table     = rc_map_dvico_mce_table,
1955                .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
1956                .rc_query         = cxusb_bluebird2_rc_query,
1957        },
1958
1959        .num_device_descs = 1,
1960        .devices = {
1961                {   "DViCO FusionHDTV DVB-T Dual Digital 4",
1962                        { NULL },
1963                        { &cxusb_table[DVICO_BLUEBIRD_DUAL_4], NULL },
1964                },
1965        }
1966};
1967
1968static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1969        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1970
1971        .usb_ctrl         = CYPRESS_FX2,
1972        .identify_state   = bluebird_fx2_identify_state,
1973
1974        .size_of_priv     = sizeof(struct cxusb_state),
1975
1976        .num_adapters = 1,
1977        .adapter = {
1978                {
1979                .num_frontends = 1,
1980                .fe = {{
1981                        .streaming_ctrl   = cxusb_streaming_ctrl,
1982                        .frontend_attach  = cxusb_nano2_frontend_attach,
1983                        .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
1984                        /* parameter for the MPEG2-data transfer */
1985                        .stream = {
1986                                .type = USB_BULK,
1987                                .count = 5,
1988                                .endpoint = 0x02,
1989                                .u = {
1990                                        .bulk = {
1991                                                .buffersize = 8192,
1992                                        }
1993                                }
1994                        },
1995                }},
1996                },
1997        },
1998
1999        .power_ctrl       = cxusb_nano2_power_ctrl,
2000
2001        .i2c_algo         = &cxusb_i2c_algo,
2002
2003        .generic_bulk_ctrl_endpoint = 0x01,
2004
2005        .rc.legacy = {
2006                .rc_interval      = 100,
2007                .rc_map_table     = rc_map_dvico_portable_table,
2008                .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
2009                .rc_query         = cxusb_bluebird2_rc_query,
2010        },
2011
2012        .num_device_descs = 1,
2013        .devices = {
2014                {   "DViCO FusionHDTV DVB-T NANO2",
2015                        { NULL },
2016                        { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL },
2017                },
2018        }
2019};
2020
2021static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
2022        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2023
2024        .usb_ctrl          = DEVICE_SPECIFIC,
2025        .firmware          = "dvb-usb-bluebird-02.fw",
2026        .download_firmware = bluebird_patch_dvico_firmware_download,
2027        .identify_state    = bluebird_fx2_identify_state,
2028
2029        .size_of_priv      = sizeof(struct cxusb_state),
2030
2031        .num_adapters = 1,
2032        .adapter = {
2033                {
2034                .num_frontends = 1,
2035                .fe = {{
2036                        .streaming_ctrl   = cxusb_streaming_ctrl,
2037                        .frontend_attach  = cxusb_nano2_frontend_attach,
2038                        .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
2039                        /* parameter for the MPEG2-data transfer */
2040                        .stream = {
2041                                .type = USB_BULK,
2042                                .count = 5,
2043                                .endpoint = 0x02,
2044                                .u = {
2045                                        .bulk = {
2046                                                .buffersize = 8192,
2047                                        }
2048                                }
2049                        },
2050                }},
2051                },
2052        },
2053
2054        .power_ctrl       = cxusb_nano2_power_ctrl,
2055
2056        .i2c_algo         = &cxusb_i2c_algo,
2057
2058        .generic_bulk_ctrl_endpoint = 0x01,
2059
2060        .rc.legacy = {
2061                .rc_interval      = 100,
2062                .rc_map_table     = rc_map_dvico_portable_table,
2063                .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
2064                .rc_query         = cxusb_rc_query,
2065        },
2066
2067        .num_device_descs = 1,
2068        .devices = {
2069                {   "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
2070                        { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL },
2071                        { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM], NULL },
2072                },
2073        }
2074};
2075
2076static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
2077        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2078
2079        .usb_ctrl         = CYPRESS_FX2,
2080
2081        .size_of_priv     = sizeof(struct cxusb_state),
2082
2083        .num_adapters = 1,
2084        .adapter = {
2085                {
2086                .num_frontends = 1,
2087                .fe = {{
2088                        .streaming_ctrl   = cxusb_aver_streaming_ctrl,
2089                        .frontend_attach  = cxusb_aver_lgdt3303_frontend_attach,
2090                        .tuner_attach     = cxusb_mxl5003s_tuner_attach,
2091                        /* parameter for the MPEG2-data transfer */
2092                        .stream = {
2093                                .type = USB_BULK,
2094                                .count = 5,
2095                                .endpoint = 0x04,
2096                                .u = {
2097                                        .bulk = {
2098                                                .buffersize = 8192,
2099                                        }
2100                                }
2101                        },
2102                }},
2103                },
2104        },
2105        .power_ctrl       = cxusb_aver_power_ctrl,
2106
2107        .i2c_algo         = &cxusb_i2c_algo,
2108
2109        .generic_bulk_ctrl_endpoint = 0x01,
2110
2111        .num_device_descs = 1,
2112        .devices = {
2113                {   "AVerMedia AVerTVHD Volar (A868R)",
2114                        { NULL },
2115                        { &cxusb_table[AVERMEDIA_VOLAR_A868R], NULL },
2116                },
2117        }
2118};
2119
2120static
2121struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
2122        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2123
2124        .usb_ctrl         = CYPRESS_FX2,
2125
2126        .size_of_priv     = sizeof(struct cxusb_state),
2127
2128        .num_adapters = 1,
2129        .adapter = {
2130                {
2131                .size_of_priv    = sizeof(struct dib0700_adapter_state),
2132                .num_frontends = 1,
2133                .fe = {{
2134                        .streaming_ctrl  = cxusb_streaming_ctrl,
2135                        .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
2136                        .tuner_attach    = cxusb_dualdig4_rev2_tuner_attach,
2137                        /* parameter for the MPEG2-data transfer */
2138                        .stream = {
2139                                .type = USB_BULK,
2140                                .count = 7,
2141                                .endpoint = 0x02,
2142                                .u = {
2143                                        .bulk = {
2144                                                .buffersize = 4096,
2145                                        }
2146                                }
2147                        },
2148                }},
2149                },
2150        },
2151
2152        .power_ctrl       = cxusb_bluebird_power_ctrl,
2153
2154        .i2c_algo         = &cxusb_i2c_algo,
2155
2156        .generic_bulk_ctrl_endpoint = 0x01,
2157
2158        .rc.legacy = {
2159                .rc_interval      = 100,
2160                .rc_map_table     = rc_map_dvico_mce_table,
2161                .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
2162                .rc_query         = cxusb_rc_query,
2163        },
2164
2165        .num_device_descs = 1,
2166        .devices = {
2167                {   "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
2168                        { NULL },
2169                        { &cxusb_table[DVICO_BLUEBIRD_DUAL_4_REV_2], NULL },
2170                },
2171        }
2172};
2173
2174static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
2175        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2176
2177        .usb_ctrl         = CYPRESS_FX2,
2178
2179        .size_of_priv     = sizeof(struct cxusb_state),
2180
2181        .num_adapters = 1,
2182        .adapter = {
2183                {
2184                .num_frontends = 1,
2185                .fe = {{
2186                        .streaming_ctrl   = cxusb_d680_dmb_streaming_ctrl,
2187                        .frontend_attach  = cxusb_d680_dmb_frontend_attach,
2188                        .tuner_attach     = cxusb_d680_dmb_tuner_attach,
2189
2190                        /* parameter for the MPEG2-data transfer */
2191                        .stream = {
2192                                .type = USB_BULK,
2193                                .count = 5,
2194                                .endpoint = 0x02,
2195                                .u = {
2196                                        .bulk = {
2197                                                .buffersize = 8192,
2198                                        }
2199                                }
2200                        },
2201                }},
2202                },
2203        },
2204
2205        .power_ctrl       = cxusb_d680_dmb_power_ctrl,
2206
2207        .i2c_algo         = &cxusb_i2c_algo,
2208
2209        .generic_bulk_ctrl_endpoint = 0x01,
2210
2211        .rc.legacy = {
2212                .rc_interval      = 100,
2213                .rc_map_table     = rc_map_d680_dmb_table,
2214                .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
2215                .rc_query         = cxusb_d680_dmb_rc_query,
2216        },
2217
2218        .num_device_descs = 1,
2219        .devices = {
2220                {
2221                        "Conexant DMB-TH Stick",
2222                        { NULL },
2223                        { &cxusb_table[CONEXANT_D680_DMB], NULL },
2224                },
2225        }
2226};
2227
2228static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
2229        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2230
2231        .usb_ctrl         = CYPRESS_FX2,
2232
2233        .size_of_priv     = sizeof(struct cxusb_state),
2234
2235        .num_adapters = 1,
2236        .adapter = {
2237                {
2238                .num_frontends = 1,
2239                .fe = {{
2240                        .streaming_ctrl   = cxusb_d680_dmb_streaming_ctrl,
2241                        .frontend_attach  = cxusb_mygica_d689_frontend_attach,
2242                        .tuner_attach     = cxusb_mygica_d689_tuner_attach,
2243
2244                        /* parameter for the MPEG2-data transfer */
2245                        .stream = {
2246                                .type = USB_BULK,
2247                                .count = 5,
2248                                .endpoint = 0x02,
2249                                .u = {
2250                                        .bulk = {
2251                                                .buffersize = 8192,
2252                                        }
2253                                }
2254                        },
2255                }},
2256                },
2257        },
2258
2259        .power_ctrl       = cxusb_d680_dmb_power_ctrl,
2260
2261        .i2c_algo         = &cxusb_i2c_algo,
2262
2263        .generic_bulk_ctrl_endpoint = 0x01,
2264
2265        .rc.legacy = {
2266                .rc_interval      = 100,
2267                .rc_map_table     = rc_map_d680_dmb_table,
2268                .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
2269                .rc_query         = cxusb_d680_dmb_rc_query,
2270        },
2271
2272        .num_device_descs = 1,
2273        .devices = {
2274                {
2275                        "Mygica D689 DMB-TH",
2276                        { NULL },
2277                        { &cxusb_table[MYGICA_D689], NULL },
2278                },
2279        }
2280};
2281
2282static struct dvb_usb_device_properties cxusb_mygica_t230_properties = {
2283        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2284
2285        .usb_ctrl         = CYPRESS_FX2,
2286
2287        .size_of_priv     = sizeof(struct cxusb_state),
2288
2289        .num_adapters = 1,
2290        .adapter = {
2291                {
2292                .num_frontends = 1,
2293                .fe = {{
2294                        .streaming_ctrl   = cxusb_streaming_ctrl,
2295                        .frontend_attach  = cxusb_mygica_t230_frontend_attach,
2296
2297                        /* parameter for the MPEG2-data transfer */
2298                        .stream = {
2299                                .type = USB_BULK,
2300                                .count = 5,
2301                                .endpoint = 0x02,
2302                                .u = {
2303                                        .bulk = {
2304                                                .buffersize = 8192,
2305                                        }
2306                                }
2307                        },
2308                } },
2309                },
2310        },
2311
2312        .power_ctrl       = cxusb_d680_dmb_power_ctrl,
2313
2314        .i2c_algo         = &cxusb_i2c_algo,
2315
2316        .generic_bulk_ctrl_endpoint = 0x01,
2317
2318        .rc.legacy = {
2319                .rc_interval      = 100,
2320                .rc_map_table     = rc_map_d680_dmb_table,
2321                .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
2322                .rc_query         = cxusb_d680_dmb_rc_query,
2323        },
2324
2325        .num_device_descs = 1,
2326        .devices = {
2327                {
2328                        "Mygica T230 DVB-T/T2/C",
2329                        { NULL },
2330                        { &cxusb_table[MYGICA_T230], NULL },
2331                },
2332        }
2333};
2334
2335static struct usb_driver cxusb_driver = {
2336        .name           = "dvb_usb_cxusb",
2337        .probe          = cxusb_probe,
2338        .disconnect     = cxusb_disconnect,
2339        .id_table       = cxusb_table,
2340};
2341
2342module_usb_driver(cxusb_driver);
2343
2344MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2345MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
2346MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
2347MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
2348MODULE_VERSION("1.0-alpha");
2349MODULE_LICENSE("GPL");
2350