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