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