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