linux/drivers/media/usb/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, S660, S480, S421, S632
   4 *      Prof 1100, 7500,
   5 *      Geniatech SU3000, T220 Cards
   6 * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by)
   7 *
   8 *      This program is free software; you can redistribute it and/or modify it
   9 *      under the terms of the GNU General Public License as published by the
  10 *      Free Software Foundation, version 2.
  11 *
  12 * see Documentation/dvb/README.dvb-usb for more information
  13 */
  14#include "dw2102.h"
  15#include "si21xx.h"
  16#include "stv0299.h"
  17#include "z0194a.h"
  18#include "stv0288.h"
  19#include "stb6000.h"
  20#include "eds1547.h"
  21#include "cx24116.h"
  22#include "tda1002x.h"
  23#include "mt312.h"
  24#include "zl10039.h"
  25#include "ts2020.h"
  26#include "ds3000.h"
  27#include "stv0900.h"
  28#include "stv6110.h"
  29#include "stb6100.h"
  30#include "stb6100_proc.h"
  31#include "m88rs2000.h"
  32#include "tda18271.h"
  33#include "cxd2820r.h"
  34
  35/* Max transfer size done by I2C transfer functions */
  36#define MAX_XFER_SIZE  64
  37
  38#ifndef USB_PID_DW2102
  39#define USB_PID_DW2102 0x2102
  40#endif
  41
  42#ifndef USB_PID_DW2104
  43#define USB_PID_DW2104 0x2104
  44#endif
  45
  46#ifndef USB_PID_DW3101
  47#define USB_PID_DW3101 0x3101
  48#endif
  49
  50#ifndef USB_PID_CINERGY_S
  51#define USB_PID_CINERGY_S 0x0064
  52#endif
  53
  54#ifndef USB_PID_TEVII_S630
  55#define USB_PID_TEVII_S630 0xd630
  56#endif
  57
  58#ifndef USB_PID_TEVII_S650
  59#define USB_PID_TEVII_S650 0xd650
  60#endif
  61
  62#ifndef USB_PID_TEVII_S660
  63#define USB_PID_TEVII_S660 0xd660
  64#endif
  65
  66#ifndef USB_PID_TEVII_S480_1
  67#define USB_PID_TEVII_S480_1 0xd481
  68#endif
  69
  70#ifndef USB_PID_TEVII_S480_2
  71#define USB_PID_TEVII_S480_2 0xd482
  72#endif
  73
  74#ifndef USB_PID_PROF_1100
  75#define USB_PID_PROF_1100 0xb012
  76#endif
  77
  78#ifndef USB_PID_TEVII_S421
  79#define USB_PID_TEVII_S421 0xd421
  80#endif
  81
  82#ifndef USB_PID_TEVII_S632
  83#define USB_PID_TEVII_S632 0xd632
  84#endif
  85
  86#ifndef USB_PID_GOTVIEW_SAT_HD
  87#define USB_PID_GOTVIEW_SAT_HD 0x5456
  88#endif
  89
  90#define DW210X_READ_MSG 0
  91#define DW210X_WRITE_MSG 1
  92
  93#define REG_1F_SYMBOLRATE_BYTE0 0x1f
  94#define REG_20_SYMBOLRATE_BYTE1 0x20
  95#define REG_21_SYMBOLRATE_BYTE2 0x21
  96/* on my own*/
  97#define DW2102_VOLTAGE_CTRL (0x1800)
  98#define SU3000_STREAM_CTRL (0x1900)
  99#define DW2102_RC_QUERY (0x1a00)
 100#define DW2102_LED_CTRL (0x1b00)
 101
 102#define DW2101_FIRMWARE "dvb-usb-dw2101.fw"
 103#define DW2102_FIRMWARE "dvb-usb-dw2102.fw"
 104#define DW2104_FIRMWARE "dvb-usb-dw2104.fw"
 105#define DW3101_FIRMWARE "dvb-usb-dw3101.fw"
 106#define S630_FIRMWARE   "dvb-usb-s630.fw"
 107#define S660_FIRMWARE   "dvb-usb-s660.fw"
 108#define P1100_FIRMWARE  "dvb-usb-p1100.fw"
 109#define P7500_FIRMWARE  "dvb-usb-p7500.fw"
 110
 111#define err_str "did not find the firmware file. (%s) " \
 112                "Please see linux/Documentation/dvb/ for more details " \
 113                "on firmware-problems."
 114
 115struct su3000_state {
 116        u8 initialized;
 117};
 118
 119struct s6x0_state {
 120        int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
 121};
 122
 123/* debug */
 124static int dvb_usb_dw2102_debug;
 125module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
 126MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
 127                                                DVB_USB_DEBUG_STATUS);
 128
 129/* demod probe */
 130static int demod_probe = 1;
 131module_param_named(demod, demod_probe, int, 0644);
 132MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
 133                        "4=stv0903+stb6100(or-able)).");
 134
 135DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 136
 137static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
 138                        u16 index, u8 * data, u16 len, int flags)
 139{
 140        int ret;
 141        u8 *u8buf;
 142        unsigned int pipe = (flags == DW210X_READ_MSG) ?
 143                                usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
 144        u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
 145
 146        u8buf = kmalloc(len, GFP_KERNEL);
 147        if (!u8buf)
 148                return -ENOMEM;
 149
 150
 151        if (flags == DW210X_WRITE_MSG)
 152                memcpy(u8buf, data, len);
 153        ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
 154                                value, index , u8buf, len, 2000);
 155
 156        if (flags == DW210X_READ_MSG)
 157                memcpy(data, u8buf, len);
 158
 159        kfree(u8buf);
 160        return ret;
 161}
 162
 163/* I2C */
 164static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 165                int num)
 166{
 167        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 168        int i = 0;
 169        u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
 170        u16 value;
 171
 172        if (!d)
 173                return -ENODEV;
 174        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 175                return -EAGAIN;
 176
 177        switch (num) {
 178        case 2:
 179                /* read stv0299 register */
 180                value = msg[0].buf[0];/* register */
 181                for (i = 0; i < msg[1].len; i++) {
 182                        dw210x_op_rw(d->udev, 0xb5, value + i, 0,
 183                                        buf6, 2, DW210X_READ_MSG);
 184                        msg[1].buf[i] = buf6[0];
 185                }
 186                break;
 187        case 1:
 188                switch (msg[0].addr) {
 189                case 0x68:
 190                        /* write to stv0299 register */
 191                        buf6[0] = 0x2a;
 192                        buf6[1] = msg[0].buf[0];
 193                        buf6[2] = msg[0].buf[1];
 194                        dw210x_op_rw(d->udev, 0xb2, 0, 0,
 195                                        buf6, 3, DW210X_WRITE_MSG);
 196                        break;
 197                case 0x60:
 198                        if (msg[0].flags == 0) {
 199                        /* write to tuner pll */
 200                                buf6[0] = 0x2c;
 201                                buf6[1] = 5;
 202                                buf6[2] = 0xc0;
 203                                buf6[3] = msg[0].buf[0];
 204                                buf6[4] = msg[0].buf[1];
 205                                buf6[5] = msg[0].buf[2];
 206                                buf6[6] = msg[0].buf[3];
 207                                dw210x_op_rw(d->udev, 0xb2, 0, 0,
 208                                                buf6, 7, DW210X_WRITE_MSG);
 209                        } else {
 210                        /* read from tuner */
 211                                dw210x_op_rw(d->udev, 0xb5, 0, 0,
 212                                                buf6, 1, DW210X_READ_MSG);
 213                                msg[0].buf[0] = buf6[0];
 214                        }
 215                        break;
 216                case (DW2102_RC_QUERY):
 217                        dw210x_op_rw(d->udev, 0xb8, 0, 0,
 218                                        buf6, 2, DW210X_READ_MSG);
 219                        msg[0].buf[0] = buf6[0];
 220                        msg[0].buf[1] = buf6[1];
 221                        break;
 222                case (DW2102_VOLTAGE_CTRL):
 223                        buf6[0] = 0x30;
 224                        buf6[1] = msg[0].buf[0];
 225                        dw210x_op_rw(d->udev, 0xb2, 0, 0,
 226                                        buf6, 2, DW210X_WRITE_MSG);
 227                        break;
 228                }
 229
 230                break;
 231        }
 232
 233        mutex_unlock(&d->i2c_mutex);
 234        return num;
 235}
 236
 237static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
 238                                                struct i2c_msg msg[], int num)
 239{
 240        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 241        u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
 242
 243        if (!d)
 244                return -ENODEV;
 245        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 246                return -EAGAIN;
 247
 248        switch (num) {
 249        case 2:
 250                /* read si2109 register by number */
 251                buf6[0] = msg[0].addr << 1;
 252                buf6[1] = msg[0].len;
 253                buf6[2] = msg[0].buf[0];
 254                dw210x_op_rw(d->udev, 0xc2, 0, 0,
 255                                buf6, msg[0].len + 2, DW210X_WRITE_MSG);
 256                /* read si2109 register */
 257                dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
 258                                buf6, msg[1].len + 2, DW210X_READ_MSG);
 259                memcpy(msg[1].buf, buf6 + 2, msg[1].len);
 260
 261                break;
 262        case 1:
 263                switch (msg[0].addr) {
 264                case 0x68:
 265                        /* write to si2109 register */
 266                        buf6[0] = msg[0].addr << 1;
 267                        buf6[1] = msg[0].len;
 268                        memcpy(buf6 + 2, msg[0].buf, msg[0].len);
 269                        dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
 270                                        msg[0].len + 2, DW210X_WRITE_MSG);
 271                        break;
 272                case(DW2102_RC_QUERY):
 273                        dw210x_op_rw(d->udev, 0xb8, 0, 0,
 274                                        buf6, 2, DW210X_READ_MSG);
 275                        msg[0].buf[0] = buf6[0];
 276                        msg[0].buf[1] = buf6[1];
 277                        break;
 278                case(DW2102_VOLTAGE_CTRL):
 279                        buf6[0] = 0x30;
 280                        buf6[1] = msg[0].buf[0];
 281                        dw210x_op_rw(d->udev, 0xb2, 0, 0,
 282                                        buf6, 2, DW210X_WRITE_MSG);
 283                        break;
 284                }
 285                break;
 286        }
 287
 288        mutex_unlock(&d->i2c_mutex);
 289        return num;
 290}
 291
 292static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
 293{
 294        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 295        int ret;
 296
 297        if (!d)
 298                return -ENODEV;
 299        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 300                return -EAGAIN;
 301
 302        switch (num) {
 303        case 2: {
 304                /* read */
 305                /* first write first register number */
 306                u8 ibuf[MAX_XFER_SIZE], obuf[3];
 307
 308                if (2 + msg[1].len > sizeof(ibuf)) {
 309                        warn("i2c rd: len=%d is too big!\n",
 310                             msg[1].len);
 311                        ret = -EOPNOTSUPP;
 312                        goto unlock;
 313                }
 314
 315                obuf[0] = msg[0].addr << 1;
 316                obuf[1] = msg[0].len;
 317                obuf[2] = msg[0].buf[0];
 318                dw210x_op_rw(d->udev, 0xc2, 0, 0,
 319                                obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 320                /* second read registers */
 321                dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
 322                                ibuf, msg[1].len + 2, DW210X_READ_MSG);
 323                memcpy(msg[1].buf, ibuf + 2, msg[1].len);
 324
 325                break;
 326        }
 327        case 1:
 328                switch (msg[0].addr) {
 329                case 0x68: {
 330                        /* write to register */
 331                        u8 obuf[MAX_XFER_SIZE];
 332
 333                        if (2 + msg[0].len > sizeof(obuf)) {
 334                                warn("i2c wr: len=%d is too big!\n",
 335                                     msg[1].len);
 336                                ret = -EOPNOTSUPP;
 337                                goto unlock;
 338                        }
 339
 340                        obuf[0] = msg[0].addr << 1;
 341                        obuf[1] = msg[0].len;
 342                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
 343                        dw210x_op_rw(d->udev, 0xc2, 0, 0,
 344                                        obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 345                        break;
 346                }
 347                case 0x61: {
 348                        /* write to tuner */
 349                        u8 obuf[MAX_XFER_SIZE];
 350
 351                        if (2 + msg[0].len > sizeof(obuf)) {
 352                                warn("i2c wr: len=%d is too big!\n",
 353                                     msg[1].len);
 354                                ret = -EOPNOTSUPP;
 355                                goto unlock;
 356                        }
 357
 358                        obuf[0] = msg[0].addr << 1;
 359                        obuf[1] = msg[0].len;
 360                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
 361                        dw210x_op_rw(d->udev, 0xc2, 0, 0,
 362                                        obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 363                        break;
 364                }
 365                case(DW2102_RC_QUERY): {
 366                        u8 ibuf[2];
 367                        dw210x_op_rw(d->udev, 0xb8, 0, 0,
 368                                        ibuf, 2, DW210X_READ_MSG);
 369                        memcpy(msg[0].buf, ibuf , 2);
 370                        break;
 371                }
 372                case(DW2102_VOLTAGE_CTRL): {
 373                        u8 obuf[2];
 374                        obuf[0] = 0x30;
 375                        obuf[1] = msg[0].buf[0];
 376                        dw210x_op_rw(d->udev, 0xb2, 0, 0,
 377                                        obuf, 2, DW210X_WRITE_MSG);
 378                        break;
 379                }
 380                }
 381
 382                break;
 383        }
 384        ret = num;
 385
 386unlock:
 387        mutex_unlock(&d->i2c_mutex);
 388        return ret;
 389}
 390
 391static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
 392{
 393        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 394        int len, i, j, ret;
 395
 396        if (!d)
 397                return -ENODEV;
 398        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 399                return -EAGAIN;
 400
 401        for (j = 0; j < num; j++) {
 402                switch (msg[j].addr) {
 403                case(DW2102_RC_QUERY): {
 404                        u8 ibuf[2];
 405                        dw210x_op_rw(d->udev, 0xb8, 0, 0,
 406                                        ibuf, 2, DW210X_READ_MSG);
 407                        memcpy(msg[j].buf, ibuf , 2);
 408                        break;
 409                }
 410                case(DW2102_VOLTAGE_CTRL): {
 411                        u8 obuf[2];
 412                        obuf[0] = 0x30;
 413                        obuf[1] = msg[j].buf[0];
 414                        dw210x_op_rw(d->udev, 0xb2, 0, 0,
 415                                        obuf, 2, DW210X_WRITE_MSG);
 416                        break;
 417                }
 418                /*case 0x55: cx24116
 419                case 0x6a: stv0903
 420                case 0x68: ds3000, stv0903
 421                case 0x60: ts2020, stv6110, stb6100 */
 422                default: {
 423                        if (msg[j].flags == I2C_M_RD) {
 424                                /* read registers */
 425                                u8  ibuf[MAX_XFER_SIZE];
 426
 427                                if (2 + msg[j].len > sizeof(ibuf)) {
 428                                        warn("i2c rd: len=%d is too big!\n",
 429                                             msg[j].len);
 430                                        ret = -EOPNOTSUPP;
 431                                        goto unlock;
 432                                }
 433
 434                                dw210x_op_rw(d->udev, 0xc3,
 435                                                (msg[j].addr << 1) + 1, 0,
 436                                                ibuf, msg[j].len + 2,
 437                                                DW210X_READ_MSG);
 438                                memcpy(msg[j].buf, ibuf + 2, msg[j].len);
 439                        mdelay(10);
 440                        } else if (((msg[j].buf[0] == 0xb0) &&
 441                                                (msg[j].addr == 0x68)) ||
 442                                                ((msg[j].buf[0] == 0xf7) &&
 443                                                (msg[j].addr == 0x55))) {
 444                                /* write firmware */
 445                                u8 obuf[19];
 446                                obuf[0] = msg[j].addr << 1;
 447                                obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
 448                                obuf[2] = msg[j].buf[0];
 449                                len = msg[j].len - 1;
 450                                i = 1;
 451                                do {
 452                                        memcpy(obuf + 3, msg[j].buf + i,
 453                                                        (len > 16 ? 16 : len));
 454                                        dw210x_op_rw(d->udev, 0xc2, 0, 0,
 455                                                obuf, (len > 16 ? 16 : len) + 3,
 456                                                DW210X_WRITE_MSG);
 457                                        i += 16;
 458                                        len -= 16;
 459                                } while (len > 0);
 460                        } else {
 461                                /* write registers */
 462                                u8 obuf[MAX_XFER_SIZE];
 463
 464                                if (2 + msg[j].len > sizeof(obuf)) {
 465                                        warn("i2c wr: len=%d is too big!\n",
 466                                             msg[j].len);
 467                                        ret = -EOPNOTSUPP;
 468                                        goto unlock;
 469                                }
 470
 471                                obuf[0] = msg[j].addr << 1;
 472                                obuf[1] = msg[j].len;
 473                                memcpy(obuf + 2, msg[j].buf, msg[j].len);
 474                                dw210x_op_rw(d->udev, 0xc2, 0, 0,
 475                                                obuf, msg[j].len + 2,
 476                                                DW210X_WRITE_MSG);
 477                        }
 478                        break;
 479                }
 480                }
 481
 482        }
 483        ret = num;
 484
 485unlock:
 486        mutex_unlock(&d->i2c_mutex);
 487        return ret;
 488}
 489
 490static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 491                                                                int num)
 492{
 493        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 494        int ret;
 495        int i;
 496
 497        if (!d)
 498                return -ENODEV;
 499        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 500                return -EAGAIN;
 501
 502        switch (num) {
 503        case 2: {
 504                /* read */
 505                /* first write first register number */
 506                u8 ibuf[MAX_XFER_SIZE], obuf[3];
 507
 508                if (2 + msg[1].len > sizeof(ibuf)) {
 509                        warn("i2c rd: len=%d is too big!\n",
 510                             msg[1].len);
 511                        ret = -EOPNOTSUPP;
 512                        goto unlock;
 513                }
 514                obuf[0] = msg[0].addr << 1;
 515                obuf[1] = msg[0].len;
 516                obuf[2] = msg[0].buf[0];
 517                dw210x_op_rw(d->udev, 0xc2, 0, 0,
 518                                obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 519                /* second read registers */
 520                dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
 521                                ibuf, msg[1].len + 2, DW210X_READ_MSG);
 522                memcpy(msg[1].buf, ibuf + 2, msg[1].len);
 523
 524                break;
 525        }
 526        case 1:
 527                switch (msg[0].addr) {
 528                case 0x60:
 529                case 0x0c: {
 530                        /* write to register */
 531                        u8 obuf[MAX_XFER_SIZE];
 532
 533                        if (2 + msg[0].len > sizeof(obuf)) {
 534                                warn("i2c wr: len=%d is too big!\n",
 535                                     msg[0].len);
 536                                ret = -EOPNOTSUPP;
 537                                goto unlock;
 538                        }
 539                        obuf[0] = msg[0].addr << 1;
 540                        obuf[1] = msg[0].len;
 541                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
 542                        dw210x_op_rw(d->udev, 0xc2, 0, 0,
 543                                        obuf, msg[0].len + 2, DW210X_WRITE_MSG);
 544                        break;
 545                }
 546                case(DW2102_RC_QUERY): {
 547                        u8 ibuf[2];
 548                        dw210x_op_rw(d->udev, 0xb8, 0, 0,
 549                                        ibuf, 2, DW210X_READ_MSG);
 550                        memcpy(msg[0].buf, ibuf , 2);
 551                        break;
 552                }
 553                }
 554
 555                break;
 556        }
 557
 558        for (i = 0; i < num; i++) {
 559                deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
 560                                msg[i].flags == 0 ? ">>>" : "<<<");
 561                debug_dump(msg[i].buf, msg[i].len, deb_xfer);
 562        }
 563        ret = num;
 564
 565unlock:
 566        mutex_unlock(&d->i2c_mutex);
 567        return ret;
 568}
 569
 570static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 571                                                                int num)
 572{
 573        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 574        struct usb_device *udev;
 575        int len, i, j, ret;
 576
 577        if (!d)
 578                return -ENODEV;
 579        udev = d->udev;
 580        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 581                return -EAGAIN;
 582
 583        for (j = 0; j < num; j++) {
 584                switch (msg[j].addr) {
 585                case (DW2102_RC_QUERY): {
 586                        u8 ibuf[5];
 587                        dw210x_op_rw(d->udev, 0xb8, 0, 0,
 588                                        ibuf, 5, DW210X_READ_MSG);
 589                        memcpy(msg[j].buf, ibuf + 3, 2);
 590                        break;
 591                }
 592                case (DW2102_VOLTAGE_CTRL): {
 593                        u8 obuf[2];
 594
 595                        obuf[0] = 1;
 596                        obuf[1] = msg[j].buf[1];/* off-on */
 597                        dw210x_op_rw(d->udev, 0x8a, 0, 0,
 598                                        obuf, 2, DW210X_WRITE_MSG);
 599                        obuf[0] = 3;
 600                        obuf[1] = msg[j].buf[0];/* 13v-18v */
 601                        dw210x_op_rw(d->udev, 0x8a, 0, 0,
 602                                        obuf, 2, DW210X_WRITE_MSG);
 603                        break;
 604                }
 605                case (DW2102_LED_CTRL): {
 606                        u8 obuf[2];
 607
 608                        obuf[0] = 5;
 609                        obuf[1] = msg[j].buf[0];
 610                        dw210x_op_rw(d->udev, 0x8a, 0, 0,
 611                                        obuf, 2, DW210X_WRITE_MSG);
 612                        break;
 613                }
 614                /*case 0x55: cx24116
 615                case 0x6a: stv0903
 616                case 0x68: ds3000, stv0903, rs2000
 617                case 0x60: ts2020, stv6110, stb6100
 618                case 0xa0: eeprom */
 619                default: {
 620                        if (msg[j].flags == I2C_M_RD) {
 621                                /* read registers */
 622                                u8 ibuf[MAX_XFER_SIZE];
 623
 624                                if (msg[j].len > sizeof(ibuf)) {
 625                                        warn("i2c rd: len=%d is too big!\n",
 626                                             msg[j].len);
 627                                        ret = -EOPNOTSUPP;
 628                                        goto unlock;
 629                                }
 630
 631                                dw210x_op_rw(d->udev, 0x91, 0, 0,
 632                                                ibuf, msg[j].len,
 633                                                DW210X_READ_MSG);
 634                                memcpy(msg[j].buf, ibuf, msg[j].len);
 635                                break;
 636                        } else if ((msg[j].buf[0] == 0xb0) &&
 637                                                (msg[j].addr == 0x68)) {
 638                                /* write firmware */
 639                                u8 obuf[19];
 640                                obuf[0] = (msg[j].len > 16 ?
 641                                                18 : msg[j].len + 1);
 642                                obuf[1] = msg[j].addr << 1;
 643                                obuf[2] = msg[j].buf[0];
 644                                len = msg[j].len - 1;
 645                                i = 1;
 646                                do {
 647                                        memcpy(obuf + 3, msg[j].buf + i,
 648                                                        (len > 16 ? 16 : len));
 649                                        dw210x_op_rw(d->udev, 0x80, 0, 0,
 650                                                obuf, (len > 16 ? 16 : len) + 3,
 651                                                DW210X_WRITE_MSG);
 652                                        i += 16;
 653                                        len -= 16;
 654                                } while (len > 0);
 655                        } else if (j < (num - 1)) {
 656                                /* write register addr before read */
 657                                u8 obuf[MAX_XFER_SIZE];
 658
 659                                if (2 + msg[j].len > sizeof(obuf)) {
 660                                        warn("i2c wr: len=%d is too big!\n",
 661                                             msg[j].len);
 662                                        ret = -EOPNOTSUPP;
 663                                        goto unlock;
 664                                }
 665
 666                                obuf[0] = msg[j + 1].len;
 667                                obuf[1] = (msg[j].addr << 1);
 668                                memcpy(obuf + 2, msg[j].buf, msg[j].len);
 669                                dw210x_op_rw(d->udev,
 670                                                udev->descriptor.idProduct ==
 671                                                0x7500 ? 0x92 : 0x90, 0, 0,
 672                                                obuf, msg[j].len + 2,
 673                                                DW210X_WRITE_MSG);
 674                                break;
 675                        } else {
 676                                /* write registers */
 677                                u8 obuf[MAX_XFER_SIZE];
 678
 679                                if (2 + msg[j].len > sizeof(obuf)) {
 680                                        warn("i2c wr: len=%d is too big!\n",
 681                                             msg[j].len);
 682                                        ret = -EOPNOTSUPP;
 683                                        goto unlock;
 684                                }
 685                                obuf[0] = msg[j].len + 1;
 686                                obuf[1] = (msg[j].addr << 1);
 687                                memcpy(obuf + 2, msg[j].buf, msg[j].len);
 688                                dw210x_op_rw(d->udev, 0x80, 0, 0,
 689                                                obuf, msg[j].len + 2,
 690                                                DW210X_WRITE_MSG);
 691                                break;
 692                        }
 693                        break;
 694                }
 695                }
 696        }
 697        ret = num;
 698
 699unlock:
 700        mutex_unlock(&d->i2c_mutex);
 701        return ret;
 702}
 703
 704static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 705                                                                int num)
 706{
 707        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 708        u8 obuf[0x40], ibuf[0x40];
 709
 710        if (!d)
 711                return -ENODEV;
 712        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 713                return -EAGAIN;
 714
 715        switch (num) {
 716        case 1:
 717                switch (msg[0].addr) {
 718                case SU3000_STREAM_CTRL:
 719                        obuf[0] = msg[0].buf[0] + 0x36;
 720                        obuf[1] = 3;
 721                        obuf[2] = 0;
 722                        if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
 723                                err("i2c transfer failed.");
 724                        break;
 725                case DW2102_RC_QUERY:
 726                        obuf[0] = 0x10;
 727                        if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
 728                                err("i2c transfer failed.");
 729                        msg[0].buf[1] = ibuf[0];
 730                        msg[0].buf[0] = ibuf[1];
 731                        break;
 732                default:
 733                        /* always i2c write*/
 734                        obuf[0] = 0x08;
 735                        obuf[1] = msg[0].addr;
 736                        obuf[2] = msg[0].len;
 737
 738                        memcpy(&obuf[3], msg[0].buf, msg[0].len);
 739
 740                        if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
 741                                                ibuf, 1, 0) < 0)
 742                                err("i2c transfer failed.");
 743
 744                }
 745                break;
 746        case 2:
 747                /* always i2c read */
 748                obuf[0] = 0x09;
 749                obuf[1] = msg[0].len;
 750                obuf[2] = msg[1].len;
 751                obuf[3] = msg[0].addr;
 752                memcpy(&obuf[4], msg[0].buf, msg[0].len);
 753
 754                if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
 755                                        ibuf, msg[1].len + 1, 0) < 0)
 756                        err("i2c transfer failed.");
 757
 758                memcpy(msg[1].buf, &ibuf[1], msg[1].len);
 759                break;
 760        default:
 761                warn("more than 2 i2c messages at a time is not handled yet.");
 762                break;
 763        }
 764        mutex_unlock(&d->i2c_mutex);
 765        return num;
 766}
 767
 768static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
 769{
 770        return I2C_FUNC_I2C;
 771}
 772
 773static struct i2c_algorithm dw2102_i2c_algo = {
 774        .master_xfer = dw2102_i2c_transfer,
 775        .functionality = dw210x_i2c_func,
 776};
 777
 778static struct i2c_algorithm dw2102_serit_i2c_algo = {
 779        .master_xfer = dw2102_serit_i2c_transfer,
 780        .functionality = dw210x_i2c_func,
 781};
 782
 783static struct i2c_algorithm dw2102_earda_i2c_algo = {
 784        .master_xfer = dw2102_earda_i2c_transfer,
 785        .functionality = dw210x_i2c_func,
 786};
 787
 788static struct i2c_algorithm dw2104_i2c_algo = {
 789        .master_xfer = dw2104_i2c_transfer,
 790        .functionality = dw210x_i2c_func,
 791};
 792
 793static struct i2c_algorithm dw3101_i2c_algo = {
 794        .master_xfer = dw3101_i2c_transfer,
 795        .functionality = dw210x_i2c_func,
 796};
 797
 798static struct i2c_algorithm s6x0_i2c_algo = {
 799        .master_xfer = s6x0_i2c_transfer,
 800        .functionality = dw210x_i2c_func,
 801};
 802
 803static struct i2c_algorithm su3000_i2c_algo = {
 804        .master_xfer = su3000_i2c_transfer,
 805        .functionality = dw210x_i2c_func,
 806};
 807
 808static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 809{
 810        int i;
 811        u8 ibuf[] = {0, 0};
 812        u8 eeprom[256], eepromline[16];
 813
 814        for (i = 0; i < 256; i++) {
 815                if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
 816                        err("read eeprom failed.");
 817                        return -1;
 818                } else {
 819                        eepromline[i%16] = ibuf[0];
 820                        eeprom[i] = ibuf[0];
 821                }
 822                if ((i % 16) == 15) {
 823                        deb_xfer("%02x: ", i - 15);
 824                        debug_dump(eepromline, 16, deb_xfer);
 825                }
 826        }
 827
 828        memcpy(mac, eeprom + 8, 6);
 829        return 0;
 830};
 831
 832static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 833{
 834        int i, ret;
 835        u8 ibuf[] = { 0 }, obuf[] = { 0 };
 836        u8 eeprom[256], eepromline[16];
 837        struct i2c_msg msg[] = {
 838                {
 839                        .addr = 0xa0 >> 1,
 840                        .flags = 0,
 841                        .buf = obuf,
 842                        .len = 1,
 843                }, {
 844                        .addr = 0xa0 >> 1,
 845                        .flags = I2C_M_RD,
 846                        .buf = ibuf,
 847                        .len = 1,
 848                }
 849        };
 850
 851        for (i = 0; i < 256; i++) {
 852                obuf[0] = i;
 853                ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
 854                if (ret != 2) {
 855                        err("read eeprom failed.");
 856                        return -1;
 857                } else {
 858                        eepromline[i % 16] = ibuf[0];
 859                        eeprom[i] = ibuf[0];
 860                }
 861
 862                if ((i % 16) == 15) {
 863                        deb_xfer("%02x: ", i - 15);
 864                        debug_dump(eepromline, 16, deb_xfer);
 865                }
 866        }
 867
 868        memcpy(mac, eeprom + 16, 6);
 869        return 0;
 870};
 871
 872static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 873{
 874        static u8 command_start[] = {0x00};
 875        static u8 command_stop[] = {0x01};
 876        struct i2c_msg msg = {
 877                .addr = SU3000_STREAM_CTRL,
 878                .flags = 0,
 879                .buf = onoff ? command_start : command_stop,
 880                .len = 1
 881        };
 882
 883        i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
 884
 885        return 0;
 886}
 887
 888static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
 889{
 890        struct su3000_state *state = (struct su3000_state *)d->priv;
 891        u8 obuf[] = {0xde, 0};
 892
 893        info("%s: %d, initialized %d\n", __func__, i, state->initialized);
 894
 895        if (i && !state->initialized) {
 896                state->initialized = 1;
 897                /* reset board */
 898                dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
 899        }
 900
 901        return 0;
 902}
 903
 904static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 905{
 906        int i;
 907        u8 obuf[] = { 0x1f, 0xf0 };
 908        u8 ibuf[] = { 0 };
 909        struct i2c_msg msg[] = {
 910                {
 911                        .addr = 0x51,
 912                        .flags = 0,
 913                        .buf = obuf,
 914                        .len = 2,
 915                }, {
 916                        .addr = 0x51,
 917                        .flags = I2C_M_RD,
 918                        .buf = ibuf,
 919                        .len = 1,
 920
 921                }
 922        };
 923
 924        for (i = 0; i < 6; i++) {
 925                obuf[1] = 0xf0 + i;
 926                if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
 927                        break;
 928                else
 929                        mac[i] = ibuf[0];
 930
 931                debug_dump(mac, 6, printk);
 932        }
 933
 934        return 0;
 935}
 936
 937static int su3000_identify_state(struct usb_device *udev,
 938                                 struct dvb_usb_device_properties *props,
 939                                 struct dvb_usb_device_description **desc,
 940                                 int *cold)
 941{
 942        info("%s\n", __func__);
 943
 944        *cold = 0;
 945        return 0;
 946}
 947
 948static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 949{
 950        static u8 command_13v[] = {0x00, 0x01};
 951        static u8 command_18v[] = {0x01, 0x01};
 952        static u8 command_off[] = {0x00, 0x00};
 953        struct i2c_msg msg = {
 954                .addr = DW2102_VOLTAGE_CTRL,
 955                .flags = 0,
 956                .buf = command_off,
 957                .len = 2,
 958        };
 959
 960        struct dvb_usb_adapter *udev_adap =
 961                (struct dvb_usb_adapter *)(fe->dvb->priv);
 962        if (voltage == SEC_VOLTAGE_18)
 963                msg.buf = command_18v;
 964        else if (voltage == SEC_VOLTAGE_13)
 965                msg.buf = command_13v;
 966
 967        i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
 968
 969        return 0;
 970}
 971
 972static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 973{
 974        struct dvb_usb_adapter *d =
 975                (struct dvb_usb_adapter *)(fe->dvb->priv);
 976        struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
 977
 978        dw210x_set_voltage(fe, voltage);
 979        if (st->old_set_voltage)
 980                st->old_set_voltage(fe, voltage);
 981
 982        return 0;
 983}
 984
 985static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
 986{
 987        static u8 led_off[] = { 0 };
 988        static u8 led_on[] = { 1 };
 989        struct i2c_msg msg = {
 990                .addr = DW2102_LED_CTRL,
 991                .flags = 0,
 992                .buf = led_off,
 993                .len = 1
 994        };
 995        struct dvb_usb_adapter *udev_adap =
 996                (struct dvb_usb_adapter *)(fe->dvb->priv);
 997
 998        if (offon)
 999                msg.buf = led_on;
1000        i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
1001}
1002
1003static struct stv0299_config sharp_z0194a_config = {
1004        .demod_address = 0x68,
1005        .inittab = sharp_z0194a_inittab,
1006        .mclk = 88000000UL,
1007        .invert = 1,
1008        .skip_reinit = 0,
1009        .lock_output = STV0299_LOCKOUTPUT_1,
1010        .volt13_op0_op1 = STV0299_VOLT13_OP1,
1011        .min_delay_ms = 100,
1012        .set_symbol_rate = sharp_z0194a_set_symbol_rate,
1013};
1014
1015static struct cx24116_config dw2104_config = {
1016        .demod_address = 0x55,
1017        .mpg_clk_pos_pol = 0x01,
1018};
1019
1020static struct si21xx_config serit_sp1511lhb_config = {
1021        .demod_address = 0x68,
1022        .min_delay_ms = 100,
1023
1024};
1025
1026static struct tda10023_config dw3101_tda10023_config = {
1027        .demod_address = 0x0c,
1028        .invert = 1,
1029};
1030
1031static struct mt312_config zl313_config = {
1032        .demod_address = 0x0e,
1033};
1034
1035static struct ds3000_config dw2104_ds3000_config = {
1036        .demod_address = 0x68,
1037};
1038
1039static struct ts2020_config dw2104_ts2020_config = {
1040        .tuner_address = 0x60,
1041        .clk_out_div = 1,
1042        .frequency_div = 1060000,
1043};
1044
1045static struct ds3000_config s660_ds3000_config = {
1046        .demod_address = 0x68,
1047        .ci_mode = 1,
1048        .set_lock_led = dw210x_led_ctrl,
1049};
1050
1051static struct ts2020_config s660_ts2020_config = {
1052        .tuner_address = 0x60,
1053        .clk_out_div = 1,
1054        .frequency_div = 1146000,
1055};
1056
1057static struct stv0900_config dw2104a_stv0900_config = {
1058        .demod_address = 0x6a,
1059        .demod_mode = 0,
1060        .xtal = 27000000,
1061        .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
1062        .diseqc_mode = 2,/* 2/3 PWM */
1063        .tun1_maddress = 0,/* 0x60 */
1064        .tun1_adc = 0,/* 2 Vpp */
1065        .path1_mode = 3,
1066};
1067
1068static struct stb6100_config dw2104a_stb6100_config = {
1069        .tuner_address = 0x60,
1070        .refclock = 27000000,
1071};
1072
1073static struct stv0900_config dw2104_stv0900_config = {
1074        .demod_address = 0x68,
1075        .demod_mode = 0,
1076        .xtal = 8000000,
1077        .clkmode = 3,
1078        .diseqc_mode = 2,
1079        .tun1_maddress = 0,
1080        .tun1_adc = 1,/* 1 Vpp */
1081        .path1_mode = 3,
1082};
1083
1084static struct stv6110_config dw2104_stv6110_config = {
1085        .i2c_address = 0x60,
1086        .mclk = 16000000,
1087        .clk_div = 1,
1088};
1089
1090static struct stv0900_config prof_7500_stv0900_config = {
1091        .demod_address = 0x6a,
1092        .demod_mode = 0,
1093        .xtal = 27000000,
1094        .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
1095        .diseqc_mode = 2,/* 2/3 PWM */
1096        .tun1_maddress = 0,/* 0x60 */
1097        .tun1_adc = 0,/* 2 Vpp */
1098        .path1_mode = 3,
1099        .tun1_type = 3,
1100        .set_lock_led = dw210x_led_ctrl,
1101};
1102
1103static struct ds3000_config su3000_ds3000_config = {
1104        .demod_address = 0x68,
1105        .ci_mode = 1,
1106        .set_lock_led = dw210x_led_ctrl,
1107};
1108
1109static struct cxd2820r_config cxd2820r_config = {
1110        .i2c_address = 0x6c, /* (0xd8 >> 1) */
1111        .ts_mode = 0x38,
1112};
1113
1114static struct tda18271_config tda18271_config = {
1115        .output_opt = TDA18271_OUTPUT_LT_OFF,
1116        .gate = TDA18271_GATE_DIGITAL,
1117};
1118
1119static u8 m88rs2000_inittab[] = {
1120        DEMOD_WRITE, 0x9a, 0x30,
1121        DEMOD_WRITE, 0x00, 0x01,
1122        WRITE_DELAY, 0x19, 0x00,
1123        DEMOD_WRITE, 0x00, 0x00,
1124        DEMOD_WRITE, 0x9a, 0xb0,
1125        DEMOD_WRITE, 0x81, 0xc1,
1126        DEMOD_WRITE, 0x81, 0x81,
1127        DEMOD_WRITE, 0x86, 0xc6,
1128        DEMOD_WRITE, 0x9a, 0x30,
1129        DEMOD_WRITE, 0xf0, 0x80,
1130        DEMOD_WRITE, 0xf1, 0xbf,
1131        DEMOD_WRITE, 0xb0, 0x45,
1132        DEMOD_WRITE, 0xb2, 0x01,
1133        DEMOD_WRITE, 0x9a, 0xb0,
1134        0xff, 0xaa, 0xff
1135};
1136
1137static struct m88rs2000_config s421_m88rs2000_config = {
1138        .demod_addr = 0x68,
1139        .inittab = m88rs2000_inittab,
1140};
1141
1142static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
1143{
1144        struct dvb_tuner_ops *tuner_ops = NULL;
1145
1146        if (demod_probe & 4) {
1147                d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
1148                                &d->dev->i2c_adap, 0);
1149                if (d->fe_adap[0].fe != NULL) {
1150                        if (dvb_attach(stb6100_attach, d->fe_adap[0].fe,
1151                                        &dw2104a_stb6100_config,
1152                                        &d->dev->i2c_adap)) {
1153                                tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops;
1154                                tuner_ops->set_frequency = stb6100_set_freq;
1155                                tuner_ops->get_frequency = stb6100_get_freq;
1156                                tuner_ops->set_bandwidth = stb6100_set_bandw;
1157                                tuner_ops->get_bandwidth = stb6100_get_bandw;
1158                                d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1159                                info("Attached STV0900+STB6100!\n");
1160                                return 0;
1161                        }
1162                }
1163        }
1164
1165        if (demod_probe & 2) {
1166                d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
1167                                &d->dev->i2c_adap, 0);
1168                if (d->fe_adap[0].fe != NULL) {
1169                        if (dvb_attach(stv6110_attach, d->fe_adap[0].fe,
1170                                        &dw2104_stv6110_config,
1171                                        &d->dev->i2c_adap)) {
1172                                d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1173                                info("Attached STV0900+STV6110A!\n");
1174                                return 0;
1175                        }
1176                }
1177        }
1178
1179        if (demod_probe & 1) {
1180                d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config,
1181                                &d->dev->i2c_adap);
1182                if (d->fe_adap[0].fe != NULL) {
1183                        d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1184                        info("Attached cx24116!\n");
1185                        return 0;
1186                }
1187        }
1188
1189        d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
1190                        &d->dev->i2c_adap);
1191        if (d->fe_adap[0].fe != NULL) {
1192                dvb_attach(ts2020_attach, d->fe_adap[0].fe,
1193                        &dw2104_ts2020_config, &d->dev->i2c_adap);
1194                d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1195                info("Attached DS3000!\n");
1196                return 0;
1197        }
1198
1199        return -EIO;
1200}
1201
1202static struct dvb_usb_device_properties dw2102_properties;
1203static struct dvb_usb_device_properties dw2104_properties;
1204static struct dvb_usb_device_properties s6x0_properties;
1205
1206static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
1207{
1208        if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
1209                /*dw2102_properties.adapter->tuner_attach = NULL;*/
1210                d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
1211                                        &d->dev->i2c_adap);
1212                if (d->fe_adap[0].fe != NULL) {
1213                        d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1214                        info("Attached si21xx!\n");
1215                        return 0;
1216                }
1217        }
1218
1219        if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
1220                d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
1221                                        &d->dev->i2c_adap);
1222                if (d->fe_adap[0].fe != NULL) {
1223                        if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
1224                                        &d->dev->i2c_adap)) {
1225                                d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1226                                info("Attached stv0288!\n");
1227                                return 0;
1228                        }
1229                }
1230        }
1231
1232        if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
1233                /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
1234                d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
1235                                        &d->dev->i2c_adap);
1236                if (d->fe_adap[0].fe != NULL) {
1237                        d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1238                        info("Attached stv0299!\n");
1239                        return 0;
1240                }
1241        }
1242        return -EIO;
1243}
1244
1245static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
1246{
1247        d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
1248                                &d->dev->i2c_adap, 0x48);
1249        if (d->fe_adap[0].fe != NULL) {
1250                info("Attached tda10023!\n");
1251                return 0;
1252        }
1253        return -EIO;
1254}
1255
1256static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
1257{
1258        d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config,
1259                        &d->dev->i2c_adap);
1260        if (d->fe_adap[0].fe != NULL) {
1261                if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
1262                                &d->dev->i2c_adap)) {
1263                        d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1264                        info("Attached zl100313+zl10039!\n");
1265                        return 0;
1266                }
1267        }
1268
1269        return -EIO;
1270}
1271
1272static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
1273{
1274        u8 obuf[] = {7, 1};
1275
1276        d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
1277                        &d->dev->i2c_adap);
1278
1279        if (d->fe_adap[0].fe == NULL)
1280                return -EIO;
1281
1282        if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap))
1283                return -EIO;
1284
1285        d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1286
1287        dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1288
1289        info("Attached stv0288+stb6000!\n");
1290
1291        return 0;
1292
1293}
1294
1295static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
1296{
1297        struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
1298        u8 obuf[] = {7, 1};
1299
1300        d->fe_adap[0].fe = dvb_attach(ds3000_attach, &s660_ds3000_config,
1301                        &d->dev->i2c_adap);
1302
1303        if (d->fe_adap[0].fe == NULL)
1304                return -EIO;
1305
1306        dvb_attach(ts2020_attach, d->fe_adap[0].fe, &s660_ts2020_config,
1307                &d->dev->i2c_adap);
1308
1309        st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage;
1310        d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage;
1311
1312        dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1313
1314        info("Attached ds3000+ts2020!\n");
1315
1316        return 0;
1317}
1318
1319static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
1320{
1321        u8 obuf[] = {7, 1};
1322
1323        d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
1324                                        &d->dev->i2c_adap, 0);
1325        if (d->fe_adap[0].fe == NULL)
1326                return -EIO;
1327
1328        d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1329
1330        dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1331
1332        info("Attached STV0900+STB6100A!\n");
1333
1334        return 0;
1335}
1336
1337static int su3000_frontend_attach(struct dvb_usb_adapter *d)
1338{
1339        u8 obuf[3] = { 0xe, 0x80, 0 };
1340        u8 ibuf[] = { 0 };
1341
1342        if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1343                err("command 0x0e transfer failed.");
1344
1345        obuf[0] = 0xe;
1346        obuf[1] = 0x02;
1347        obuf[2] = 1;
1348
1349        if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1350                err("command 0x0e transfer failed.");
1351        msleep(300);
1352
1353        obuf[0] = 0xe;
1354        obuf[1] = 0x83;
1355        obuf[2] = 0;
1356
1357        if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1358                err("command 0x0e transfer failed.");
1359
1360        obuf[0] = 0xe;
1361        obuf[1] = 0x83;
1362        obuf[2] = 1;
1363
1364        if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1365                err("command 0x0e transfer failed.");
1366
1367        obuf[0] = 0x51;
1368
1369        if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1370                err("command 0x51 transfer failed.");
1371
1372        d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
1373                                        &d->dev->i2c_adap);
1374        if (d->fe_adap[0].fe == NULL)
1375                return -EIO;
1376
1377        if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
1378                                &dw2104_ts2020_config,
1379                                &d->dev->i2c_adap)) {
1380                info("Attached DS3000/TS2020!\n");
1381                return 0;
1382        }
1383
1384        info("Failed to attach DS3000/TS2020!\n");
1385        return -EIO;
1386}
1387
1388static int t220_frontend_attach(struct dvb_usb_adapter *d)
1389{
1390        u8 obuf[3] = { 0xe, 0x80, 0 };
1391        u8 ibuf[] = { 0 };
1392
1393        if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1394                err("command 0x0e transfer failed.");
1395
1396        obuf[0] = 0xe;
1397        obuf[1] = 0x83;
1398        obuf[2] = 0;
1399
1400        if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1401                err("command 0x0e transfer failed.");
1402
1403        msleep(100);
1404
1405        obuf[0] = 0xe;
1406        obuf[1] = 0x80;
1407        obuf[2] = 1;
1408
1409        if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1410                err("command 0x0e transfer failed.");
1411
1412        obuf[0] = 0x51;
1413
1414        if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1415                err("command 0x51 transfer failed.");
1416
1417        d->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
1418                                        &d->dev->i2c_adap, NULL);
1419        if (d->fe_adap[0].fe != NULL) {
1420                if (dvb_attach(tda18271_attach, d->fe_adap[0].fe, 0x60,
1421                                        &d->dev->i2c_adap, &tda18271_config)) {
1422                        info("Attached TDA18271HD/CXD2820R!\n");
1423                        return 0;
1424                }
1425        }
1426
1427        info("Failed to attach TDA18271HD/CXD2820R!\n");
1428        return -EIO;
1429}
1430
1431static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d)
1432{
1433        u8 obuf[] = { 0x51 };
1434        u8 ibuf[] = { 0 };
1435
1436        if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1437                err("command 0x51 transfer failed.");
1438
1439        d->fe_adap[0].fe = dvb_attach(m88rs2000_attach, &s421_m88rs2000_config,
1440                                        &d->dev->i2c_adap);
1441
1442        if (d->fe_adap[0].fe == NULL)
1443                return -EIO;
1444
1445        if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
1446                                &dw2104_ts2020_config,
1447                                &d->dev->i2c_adap)) {
1448                info("Attached RS2000/TS2020!\n");
1449                return 0;
1450        }
1451
1452        info("Failed to attach RS2000/TS2020!\n");
1453        return -EIO;
1454}
1455
1456static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
1457{
1458        dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
1459                &adap->dev->i2c_adap, DVB_PLL_OPERA1);
1460        return 0;
1461}
1462
1463static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
1464{
1465        dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
1466                &adap->dev->i2c_adap, DVB_PLL_TUA6034);
1467
1468        return 0;
1469}
1470
1471static int dw2102_rc_query(struct dvb_usb_device *d)
1472{
1473        u8 key[2];
1474        struct i2c_msg msg = {
1475                .addr = DW2102_RC_QUERY,
1476                .flags = I2C_M_RD,
1477                .buf = key,
1478                .len = 2
1479        };
1480
1481        if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1482                if (msg.buf[0] != 0xff) {
1483                        deb_rc("%s: rc code: %x, %x\n",
1484                                        __func__, key[0], key[1]);
1485                        rc_keydown(d->rc_dev, key[0], 1);
1486                }
1487        }
1488
1489        return 0;
1490}
1491
1492static int prof_rc_query(struct dvb_usb_device *d)
1493{
1494        u8 key[2];
1495        struct i2c_msg msg = {
1496                .addr = DW2102_RC_QUERY,
1497                .flags = I2C_M_RD,
1498                .buf = key,
1499                .len = 2
1500        };
1501
1502        if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1503                if (msg.buf[0] != 0xff) {
1504                        deb_rc("%s: rc code: %x, %x\n",
1505                                        __func__, key[0], key[1]);
1506                        rc_keydown(d->rc_dev, key[0]^0xff, 1);
1507                }
1508        }
1509
1510        return 0;
1511}
1512
1513static int su3000_rc_query(struct dvb_usb_device *d)
1514{
1515        u8 key[2];
1516        struct i2c_msg msg = {
1517                .addr = DW2102_RC_QUERY,
1518                .flags = I2C_M_RD,
1519                .buf = key,
1520                .len = 2
1521        };
1522
1523        if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1524                if (msg.buf[0] != 0xff) {
1525                        deb_rc("%s: rc code: %x, %x\n",
1526                                        __func__, key[0], key[1]);
1527                        rc_keydown(d->rc_dev, key[1] << 8 | key[0], 1);
1528                }
1529        }
1530
1531        return 0;
1532}
1533
1534enum dw2102_table_entry {
1535        CYPRESS_DW2102,
1536        CYPRESS_DW2101,
1537        CYPRESS_DW2104,
1538        TEVII_S650,
1539        TERRATEC_CINERGY_S,
1540        CYPRESS_DW3101,
1541        TEVII_S630,
1542        PROF_1100,
1543        TEVII_S660,
1544        PROF_7500,
1545        GENIATECH_SU3000,
1546        TERRATEC_CINERGY_S2,
1547        TEVII_S480_1,
1548        TEVII_S480_2,
1549        X3M_SPC1400HD,
1550        TEVII_S421,
1551        TEVII_S632,
1552        TERRATEC_CINERGY_S2_R2,
1553        GOTVIEW_SAT_HD,
1554        GENIATECH_T220,
1555};
1556
1557static struct usb_device_id dw2102_table[] = {
1558        [CYPRESS_DW2102] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
1559        [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
1560        [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
1561        [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
1562        [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
1563        [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
1564        [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
1565        [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1566        [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
1567        [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)},
1568        [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)},
1569        [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
1570        [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
1571        [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
1572        [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
1573        [TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)},
1574        [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)},
1575        [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)},
1576        [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)},
1577        [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)},
1578        { }
1579};
1580
1581MODULE_DEVICE_TABLE(usb, dw2102_table);
1582
1583static int dw2102_load_firmware(struct usb_device *dev,
1584                        const struct firmware *frmwr)
1585{
1586        u8 *b, *p;
1587        int ret = 0, i;
1588        u8 reset;
1589        u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
1590        const struct firmware *fw;
1591
1592        switch (dev->descriptor.idProduct) {
1593        case 0x2101:
1594                ret = request_firmware(&fw, DW2101_FIRMWARE, &dev->dev);
1595                if (ret != 0) {
1596                        err(err_str, DW2101_FIRMWARE);
1597                        return ret;
1598                }
1599                break;
1600        default:
1601                fw = frmwr;
1602                break;
1603        }
1604        info("start downloading DW210X firmware");
1605        p = kmalloc(fw->size, GFP_KERNEL);
1606        reset = 1;
1607        /*stop the CPU*/
1608        dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
1609        dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
1610
1611        if (p != NULL) {
1612                memcpy(p, fw->data, fw->size);
1613                for (i = 0; i < fw->size; i += 0x40) {
1614                        b = (u8 *) p + i;
1615                        if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
1616                                        DW210X_WRITE_MSG) != 0x40) {
1617                                err("error while transferring firmware");
1618                                ret = -EINVAL;
1619                                break;
1620                        }
1621                }
1622                /* restart the CPU */
1623                reset = 0;
1624                if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
1625                                        DW210X_WRITE_MSG) != 1) {
1626                        err("could not restart the USB controller CPU.");
1627                        ret = -EINVAL;
1628                }
1629                if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
1630                                        DW210X_WRITE_MSG) != 1) {
1631                        err("could not restart the USB controller CPU.");
1632                        ret = -EINVAL;
1633                }
1634                /* init registers */
1635                switch (dev->descriptor.idProduct) {
1636                case USB_PID_TEVII_S650:
1637                        dw2104_properties.rc.core.rc_codes = RC_MAP_TEVII_NEC;
1638                case USB_PID_DW2104:
1639                        reset = 1;
1640                        dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
1641                                        DW210X_WRITE_MSG);
1642                        /* break omitted intentionally */
1643                case USB_PID_DW3101:
1644                        reset = 0;
1645                        dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1646                                        DW210X_WRITE_MSG);
1647                        break;
1648                case USB_PID_CINERGY_S:
1649                case USB_PID_DW2102:
1650                        dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1651                                        DW210X_WRITE_MSG);
1652                        dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1653                                        DW210X_READ_MSG);
1654                        /* check STV0299 frontend  */
1655                        dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
1656                                        DW210X_READ_MSG);
1657                        if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
1658                                dw2102_properties.i2c_algo = &dw2102_i2c_algo;
1659                                dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach;
1660                                break;
1661                        } else {
1662                                /* check STV0288 frontend  */
1663                                reset16[0] = 0xd0;
1664                                reset16[1] = 1;
1665                                reset16[2] = 0;
1666                                dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
1667                                                DW210X_WRITE_MSG);
1668                                dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
1669                                                DW210X_READ_MSG);
1670                                if (reset16[2] == 0x11) {
1671                                        dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
1672                                        break;
1673                                }
1674                        }
1675                case 0x2101:
1676                        dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
1677                                        DW210X_READ_MSG);
1678                        dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1679                                        DW210X_READ_MSG);
1680                        dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1681                                        DW210X_READ_MSG);
1682                        dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1683                                        DW210X_READ_MSG);
1684                        break;
1685                }
1686
1687                msleep(100);
1688                kfree(p);
1689        }
1690        return ret;
1691}
1692
1693static struct dvb_usb_device_properties dw2102_properties = {
1694        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1695        .usb_ctrl = DEVICE_SPECIFIC,
1696        .firmware = DW2102_FIRMWARE,
1697        .no_reconnect = 1,
1698
1699        .i2c_algo = &dw2102_serit_i2c_algo,
1700
1701        .rc.core = {
1702                .rc_interval = 150,
1703                .rc_codes = RC_MAP_DM1105_NEC,
1704                .module_name = "dw2102",
1705                .allowed_protos   = RC_BIT_NEC,
1706                .rc_query = dw2102_rc_query,
1707        },
1708
1709        .generic_bulk_ctrl_endpoint = 0x81,
1710        /* parameter for the MPEG2-data transfer */
1711        .num_adapters = 1,
1712        .download_firmware = dw2102_load_firmware,
1713        .read_mac_address = dw210x_read_mac_address,
1714        .adapter = {
1715                {
1716                .num_frontends = 1,
1717                .fe = {{
1718                        .frontend_attach = dw2102_frontend_attach,
1719                        .stream = {
1720                                .type = USB_BULK,
1721                                .count = 8,
1722                                .endpoint = 0x82,
1723                                .u = {
1724                                        .bulk = {
1725                                                .buffersize = 4096,
1726                                        }
1727                                }
1728                        },
1729                }},
1730                }
1731        },
1732        .num_device_descs = 3,
1733        .devices = {
1734                {"DVBWorld DVB-S 2102 USB2.0",
1735                        {&dw2102_table[CYPRESS_DW2102], NULL},
1736                        {NULL},
1737                },
1738                {"DVBWorld DVB-S 2101 USB2.0",
1739                        {&dw2102_table[CYPRESS_DW2101], NULL},
1740                        {NULL},
1741                },
1742                {"TerraTec Cinergy S USB",
1743                        {&dw2102_table[TERRATEC_CINERGY_S], NULL},
1744                        {NULL},
1745                },
1746        }
1747};
1748
1749static struct dvb_usb_device_properties dw2104_properties = {
1750        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1751        .usb_ctrl = DEVICE_SPECIFIC,
1752        .firmware = DW2104_FIRMWARE,
1753        .no_reconnect = 1,
1754
1755        .i2c_algo = &dw2104_i2c_algo,
1756        .rc.core = {
1757                .rc_interval = 150,
1758                .rc_codes = RC_MAP_DM1105_NEC,
1759                .module_name = "dw2102",
1760                .allowed_protos   = RC_BIT_NEC,
1761                .rc_query = dw2102_rc_query,
1762        },
1763
1764        .generic_bulk_ctrl_endpoint = 0x81,
1765        /* parameter for the MPEG2-data transfer */
1766        .num_adapters = 1,
1767        .download_firmware = dw2102_load_firmware,
1768        .read_mac_address = dw210x_read_mac_address,
1769        .adapter = {
1770                {
1771                .num_frontends = 1,
1772                .fe = {{
1773                        .frontend_attach = dw2104_frontend_attach,
1774                        .stream = {
1775                                .type = USB_BULK,
1776                                .count = 8,
1777                                .endpoint = 0x82,
1778                                .u = {
1779                                        .bulk = {
1780                                                .buffersize = 4096,
1781                                        }
1782                                }
1783                        },
1784                }},
1785                }
1786        },
1787        .num_device_descs = 2,
1788        .devices = {
1789                { "DVBWorld DW2104 USB2.0",
1790                        {&dw2102_table[CYPRESS_DW2104], NULL},
1791                        {NULL},
1792                },
1793                { "TeVii S650 USB2.0",
1794                        {&dw2102_table[TEVII_S650], NULL},
1795                        {NULL},
1796                },
1797        }
1798};
1799
1800static struct dvb_usb_device_properties dw3101_properties = {
1801        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1802        .usb_ctrl = DEVICE_SPECIFIC,
1803        .firmware = DW3101_FIRMWARE,
1804        .no_reconnect = 1,
1805
1806        .i2c_algo = &dw3101_i2c_algo,
1807        .rc.core = {
1808                .rc_interval = 150,
1809                .rc_codes = RC_MAP_DM1105_NEC,
1810                .module_name = "dw2102",
1811                .allowed_protos   = RC_BIT_NEC,
1812                .rc_query = dw2102_rc_query,
1813        },
1814
1815        .generic_bulk_ctrl_endpoint = 0x81,
1816        /* parameter for the MPEG2-data transfer */
1817        .num_adapters = 1,
1818        .download_firmware = dw2102_load_firmware,
1819        .read_mac_address = dw210x_read_mac_address,
1820        .adapter = {
1821                {
1822                .num_frontends = 1,
1823                .fe = {{
1824                        .frontend_attach = dw3101_frontend_attach,
1825                        .tuner_attach = dw3101_tuner_attach,
1826                        .stream = {
1827                                .type = USB_BULK,
1828                                .count = 8,
1829                                .endpoint = 0x82,
1830                                .u = {
1831                                        .bulk = {
1832                                                .buffersize = 4096,
1833                                        }
1834                                }
1835                        },
1836                }},
1837                }
1838        },
1839        .num_device_descs = 1,
1840        .devices = {
1841                { "DVBWorld DVB-C 3101 USB2.0",
1842                        {&dw2102_table[CYPRESS_DW3101], NULL},
1843                        {NULL},
1844                },
1845        }
1846};
1847
1848static struct dvb_usb_device_properties s6x0_properties = {
1849        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1850        .usb_ctrl = DEVICE_SPECIFIC,
1851        .size_of_priv = sizeof(struct s6x0_state),
1852        .firmware = S630_FIRMWARE,
1853        .no_reconnect = 1,
1854
1855        .i2c_algo = &s6x0_i2c_algo,
1856        .rc.core = {
1857                .rc_interval = 150,
1858                .rc_codes = RC_MAP_TEVII_NEC,
1859                .module_name = "dw2102",
1860                .allowed_protos   = RC_BIT_NEC,
1861                .rc_query = dw2102_rc_query,
1862        },
1863
1864        .generic_bulk_ctrl_endpoint = 0x81,
1865        .num_adapters = 1,
1866        .download_firmware = dw2102_load_firmware,
1867        .read_mac_address = s6x0_read_mac_address,
1868        .adapter = {
1869                {
1870                .num_frontends = 1,
1871                .fe = {{
1872                        .frontend_attach = zl100313_frontend_attach,
1873                        .stream = {
1874                                .type = USB_BULK,
1875                                .count = 8,
1876                                .endpoint = 0x82,
1877                                .u = {
1878                                        .bulk = {
1879                                                .buffersize = 4096,
1880                                        }
1881                                }
1882                        },
1883                }},
1884                }
1885        },
1886        .num_device_descs = 1,
1887        .devices = {
1888                {"TeVii S630 USB",
1889                        {&dw2102_table[TEVII_S630], NULL},
1890                        {NULL},
1891                },
1892        }
1893};
1894
1895struct dvb_usb_device_properties *p1100;
1896static struct dvb_usb_device_description d1100 = {
1897        "Prof 1100 USB ",
1898        {&dw2102_table[PROF_1100], NULL},
1899        {NULL},
1900};
1901
1902struct dvb_usb_device_properties *s660;
1903static struct dvb_usb_device_description d660 = {
1904        "TeVii S660 USB",
1905        {&dw2102_table[TEVII_S660], NULL},
1906        {NULL},
1907};
1908
1909static struct dvb_usb_device_description d480_1 = {
1910        "TeVii S480.1 USB",
1911        {&dw2102_table[TEVII_S480_1], NULL},
1912        {NULL},
1913};
1914
1915static struct dvb_usb_device_description d480_2 = {
1916        "TeVii S480.2 USB",
1917        {&dw2102_table[TEVII_S480_2], NULL},
1918        {NULL},
1919};
1920
1921struct dvb_usb_device_properties *p7500;
1922static struct dvb_usb_device_description d7500 = {
1923        "Prof 7500 USB DVB-S2",
1924        {&dw2102_table[PROF_7500], NULL},
1925        {NULL},
1926};
1927
1928struct dvb_usb_device_properties *s421;
1929static struct dvb_usb_device_description d421 = {
1930        "TeVii S421 PCI",
1931        {&dw2102_table[TEVII_S421], NULL},
1932        {NULL},
1933};
1934
1935static struct dvb_usb_device_description d632 = {
1936        "TeVii S632 USB",
1937        {&dw2102_table[TEVII_S632], NULL},
1938        {NULL},
1939};
1940
1941static struct dvb_usb_device_properties su3000_properties = {
1942        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1943        .usb_ctrl = DEVICE_SPECIFIC,
1944        .size_of_priv = sizeof(struct su3000_state),
1945        .power_ctrl = su3000_power_ctrl,
1946        .num_adapters = 1,
1947        .identify_state = su3000_identify_state,
1948        .i2c_algo = &su3000_i2c_algo,
1949
1950        .rc.core = {
1951                .rc_interval = 150,
1952                .rc_codes = RC_MAP_SU3000,
1953                .module_name = "dw2102",
1954                .allowed_protos   = RC_BIT_RC5,
1955                .rc_query = su3000_rc_query,
1956        },
1957
1958        .read_mac_address = su3000_read_mac_address,
1959
1960        .generic_bulk_ctrl_endpoint = 0x01,
1961
1962        .adapter = {
1963                {
1964                .num_frontends = 1,
1965                .fe = {{
1966                        .streaming_ctrl   = su3000_streaming_ctrl,
1967                        .frontend_attach  = su3000_frontend_attach,
1968                        .stream = {
1969                                .type = USB_BULK,
1970                                .count = 8,
1971                                .endpoint = 0x82,
1972                                .u = {
1973                                        .bulk = {
1974                                                .buffersize = 4096,
1975                                        }
1976                                }
1977                        }
1978                }},
1979                }
1980        },
1981        .num_device_descs = 5,
1982        .devices = {
1983                { "SU3000HD DVB-S USB2.0",
1984                        { &dw2102_table[GENIATECH_SU3000], NULL },
1985                        { NULL },
1986                },
1987                { "Terratec Cinergy S2 USB HD",
1988                        { &dw2102_table[TERRATEC_CINERGY_S2], NULL },
1989                        { NULL },
1990                },
1991                { "X3M TV SPC1400HD PCI",
1992                        { &dw2102_table[X3M_SPC1400HD], NULL },
1993                        { NULL },
1994                },
1995                { "Terratec Cinergy S2 USB HD Rev.2",
1996                        { &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL },
1997                        { NULL },
1998                },
1999                { "GOTVIEW Satellite HD",
2000                        { &dw2102_table[GOTVIEW_SAT_HD], NULL },
2001                        { NULL },
2002                },
2003        }
2004};
2005
2006static struct dvb_usb_device_properties t220_properties = {
2007        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2008        .usb_ctrl = DEVICE_SPECIFIC,
2009        .size_of_priv = sizeof(struct su3000_state),
2010        .power_ctrl = su3000_power_ctrl,
2011        .num_adapters = 1,
2012        .identify_state = su3000_identify_state,
2013        .i2c_algo = &su3000_i2c_algo,
2014
2015        .rc.core = {
2016                .rc_interval = 150,
2017                .rc_codes = RC_MAP_SU3000,
2018                .module_name = "dw2102",
2019                .allowed_protos   = RC_BIT_RC5,
2020                .rc_query = su3000_rc_query,
2021        },
2022
2023        .read_mac_address = su3000_read_mac_address,
2024
2025        .generic_bulk_ctrl_endpoint = 0x01,
2026
2027        .adapter = {
2028                {
2029                .num_frontends = 1,
2030                .fe = { {
2031                        .streaming_ctrl   = su3000_streaming_ctrl,
2032                        .frontend_attach  = t220_frontend_attach,
2033                        .stream = {
2034                                .type = USB_BULK,
2035                                .count = 8,
2036                                .endpoint = 0x82,
2037                                .u = {
2038                                        .bulk = {
2039                                                .buffersize = 4096,
2040                                        }
2041                                }
2042                        }
2043                } },
2044                }
2045        },
2046        .num_device_descs = 1,
2047        .devices = {
2048                { "Geniatech T220 DVB-T/T2 USB2.0",
2049                        { &dw2102_table[GENIATECH_T220], NULL },
2050                        { NULL },
2051                },
2052        }
2053};
2054
2055static int dw2102_probe(struct usb_interface *intf,
2056                const struct usb_device_id *id)
2057{
2058        p1100 = kmemdup(&s6x0_properties,
2059                        sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
2060        if (!p1100)
2061                return -ENOMEM;
2062        /* copy default structure */
2063        /* fill only different fields */
2064        p1100->firmware = P1100_FIRMWARE;
2065        p1100->devices[0] = d1100;
2066        p1100->rc.core.rc_query = prof_rc_query;
2067        p1100->rc.core.rc_codes = RC_MAP_TBS_NEC;
2068        p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
2069
2070        s660 = kmemdup(&s6x0_properties,
2071                       sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
2072        if (!s660) {
2073                kfree(p1100);
2074                return -ENOMEM;
2075        }
2076        s660->firmware = S660_FIRMWARE;
2077        s660->num_device_descs = 3;
2078        s660->devices[0] = d660;
2079        s660->devices[1] = d480_1;
2080        s660->devices[2] = d480_2;
2081        s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach;
2082
2083        p7500 = kmemdup(&s6x0_properties,
2084                        sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
2085        if (!p7500) {
2086                kfree(p1100);
2087                kfree(s660);
2088                return -ENOMEM;
2089        }
2090        p7500->firmware = P7500_FIRMWARE;
2091        p7500->devices[0] = d7500;
2092        p7500->rc.core.rc_query = prof_rc_query;
2093        p7500->rc.core.rc_codes = RC_MAP_TBS_NEC;
2094        p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach;
2095
2096
2097        s421 = kmemdup(&su3000_properties,
2098                       sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
2099        if (!s421) {
2100                kfree(p1100);
2101                kfree(s660);
2102                kfree(p7500);
2103                return -ENOMEM;
2104        }
2105        s421->num_device_descs = 2;
2106        s421->devices[0] = d421;
2107        s421->devices[1] = d632;
2108        s421->adapter->fe[0].frontend_attach = m88rs2000_frontend_attach;
2109
2110        if (0 == dvb_usb_device_init(intf, &dw2102_properties,
2111                        THIS_MODULE, NULL, adapter_nr) ||
2112            0 == dvb_usb_device_init(intf, &dw2104_properties,
2113                        THIS_MODULE, NULL, adapter_nr) ||
2114            0 == dvb_usb_device_init(intf, &dw3101_properties,
2115                        THIS_MODULE, NULL, adapter_nr) ||
2116            0 == dvb_usb_device_init(intf, &s6x0_properties,
2117                        THIS_MODULE, NULL, adapter_nr) ||
2118            0 == dvb_usb_device_init(intf, p1100,
2119                        THIS_MODULE, NULL, adapter_nr) ||
2120            0 == dvb_usb_device_init(intf, s660,
2121                        THIS_MODULE, NULL, adapter_nr) ||
2122            0 == dvb_usb_device_init(intf, p7500,
2123                        THIS_MODULE, NULL, adapter_nr) ||
2124            0 == dvb_usb_device_init(intf, s421,
2125                        THIS_MODULE, NULL, adapter_nr) ||
2126            0 == dvb_usb_device_init(intf, &su3000_properties,
2127                         THIS_MODULE, NULL, adapter_nr) ||
2128            0 == dvb_usb_device_init(intf, &t220_properties,
2129                         THIS_MODULE, NULL, adapter_nr))
2130                return 0;
2131
2132        return -ENODEV;
2133}
2134
2135static struct usb_driver dw2102_driver = {
2136        .name = "dw2102",
2137        .probe = dw2102_probe,
2138        .disconnect = dvb_usb_device_exit,
2139        .id_table = dw2102_table,
2140};
2141
2142module_usb_driver(dw2102_driver);
2143
2144MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
2145MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
2146                        " DVB-C 3101 USB2.0,"
2147                        " TeVii S600, S630, S650, S660, S480, S421, S632"
2148                        " Prof 1100, 7500 USB2.0,"
2149                        " Geniatech SU3000, T220 devices");
2150MODULE_VERSION("0.1");
2151MODULE_LICENSE("GPL");
2152MODULE_FIRMWARE(DW2101_FIRMWARE);
2153MODULE_FIRMWARE(DW2102_FIRMWARE);
2154MODULE_FIRMWARE(DW2104_FIRMWARE);
2155MODULE_FIRMWARE(DW3101_FIRMWARE);
2156MODULE_FIRMWARE(S630_FIRMWARE);
2157MODULE_FIRMWARE(S660_FIRMWARE);
2158MODULE_FIRMWARE(P1100_FIRMWARE);
2159MODULE_FIRMWARE(P7500_FIRMWARE);
2160