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