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