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