linux/drivers/media/dvb/dvb-usb/dw2102.c
<<
>>
Prefs
   1/* DVB USB framework compliant Linux driver for the
   2*       DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
   3*       TeVii S600, S630, S650 Cards
   4* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
   5*
   6*       This program is free software; you can redistribute it and/or modify it
   7*       under the terms of the GNU General Public License as published by the
   8*       Free Software Foundation, version 2.
   9*
  10* see Documentation/dvb/README.dvb-usb for more information
  11*/
  12#include "dw2102.h"
  13#include "si21xx.h"
  14#include "stv0299.h"
  15#include "z0194a.h"
  16#include "stv0288.h"
  17#include "stb6000.h"
  18#include "eds1547.h"
  19#include "cx24116.h"
  20#include "tda1002x.h"
  21#include "mt312.h"
  22#include "zl10039.h"
  23
  24#ifndef USB_PID_DW2102
  25#define USB_PID_DW2102 0x2102
  26#endif
  27
  28#ifndef USB_PID_DW2104
  29#define USB_PID_DW2104 0x2104
  30#endif
  31
  32#ifndef USB_PID_DW3101
  33#define USB_PID_DW3101 0x3101
  34#endif
  35
  36#ifndef USB_PID_CINERGY_S
  37#define USB_PID_CINERGY_S 0x0064
  38#endif
  39
  40#ifndef USB_PID_TEVII_S650
  41#define USB_PID_TEVII_S650 0xd650
  42#endif
  43
  44#ifndef USB_PID_TEVII_S630
  45#define USB_PID_TEVII_S630 0xd630
  46#endif
  47
  48#define DW210X_READ_MSG 0
  49#define DW210X_WRITE_MSG 1
  50
  51#define REG_1F_SYMBOLRATE_BYTE0 0x1f
  52#define REG_20_SYMBOLRATE_BYTE1 0x20
  53#define REG_21_SYMBOLRATE_BYTE2 0x21
  54/* on my own*/
  55#define DW2102_VOLTAGE_CTRL (0x1800)
  56#define DW2102_RC_QUERY (0x1a00)
  57
  58struct dvb_usb_rc_keys_table {
  59        struct dvb_usb_rc_key *rc_keys;
  60        int rc_keys_size;
  61};
  62
  63/* debug */
  64static int dvb_usb_dw2102_debug;
  65module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
  66MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
  67                                                DVB_USB_DEBUG_STATUS);
  68
  69/* keymaps */
  70static int ir_keymap;
  71module_param_named(keymap, ir_keymap, int, 0644);
  72MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ...");
  73
  74DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  75
  76static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
  77                        u16 index, u8 * data, u16 len, int flags)
  78{
  79        int ret;
  80        u8 u8buf[len];
  81
  82        unsigned int pipe = (flags == DW210X_READ_MSG) ?
  83                                usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
  84        u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
  85
  86        if (flags == DW210X_WRITE_MSG)
  87                memcpy(u8buf, data, len);
  88        ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
  89                                value, index , u8buf, len, 2000);
  90
  91        if (flags == DW210X_READ_MSG)
  92                memcpy(data, u8buf, len);
  93        return ret;
  94}
  95
  96/* I2C */
  97static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
  98                int num)
  99{
 100        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 101        int i = 0, ret = 0;
 102        u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
 103        u16 value;
 104
 105        if (!d)
 106                return -ENODEV;
 107        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 108                return -EAGAIN;
 109
 110        switch (num) {
 111        case 2:
 112                /* read stv0299 register */
 113                value = msg[0].buf[0];/* register */
 114                for (i = 0; i < msg[1].len; i++) {
 115                        value = value + i;
 116                        ret = dw210x_op_rw(d->udev, 0xb5, value, 0,
 117                                        buf6, 2, DW210X_READ_MSG);
 118                        msg[1].buf[i] = buf6[0];
 119                }
 120                break;
 121        case 1:
 122                switch (msg[0].addr) {
 123                case 0x68:
 124                        /* write to stv0299 register */
 125                        buf6[0] = 0x2a;
 126                        buf6[1] = msg[0].buf[0];
 127                        buf6[2] = msg[0].buf[1];
 128                        ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
 129                                        buf6, 3, DW210X_WRITE_MSG);
 130                        break;
 131                case 0x60:
 132                        if (msg[0].flags == 0) {
 133                        /* write to tuner pll */
 134                                buf6[0] = 0x2c;
 135                                buf6[1] = 5;
 136                                buf6[2] = 0xc0;
 137                                buf6[3] = msg[0].buf[0];
 138                                buf6[4] = msg[0].buf[1];
 139                                buf6[5] = msg[0].buf[2];
 140                                buf6[6] = msg[0].buf[3];
 141                                ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
 142                                                buf6, 7, DW210X_WRITE_MSG);
 143                        } else {
 144                        /* read from tuner */
 145                                ret = dw210x_op_rw(d->udev, 0xb5, 0, 0,
 146                                                buf6, 1, DW210X_READ_MSG);
 147                                msg[0].buf[0] = buf6[0];
 148                        }
 149                        break;
 150                case (DW2102_RC_QUERY):
 151                        ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
 152                                        buf6, 2, DW210X_READ_MSG);
 153                        msg[0].buf[0] = buf6[0];
 154                        msg[0].buf[1] = buf6[1];
 155                        break;
 156                case (DW2102_VOLTAGE_CTRL):
 157                        buf6[0] = 0x30;
 158                        buf6[1] = msg[0].buf[0];
 159                        ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
 160                                        buf6, 2, DW210X_WRITE_MSG);
 161                        break;
 162                }
 163
 164                break;
 165        }
 166
 167        mutex_unlock(&d->i2c_mutex);
 168        return num;
 169}
 170
 171static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
 172                                                struct i2c_msg msg[], int num)
 173{
 174        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 175        int ret = 0;
 176        u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
 177
 178        if (!d)
 179                return -ENODEV;
 180        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 181                return -EAGAIN;
 182
 183        switch (num) {
 184        case 2:
 185                /* read si2109 register by number */
 186                buf6[0] = 0xd0;
 187                buf6[1] = msg[0].len;
 188                buf6[2] = msg[0].buf[0];
 189                ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
 190                                buf6, msg[0].len + 2, DW210X_WRITE_MSG);
 191                /* read si2109 register */
 192                ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
 193                                buf6, msg[1].len + 2, DW210X_READ_MSG);
 194                memcpy(msg[1].buf, buf6 + 2, msg[1].len);
 195
 196                break;
 197        case 1:
 198                switch (msg[0].addr) {
 199                case 0x68:
 200                        /* write to si2109 register */
 201                        buf6[0] = 0xd0;
 202                        buf6[1] = msg[0].len;
 203                        memcpy(buf6 + 2, msg[0].buf, msg[0].len);
 204                        ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
 205                                        msg[0].len + 2, DW210X_WRITE_MSG);
 206                        break;
 207                case(DW2102_RC_QUERY):
 208                        ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
 209                                        buf6, 2, DW210X_READ_MSG);
 210                        msg[0].buf[0] = buf6[0];
 211                        msg[0].buf[1] = buf6[1];
 212                        break;
 213                case(DW2102_VOLTAGE_CTRL):
 214                        buf6[0] = 0x30;
 215                        buf6[1] = msg[0].buf[0];
 216                        ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
 217                                        buf6, 2, DW210X_WRITE_MSG);
 218                        break;
 219                }
 220                break;
 221        }
 222
 223        mutex_unlock(&d->i2c_mutex);
 224        return num;
 225}
 226
 227static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
 228{
 229        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 230        int ret = 0;
 231
 232        if (!d)
 233                return -ENODEV;
 234        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 235                return -EAGAIN;
 236
 237        switch (num) {
 238        case 2: {
 239                /* read */
 240                /* first write first register number */
 241                u8 ibuf[msg[1].len + 2], obuf[3];
 242                obuf[0] = 0xd0;
 243                obuf[1] = msg[0].len;
 244                obuf[2] = msg[0].buf[0];
 245                ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
 246                                obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 247                /* second read registers */
 248                ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
 249                                ibuf, msg[1].len + 2, DW210X_READ_MSG);
 250                memcpy(msg[1].buf, ibuf + 2, msg[1].len);
 251
 252                break;
 253        }
 254        case 1:
 255                switch (msg[0].addr) {
 256                case 0x68: {
 257                        /* write to register */
 258                        u8 obuf[msg[0].len + 2];
 259                        obuf[0] = 0xd0;
 260                        obuf[1] = msg[0].len;
 261                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
 262                        ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
 263                                        obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 264                        break;
 265                }
 266                case 0x61: {
 267                        /* write to tuner */
 268                        u8 obuf[msg[0].len + 2];
 269                        obuf[0] = 0xc2;
 270                        obuf[1] = msg[0].len;
 271                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
 272                        ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
 273                                        obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 274                        break;
 275                }
 276                case(DW2102_RC_QUERY): {
 277                        u8 ibuf[2];
 278                        ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
 279                                        ibuf, 2, DW210X_READ_MSG);
 280                        memcpy(msg[0].buf, ibuf , 2);
 281                        break;
 282                }
 283                case(DW2102_VOLTAGE_CTRL): {
 284                        u8 obuf[2];
 285                        obuf[0] = 0x30;
 286                        obuf[1] = msg[0].buf[0];
 287                        ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
 288                                        obuf, 2, DW210X_WRITE_MSG);
 289                        break;
 290                }
 291                }
 292
 293                break;
 294        }
 295
 296        mutex_unlock(&d->i2c_mutex);
 297        return num;
 298}
 299
 300static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
 301{
 302        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 303        int ret = 0;
 304        int len, i;
 305
 306        if (!d)
 307                return -ENODEV;
 308        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 309                return -EAGAIN;
 310
 311        switch (num) {
 312        case 2: {
 313                /* read */
 314                /* first write first register number */
 315                u8 ibuf[msg[1].len + 2], obuf[3];
 316                obuf[0] = 0xaa;
 317                obuf[1] = msg[0].len;
 318                obuf[2] = msg[0].buf[0];
 319                ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
 320                                obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 321                /* second read registers */
 322                ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0,
 323                                ibuf, msg[1].len + 2, DW210X_READ_MSG);
 324                memcpy(msg[1].buf, ibuf + 2, msg[1].len);
 325
 326                break;
 327        }
 328        case 1:
 329                switch (msg[0].addr) {
 330                case 0x55: {
 331                        if (msg[0].buf[0] == 0xf7) {
 332                                /* firmware */
 333                                /* Write in small blocks */
 334                                u8 obuf[19];
 335                                obuf[0] = 0xaa;
 336                                obuf[1] = 0x11;
 337                                obuf[2] = 0xf7;
 338                                len = msg[0].len - 1;
 339                                i = 1;
 340                                do {
 341                                        memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len));
 342                                        ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
 343                                                obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG);
 344                                        i += 16;
 345                                        len -= 16;
 346                                } while (len > 0);
 347                        } else {
 348                                /* write to register */
 349                                u8 obuf[msg[0].len + 2];
 350                                obuf[0] = 0xaa;
 351                                obuf[1] = msg[0].len;
 352                                memcpy(obuf + 2, msg[0].buf, msg[0].len);
 353                                ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
 354                                                obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 355                        }
 356                        break;
 357                }
 358                case(DW2102_RC_QUERY): {
 359                        u8 ibuf[2];
 360                        ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
 361                                        ibuf, 2, DW210X_READ_MSG);
 362                        memcpy(msg[0].buf, ibuf , 2);
 363                        break;
 364                }
 365                case(DW2102_VOLTAGE_CTRL): {
 366                        u8 obuf[2];
 367                        obuf[0] = 0x30;
 368                        obuf[1] = msg[0].buf[0];
 369                        ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
 370                                        obuf, 2, DW210X_WRITE_MSG);
 371                        break;
 372                }
 373                }
 374
 375                break;
 376        }
 377
 378        mutex_unlock(&d->i2c_mutex);
 379        return num;
 380}
 381
 382static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 383                                                                int num)
 384{
 385        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 386        int ret = 0, i;
 387
 388        if (!d)
 389                return -ENODEV;
 390        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 391                return -EAGAIN;
 392
 393        switch (num) {
 394        case 2: {
 395                /* read */
 396                /* first write first register number */
 397                u8 ibuf[msg[1].len + 2], obuf[3];
 398                obuf[0] = msg[0].addr << 1;
 399                obuf[1] = msg[0].len;
 400                obuf[2] = msg[0].buf[0];
 401                ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
 402                                obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 403                /* second read registers */
 404                ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
 405                                ibuf, msg[1].len + 2, DW210X_READ_MSG);
 406                memcpy(msg[1].buf, ibuf + 2, msg[1].len);
 407
 408                break;
 409        }
 410        case 1:
 411                switch (msg[0].addr) {
 412                case 0x60:
 413                case 0x0c: {
 414                        /* write to register */
 415                        u8 obuf[msg[0].len + 2];
 416                        obuf[0] = msg[0].addr << 1;
 417                        obuf[1] = msg[0].len;
 418                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
 419                        ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
 420                                        obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 421                        break;
 422                }
 423                case(DW2102_RC_QUERY): {
 424                        u8 ibuf[2];
 425                        ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
 426                                        ibuf, 2, DW210X_READ_MSG);
 427                        memcpy(msg[0].buf, ibuf , 2);
 428                        break;
 429                }
 430                }
 431
 432                break;
 433        }
 434
 435        for (i = 0; i < num; i++) {
 436                deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
 437                                msg[i].flags == 0 ? ">>>" : "<<<");
 438                debug_dump(msg[i].buf, msg[i].len, deb_xfer);
 439        }
 440
 441        mutex_unlock(&d->i2c_mutex);
 442        return num;
 443}
 444
 445static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 446                                                                int num)
 447{
 448        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 449        int ret = 0;
 450
 451        if (!d)
 452                return -ENODEV;
 453        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 454                return -EAGAIN;
 455
 456        switch (num) {
 457        case 2: { /* read */
 458                u8 ibuf[msg[1].len], obuf[3];
 459                obuf[0] = msg[1].len;
 460                obuf[1] = (msg[0].addr << 1);
 461                obuf[2] = msg[0].buf[0];
 462
 463                ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
 464                                        obuf, 3, DW210X_WRITE_MSG);
 465                msleep(5);
 466                ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
 467                                        ibuf, msg[1].len, DW210X_READ_MSG);
 468                memcpy(msg[1].buf, ibuf, msg[1].len);
 469                break;
 470        }
 471        case 1:
 472                switch (msg[0].addr) {
 473                case 0x60:
 474                case 0x0e: {
 475                        /* write to zl10313, zl10039 register, */
 476                        u8 obuf[msg[0].len + 2];
 477                        obuf[0] = msg[0].len + 1;
 478                        obuf[1] = (msg[0].addr << 1);
 479                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
 480                        ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
 481                                        obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 482                        break;
 483                }
 484                case (DW2102_RC_QUERY): {
 485                        u8 ibuf[4];
 486                        ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
 487                                        ibuf, 4, DW210X_READ_MSG);
 488                        msg[0].buf[0] = ibuf[3];
 489                        break;
 490                }
 491                case (DW2102_VOLTAGE_CTRL): {
 492                        u8 obuf[2];
 493                        obuf[0] = 0x03;
 494                        obuf[1] = msg[0].buf[0];
 495                        ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
 496                                        obuf, 2, DW210X_WRITE_MSG);
 497                        break;
 498                }
 499                }
 500
 501                break;
 502        }
 503
 504        mutex_unlock(&d->i2c_mutex);
 505        return num;
 506}
 507
 508static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
 509{
 510        return I2C_FUNC_I2C;
 511}
 512
 513static struct i2c_algorithm dw2102_i2c_algo = {
 514        .master_xfer = dw2102_i2c_transfer,
 515        .functionality = dw210x_i2c_func,
 516};
 517
 518static struct i2c_algorithm dw2102_serit_i2c_algo = {
 519        .master_xfer = dw2102_serit_i2c_transfer,
 520        .functionality = dw210x_i2c_func,
 521};
 522
 523static struct i2c_algorithm dw2102_earda_i2c_algo = {
 524        .master_xfer = dw2102_earda_i2c_transfer,
 525        .functionality = dw210x_i2c_func,
 526};
 527
 528static struct i2c_algorithm dw2104_i2c_algo = {
 529        .master_xfer = dw2104_i2c_transfer,
 530        .functionality = dw210x_i2c_func,
 531};
 532
 533static struct i2c_algorithm dw3101_i2c_algo = {
 534        .master_xfer = dw3101_i2c_transfer,
 535        .functionality = dw210x_i2c_func,
 536};
 537
 538static struct i2c_algorithm s630_i2c_algo = {
 539        .master_xfer = s630_i2c_transfer,
 540        .functionality = dw210x_i2c_func,
 541};
 542
 543static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 544{
 545        int i;
 546        u8 ibuf[] = {0, 0};
 547        u8 eeprom[256], eepromline[16];
 548
 549        for (i = 0; i < 256; i++) {
 550                if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
 551                        err("read eeprom failed.");
 552                        return -1;
 553                } else {
 554                        eepromline[i%16] = ibuf[0];
 555                        eeprom[i] = ibuf[0];
 556                }
 557                if ((i % 16) == 15) {
 558                        deb_xfer("%02x: ", i - 15);
 559                        debug_dump(eepromline, 16, deb_xfer);
 560                }
 561        }
 562
 563        memcpy(mac, eeprom + 8, 6);
 564        return 0;
 565};
 566
 567static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 568{
 569        int i, ret;
 570        u8 buf[3], eeprom[256], eepromline[16];
 571
 572        for (i = 0; i < 256; i++) {
 573                buf[0] = 1;
 574                buf[1] = 0xa0;
 575                buf[2] = i;
 576                ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
 577                                        buf, 3, DW210X_WRITE_MSG);
 578                ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
 579                                        buf, 1, DW210X_READ_MSG);
 580                if (ret < 0) {
 581                        err("read eeprom failed.");
 582                        return -1;
 583                } else {
 584                        eepromline[i % 16] = buf[0];
 585                        eeprom[i] = buf[0];
 586                }
 587
 588                if ((i % 16) == 15) {
 589                        deb_xfer("%02x: ", i - 15);
 590                        debug_dump(eepromline, 16, deb_xfer);
 591                }
 592        }
 593
 594        memcpy(mac, eeprom + 16, 6);
 595        return 0;
 596};
 597
 598static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 599{
 600        static u8 command_13v[1] = {0x00};
 601        static u8 command_18v[1] = {0x01};
 602        struct i2c_msg msg[] = {
 603                {.addr = DW2102_VOLTAGE_CTRL, .flags = 0,
 604                        .buf = command_13v, .len = 1},
 605        };
 606
 607        struct dvb_usb_adapter *udev_adap =
 608                (struct dvb_usb_adapter *)(fe->dvb->priv);
 609        if (voltage == SEC_VOLTAGE_18)
 610                msg[0].buf = command_18v;
 611        i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
 612        return 0;
 613}
 614
 615static struct stv0299_config sharp_z0194a_config = {
 616        .demod_address = 0x68,
 617        .inittab = sharp_z0194a_inittab,
 618        .mclk = 88000000UL,
 619        .invert = 1,
 620        .skip_reinit = 0,
 621        .lock_output = STV0299_LOCKOUTPUT_1,
 622        .volt13_op0_op1 = STV0299_VOLT13_OP1,
 623        .min_delay_ms = 100,
 624        .set_symbol_rate = sharp_z0194a_set_symbol_rate,
 625};
 626
 627static struct cx24116_config dw2104_config = {
 628        .demod_address = 0x55,
 629        .mpg_clk_pos_pol = 0x01,
 630};
 631
 632static struct si21xx_config serit_sp1511lhb_config = {
 633        .demod_address = 0x68,
 634        .min_delay_ms = 100,
 635
 636};
 637
 638static struct tda10023_config dw3101_tda10023_config = {
 639        .demod_address = 0x0c,
 640        .invert = 1,
 641};
 642
 643static struct mt312_config zl313_config = {
 644        .demod_address = 0x0e,
 645};
 646
 647static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
 648{
 649        if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
 650                        &d->dev->i2c_adap)) != NULL) {
 651                d->fe->ops.set_voltage = dw210x_set_voltage;
 652                info("Attached cx24116!\n");
 653                return 0;
 654        }
 655        return -EIO;
 656}
 657
 658static struct dvb_usb_device_properties dw2102_properties;
 659static struct dvb_usb_device_properties dw2104_properties;
 660
 661static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
 662{
 663        if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
 664                /*dw2102_properties.adapter->tuner_attach = NULL;*/
 665                d->fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
 666                                        &d->dev->i2c_adap);
 667                if (d->fe != NULL) {
 668                        d->fe->ops.set_voltage = dw210x_set_voltage;
 669                        info("Attached si21xx!\n");
 670                        return 0;
 671                }
 672        }
 673        if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
 674                /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
 675                d->fe = dvb_attach(stv0288_attach, &earda_config,
 676                                        &d->dev->i2c_adap);
 677                if (d->fe != NULL) {
 678                        d->fe->ops.set_voltage = dw210x_set_voltage;
 679                        info("Attached stv0288!\n");
 680                        return 0;
 681                }
 682        }
 683
 684        if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
 685                /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
 686                d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
 687                                        &d->dev->i2c_adap);
 688                if (d->fe != NULL) {
 689                        d->fe->ops.set_voltage = dw210x_set_voltage;
 690                        info("Attached stv0299!\n");
 691                        return 0;
 692                }
 693        }
 694        return -EIO;
 695}
 696
 697static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
 698{
 699        d->fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
 700                                &d->dev->i2c_adap, 0x48);
 701        if (d->fe != NULL) {
 702                info("Attached tda10023!\n");
 703                return 0;
 704        }
 705        return -EIO;
 706}
 707
 708static int s630_frontend_attach(struct dvb_usb_adapter *d)
 709{
 710        d->fe = dvb_attach(mt312_attach, &zl313_config,
 711                                &d->dev->i2c_adap);
 712        if (d->fe != NULL) {
 713                d->fe->ops.set_voltage = dw210x_set_voltage;
 714                info("Attached zl10313!\n");
 715                return 0;
 716        }
 717        return -EIO;
 718}
 719
 720static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
 721{
 722        dvb_attach(dvb_pll_attach, adap->fe, 0x60,
 723                &adap->dev->i2c_adap, DVB_PLL_OPERA1);
 724        return 0;
 725}
 726
 727static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
 728{
 729        dvb_attach(stb6000_attach, adap->fe, 0x61,
 730                &adap->dev->i2c_adap);
 731
 732        return 0;
 733}
 734
 735static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
 736{
 737        dvb_attach(dvb_pll_attach, adap->fe, 0x60,
 738                &adap->dev->i2c_adap, DVB_PLL_TUA6034);
 739
 740        return 0;
 741}
 742
 743static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap)
 744{
 745        dvb_attach(zl10039_attach, adap->fe, 0x60,
 746                &adap->dev->i2c_adap);
 747
 748        return 0;
 749}
 750
 751static struct dvb_usb_rc_key dw210x_rc_keys[] = {
 752        { 0xf80a, KEY_Q },              /*power*/
 753        { 0xf80c, KEY_M },              /*mute*/
 754        { 0xf811, KEY_1 },
 755        { 0xf812, KEY_2 },
 756        { 0xf813, KEY_3 },
 757        { 0xf814, KEY_4 },
 758        { 0xf815, KEY_5 },
 759        { 0xf816, KEY_6 },
 760        { 0xf817, KEY_7 },
 761        { 0xf818, KEY_8 },
 762        { 0xf819, KEY_9 },
 763        { 0xf810, KEY_0 },
 764        { 0xf81c, KEY_PAGEUP }, /*ch+*/
 765        { 0xf80f, KEY_PAGEDOWN },       /*ch-*/
 766        { 0xf81a, KEY_O },              /*vol+*/
 767        { 0xf80e, KEY_Z },              /*vol-*/
 768        { 0xf804, KEY_R },              /*rec*/
 769        { 0xf809, KEY_D },              /*fav*/
 770        { 0xf808, KEY_BACKSPACE },      /*rewind*/
 771        { 0xf807, KEY_A },              /*fast*/
 772        { 0xf80b, KEY_P },              /*pause*/
 773        { 0xf802, KEY_ESC },    /*cancel*/
 774        { 0xf803, KEY_G },              /*tab*/
 775        { 0xf800, KEY_UP },             /*up*/
 776        { 0xf81f, KEY_ENTER },  /*ok*/
 777        { 0xf801, KEY_DOWN },   /*down*/
 778        { 0xf805, KEY_C },              /*cap*/
 779        { 0xf806, KEY_S },              /*stop*/
 780        { 0xf840, KEY_F },              /*full*/
 781        { 0xf81e, KEY_W },              /*tvmode*/
 782        { 0xf81b, KEY_B },              /*recall*/
 783};
 784
 785static struct dvb_usb_rc_key tevii_rc_keys[] = {
 786        { 0xf80a, KEY_POWER },
 787        { 0xf80c, KEY_MUTE },
 788        { 0xf811, KEY_1 },
 789        { 0xf812, KEY_2 },
 790        { 0xf813, KEY_3 },
 791        { 0xf814, KEY_4 },
 792        { 0xf815, KEY_5 },
 793        { 0xf816, KEY_6 },
 794        { 0xf817, KEY_7 },
 795        { 0xf818, KEY_8 },
 796        { 0xf819, KEY_9 },
 797        { 0xf810, KEY_0 },
 798        { 0xf81c, KEY_MENU },
 799        { 0xf80f, KEY_VOLUMEDOWN },
 800        { 0xf81a, KEY_LAST },
 801        { 0xf80e, KEY_OPEN },
 802        { 0xf804, KEY_RECORD },
 803        { 0xf809, KEY_VOLUMEUP },
 804        { 0xf808, KEY_CHANNELUP },
 805        { 0xf807, KEY_PVR },
 806        { 0xf80b, KEY_TIME },
 807        { 0xf802, KEY_RIGHT },
 808        { 0xf803, KEY_LEFT },
 809        { 0xf800, KEY_UP },
 810        { 0xf81f, KEY_OK },
 811        { 0xf801, KEY_DOWN },
 812        { 0xf805, KEY_TUNER },
 813        { 0xf806, KEY_CHANNELDOWN },
 814        { 0xf840, KEY_PLAYPAUSE },
 815        { 0xf81e, KEY_REWIND },
 816        { 0xf81b, KEY_FAVORITES },
 817        { 0xf81d, KEY_BACK },
 818        { 0xf84d, KEY_FASTFORWARD },
 819        { 0xf844, KEY_EPG },
 820        { 0xf84c, KEY_INFO },
 821        { 0xf841, KEY_AB },
 822        { 0xf843, KEY_AUDIO },
 823        { 0xf845, KEY_SUBTITLE },
 824        { 0xf84a, KEY_LIST },
 825        { 0xf846, KEY_F1 },
 826        { 0xf847, KEY_F2 },
 827        { 0xf85e, KEY_F3 },
 828        { 0xf85c, KEY_F4 },
 829        { 0xf852, KEY_F5 },
 830        { 0xf85a, KEY_F6 },
 831        { 0xf856, KEY_MODE },
 832        { 0xf858, KEY_SWITCHVIDEOMODE },
 833};
 834
 835static struct dvb_usb_rc_key tbs_rc_keys[] = {
 836        { 0xf884, KEY_POWER },
 837        { 0xf894, KEY_MUTE },
 838        { 0xf887, KEY_1 },
 839        { 0xf886, KEY_2 },
 840        { 0xf885, KEY_3 },
 841        { 0xf88b, KEY_4 },
 842        { 0xf88a, KEY_5 },
 843        { 0xf889, KEY_6 },
 844        { 0xf88f, KEY_7 },
 845        { 0xf88e, KEY_8 },
 846        { 0xf88d, KEY_9 },
 847        { 0xf892, KEY_0 },
 848        { 0xf896, KEY_CHANNELUP },
 849        { 0xf891, KEY_CHANNELDOWN },
 850        { 0xf893, KEY_VOLUMEUP },
 851        { 0xf88c, KEY_VOLUMEDOWN },
 852        { 0xf883, KEY_RECORD },
 853        { 0xf898, KEY_PAUSE  },
 854        { 0xf899, KEY_OK },
 855        { 0xf89a, KEY_SHUFFLE },
 856        { 0xf881, KEY_UP },
 857        { 0xf890, KEY_LEFT },
 858        { 0xf882, KEY_RIGHT },
 859        { 0xf888, KEY_DOWN },
 860        { 0xf895, KEY_FAVORITES },
 861        { 0xf897, KEY_SUBTITLE },
 862        { 0xf89d, KEY_ZOOM },
 863        { 0xf89f, KEY_EXIT },
 864        { 0xf89e, KEY_MENU },
 865        { 0xf89c, KEY_EPG },
 866        { 0xf880, KEY_PREVIOUS },
 867        { 0xf89b, KEY_MODE }
 868};
 869
 870static struct dvb_usb_rc_keys_table keys_tables[] = {
 871        { dw210x_rc_keys, ARRAY_SIZE(dw210x_rc_keys) },
 872        { tevii_rc_keys, ARRAY_SIZE(tevii_rc_keys) },
 873        { tbs_rc_keys, ARRAY_SIZE(tbs_rc_keys) },
 874};
 875
 876static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 877{
 878        struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
 879        int keymap_size = d->props.rc_key_map_size;
 880        u8 key[2];
 881        struct i2c_msg msg = {
 882                .addr = DW2102_RC_QUERY,
 883                .flags = I2C_M_RD,
 884                .buf = key,
 885                .len = 2
 886        };
 887        int i;
 888        /* override keymap */
 889        if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
 890                keymap = keys_tables[ir_keymap - 1].rc_keys ;
 891                keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
 892        }
 893
 894        *state = REMOTE_NO_KEY_PRESSED;
 895        if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
 896                for (i = 0; i < keymap_size ; i++) {
 897                        if (rc5_data(&keymap[i]) == msg.buf[0]) {
 898                                *state = REMOTE_KEY_PRESSED;
 899                                *event = keymap[i].event;
 900                                break;
 901                        }
 902
 903                }
 904
 905                if ((*state) == REMOTE_KEY_PRESSED)
 906                        deb_rc("%s: found rc key: %x, %x, event: %x\n",
 907                                        __func__, key[0], key[1], (*event));
 908                else if (key[0] != 0xff)
 909                        deb_rc("%s: unknown rc key: %x, %x\n",
 910                                        __func__, key[0], key[1]);
 911
 912        }
 913
 914        return 0;
 915}
 916
 917static struct usb_device_id dw2102_table[] = {
 918        {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
 919        {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
 920        {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
 921        {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
 922        {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
 923        {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
 924        {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
 925        { }
 926};
 927
 928MODULE_DEVICE_TABLE(usb, dw2102_table);
 929
 930static int dw2102_load_firmware(struct usb_device *dev,
 931                        const struct firmware *frmwr)
 932{
 933        u8 *b, *p;
 934        int ret = 0, i;
 935        u8 reset;
 936        u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
 937        const struct firmware *fw;
 938        const char *filename = "dvb-usb-dw2101.fw";
 939
 940        switch (dev->descriptor.idProduct) {
 941        case 0x2101:
 942                ret = request_firmware(&fw, filename, &dev->dev);
 943                if (ret != 0) {
 944                        err("did not find the firmware file. (%s) "
 945                        "Please see linux/Documentation/dvb/ for more details "
 946                        "on firmware-problems.", filename);
 947                        return ret;
 948                }
 949                break;
 950        default:
 951                fw = frmwr;
 952                break;
 953        }
 954        info("start downloading DW210X firmware");
 955        p = kmalloc(fw->size, GFP_KERNEL);
 956        reset = 1;
 957        /*stop the CPU*/
 958        dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
 959        dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
 960
 961        if (p != NULL) {
 962                memcpy(p, fw->data, fw->size);
 963                for (i = 0; i < fw->size; i += 0x40) {
 964                        b = (u8 *) p + i;
 965                        if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
 966                                        DW210X_WRITE_MSG) != 0x40) {
 967                                err("error while transferring firmware");
 968                                ret = -EINVAL;
 969                                break;
 970                        }
 971                }
 972                /* restart the CPU */
 973                reset = 0;
 974                if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
 975                                        DW210X_WRITE_MSG) != 1) {
 976                        err("could not restart the USB controller CPU.");
 977                        ret = -EINVAL;
 978                }
 979                if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
 980                                        DW210X_WRITE_MSG) != 1) {
 981                        err("could not restart the USB controller CPU.");
 982                        ret = -EINVAL;
 983                }
 984                /* init registers */
 985                switch (dev->descriptor.idProduct) {
 986                case USB_PID_TEVII_S650:
 987                        dw2104_properties.rc_key_map = tevii_rc_keys;
 988                        dw2104_properties.rc_key_map_size =
 989                                        ARRAY_SIZE(tevii_rc_keys);
 990                case USB_PID_DW2104:
 991                        reset = 1;
 992                        dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
 993                                        DW210X_WRITE_MSG);
 994                        /* break omitted intentionally */
 995                case USB_PID_DW3101:
 996                        reset = 0;
 997                        dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
 998                                        DW210X_WRITE_MSG);
 999                        break;
1000                case USB_PID_CINERGY_S:
1001                case USB_PID_DW2102:
1002                        dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1003                                        DW210X_WRITE_MSG);
1004                        dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1005                                        DW210X_READ_MSG);
1006                        /* check STV0299 frontend  */
1007                        dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
1008                                        DW210X_READ_MSG);
1009                        if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
1010                                dw2102_properties.i2c_algo = &dw2102_i2c_algo;
1011                                dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach;
1012                                break;
1013                        } else {
1014                                /* check STV0288 frontend  */
1015                                reset16[0] = 0xd0;
1016                                reset16[1] = 1;
1017                                reset16[2] = 0;
1018                                dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
1019                                                DW210X_WRITE_MSG);
1020                                dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
1021                                                DW210X_READ_MSG);
1022                                if (reset16[2] == 0x11) {
1023                                        dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
1024                                        dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
1025                                        break;
1026                                }
1027                        }
1028                case 0x2101:
1029                        dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
1030                                        DW210X_READ_MSG);
1031                        dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1032                                        DW210X_READ_MSG);
1033                        dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1034                                        DW210X_READ_MSG);
1035                        dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1036                                        DW210X_READ_MSG);
1037                        break;
1038                }
1039
1040                msleep(100);
1041                kfree(p);
1042        }
1043        return ret;
1044}
1045
1046static struct dvb_usb_device_properties dw2102_properties = {
1047        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1048        .usb_ctrl = DEVICE_SPECIFIC,
1049        .firmware = "dvb-usb-dw2102.fw",
1050        .no_reconnect = 1,
1051
1052        .i2c_algo = &dw2102_serit_i2c_algo,
1053        .rc_key_map = dw210x_rc_keys,
1054        .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
1055        .rc_interval = 150,
1056        .rc_query = dw2102_rc_query,
1057
1058        .generic_bulk_ctrl_endpoint = 0x81,
1059        /* parameter for the MPEG2-data transfer */
1060        .num_adapters = 1,
1061        .download_firmware = dw2102_load_firmware,
1062        .read_mac_address = dw210x_read_mac_address,
1063        .adapter = {
1064                {
1065                        .frontend_attach = dw2102_frontend_attach,
1066                        .streaming_ctrl = NULL,
1067                        .tuner_attach = NULL,
1068                        .stream = {
1069                                .type = USB_BULK,
1070                                .count = 8,
1071                                .endpoint = 0x82,
1072                                .u = {
1073                                        .bulk = {
1074                                                .buffersize = 4096,
1075                                        }
1076                                }
1077                        },
1078                }
1079        },
1080        .num_device_descs = 3,
1081        .devices = {
1082                {"DVBWorld DVB-S 2102 USB2.0",
1083                        {&dw2102_table[0], NULL},
1084                        {NULL},
1085                },
1086                {"DVBWorld DVB-S 2101 USB2.0",
1087                        {&dw2102_table[1], NULL},
1088                        {NULL},
1089                },
1090                {"TerraTec Cinergy S USB",
1091                        {&dw2102_table[4], NULL},
1092                        {NULL},
1093                },
1094        }
1095};
1096
1097static struct dvb_usb_device_properties dw2104_properties = {
1098        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1099        .usb_ctrl = DEVICE_SPECIFIC,
1100        .firmware = "dvb-usb-dw2104.fw",
1101        .no_reconnect = 1,
1102
1103        .i2c_algo = &dw2104_i2c_algo,
1104        .rc_key_map = dw210x_rc_keys,
1105        .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
1106        .rc_interval = 150,
1107        .rc_query = dw2102_rc_query,
1108
1109        .generic_bulk_ctrl_endpoint = 0x81,
1110        /* parameter for the MPEG2-data transfer */
1111        .num_adapters = 1,
1112        .download_firmware = dw2102_load_firmware,
1113        .read_mac_address = dw210x_read_mac_address,
1114        .adapter = {
1115                {
1116                        .frontend_attach = dw2104_frontend_attach,
1117                        .streaming_ctrl = NULL,
1118                        /*.tuner_attach = dw2104_tuner_attach,*/
1119                        .stream = {
1120                                .type = USB_BULK,
1121                                .count = 8,
1122                                .endpoint = 0x82,
1123                                .u = {
1124                                        .bulk = {
1125                                                .buffersize = 4096,
1126                                        }
1127                                }
1128                        },
1129                }
1130        },
1131        .num_device_descs = 2,
1132        .devices = {
1133                { "DVBWorld DW2104 USB2.0",
1134                        {&dw2102_table[2], NULL},
1135                        {NULL},
1136                },
1137                { "TeVii S650 USB2.0",
1138                        {&dw2102_table[3], NULL},
1139                        {NULL},
1140                },
1141        }
1142};
1143
1144static struct dvb_usb_device_properties dw3101_properties = {
1145        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1146        .usb_ctrl = DEVICE_SPECIFIC,
1147        .firmware = "dvb-usb-dw3101.fw",
1148        .no_reconnect = 1,
1149
1150        .i2c_algo = &dw3101_i2c_algo,
1151        .rc_key_map = dw210x_rc_keys,
1152        .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
1153        .rc_interval = 150,
1154        .rc_query = dw2102_rc_query,
1155
1156        .generic_bulk_ctrl_endpoint = 0x81,
1157        /* parameter for the MPEG2-data transfer */
1158        .num_adapters = 1,
1159        .download_firmware = dw2102_load_firmware,
1160        .read_mac_address = dw210x_read_mac_address,
1161        .adapter = {
1162                {
1163                        .frontend_attach = dw3101_frontend_attach,
1164                        .streaming_ctrl = NULL,
1165                        .tuner_attach = dw3101_tuner_attach,
1166                        .stream = {
1167                                .type = USB_BULK,
1168                                .count = 8,
1169                                .endpoint = 0x82,
1170                                .u = {
1171                                        .bulk = {
1172                                                .buffersize = 4096,
1173                                        }
1174                                }
1175                        },
1176                }
1177        },
1178        .num_device_descs = 1,
1179        .devices = {
1180                { "DVBWorld DVB-C 3101 USB2.0",
1181                        {&dw2102_table[5], NULL},
1182                        {NULL},
1183                },
1184        }
1185};
1186
1187static struct dvb_usb_device_properties s630_properties = {
1188        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1189        .usb_ctrl = DEVICE_SPECIFIC,
1190        .firmware = "dvb-usb-s630.fw",
1191        .no_reconnect = 1,
1192
1193        .i2c_algo = &s630_i2c_algo,
1194        .rc_key_map = tevii_rc_keys,
1195        .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys),
1196        .rc_interval = 150,
1197        .rc_query = dw2102_rc_query,
1198
1199        .generic_bulk_ctrl_endpoint = 0x81,
1200        .num_adapters = 1,
1201        .download_firmware = dw2102_load_firmware,
1202        .read_mac_address = s630_read_mac_address,
1203        .adapter = {
1204                {
1205                        .frontend_attach = s630_frontend_attach,
1206                        .streaming_ctrl = NULL,
1207                        .tuner_attach = s630_zl10039_tuner_attach,
1208                        .stream = {
1209                                .type = USB_BULK,
1210                                .count = 8,
1211                                .endpoint = 0x82,
1212                                .u = {
1213                                        .bulk = {
1214                                                .buffersize = 4096,
1215                                        }
1216                                }
1217                        },
1218                }
1219        },
1220        .num_device_descs = 1,
1221        .devices = {
1222                {"TeVii S630 USB",
1223                        {&dw2102_table[6], NULL},
1224                        {NULL},
1225                },
1226        }
1227};
1228
1229static int dw2102_probe(struct usb_interface *intf,
1230                const struct usb_device_id *id)
1231{
1232        if (0 == dvb_usb_device_init(intf, &dw2102_properties,
1233                        THIS_MODULE, NULL, adapter_nr) ||
1234            0 == dvb_usb_device_init(intf, &dw2104_properties,
1235                        THIS_MODULE, NULL, adapter_nr) ||
1236            0 == dvb_usb_device_init(intf, &dw3101_properties,
1237                        THIS_MODULE, NULL, adapter_nr) ||
1238            0 == dvb_usb_device_init(intf, &s630_properties,
1239                        THIS_MODULE, NULL, adapter_nr)) {
1240                return 0;
1241        }
1242        return -ENODEV;
1243}
1244
1245static struct usb_driver dw2102_driver = {
1246        .name = "dw2102",
1247        .probe = dw2102_probe,
1248        .disconnect = dvb_usb_device_exit,
1249        .id_table = dw2102_table,
1250};
1251
1252static int __init dw2102_module_init(void)
1253{
1254        int ret =  usb_register(&dw2102_driver);
1255        if (ret)
1256                err("usb_register failed. Error number %d", ret);
1257
1258        return ret;
1259}
1260
1261static void __exit dw2102_module_exit(void)
1262{
1263        usb_deregister(&dw2102_driver);
1264}
1265
1266module_init(dw2102_module_init);
1267module_exit(dw2102_module_exit);
1268
1269MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1270MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1271                                " DVB-C 3101 USB2.0,"
1272                                " TeVii S600, S630, S650 USB2.0 devices");
1273MODULE_VERSION("0.1");
1274MODULE_LICENSE("GPL");
1275