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