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