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