linux/drivers/media/usb/dvb-usb/ttusb2.c
<<
>>
Prefs
   1/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
   2 * (e.g. Pinnacle 400e DVB-S USB2.0).
   3 *
   4 * The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes.
   5 *
   6 * TDA8263 + TDA10086
   7 *
   8 * I2C addresses:
   9 * 0x08 - LNBP21PD   - LNB power supply
  10 * 0x0e - TDA10086   - Demodulator
  11 * 0x50 - FX2 eeprom
  12 * 0x60 - TDA8263    - Tuner
  13 * 0x78 ???
  14 *
  15 * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
  16 * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
  17 * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.org>
  18 *
  19 *      This program is free software; you can redistribute it and/or modify it
  20 *      under the terms of the GNU General Public License as published by the Free
  21 *      Software Foundation, version 2.
  22 *
  23 * see Documentation/dvb/README.dvb-usb for more information
  24 */
  25#define DVB_USB_LOG_PREFIX "ttusb2"
  26#include "dvb-usb.h"
  27
  28#include "ttusb2.h"
  29
  30#include "tda826x.h"
  31#include "tda10086.h"
  32#include "tda1002x.h"
  33#include "tda10048.h"
  34#include "tda827x.h"
  35#include "lnbp21.h"
  36/* CA */
  37#include "dvb_ca_en50221.h"
  38
  39/* debug */
  40static int dvb_usb_ttusb2_debug;
  41#define deb_info(args...)   dprintk(dvb_usb_ttusb2_debug,0x01,args)
  42module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644);
  43MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS);
  44static int dvb_usb_ttusb2_debug_ci;
  45module_param_named(debug_ci,dvb_usb_ttusb2_debug_ci, int, 0644);
  46MODULE_PARM_DESC(debug_ci, "set debugging ci." DVB_USB_DEBUG_STATUS);
  47
  48DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  49
  50#define ci_dbg(format, arg...)                \
  51do {                                          \
  52        if (dvb_usb_ttusb2_debug_ci)                                    \
  53                printk(KERN_DEBUG DVB_USB_LOG_PREFIX \
  54                        ": %s " format "\n" , __func__, ## arg);       \
  55} while (0)
  56
  57enum {
  58        TT3650_CMD_CI_TEST = 0x40,
  59        TT3650_CMD_CI_RD_CTRL,
  60        TT3650_CMD_CI_WR_CTRL,
  61        TT3650_CMD_CI_RD_ATTR,
  62        TT3650_CMD_CI_WR_ATTR,
  63        TT3650_CMD_CI_RESET,
  64        TT3650_CMD_CI_SET_VIDEO_PORT
  65};
  66
  67struct ttusb2_state {
  68        struct dvb_ca_en50221 ca;
  69        struct mutex ca_mutex;
  70        u8 id;
  71        u16 last_rc_key;
  72};
  73
  74static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
  75                u8 *wbuf, int wlen, u8 *rbuf, int rlen)
  76{
  77        struct ttusb2_state *st = d->priv;
  78        u8 *s, *r = NULL;
  79        int ret = 0;
  80
  81        if (4 + rlen > 64)
  82                return -EIO;
  83
  84        s = kzalloc(wlen+4, GFP_KERNEL);
  85        if (!s)
  86                return -ENOMEM;
  87
  88        r = kzalloc(64, GFP_KERNEL);
  89        if (!r) {
  90                kfree(s);
  91                return -ENOMEM;
  92        }
  93
  94        s[0] = 0xaa;
  95        s[1] = ++st->id;
  96        s[2] = cmd;
  97        s[3] = wlen;
  98        memcpy(&s[4],wbuf,wlen);
  99
 100        ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0);
 101
 102        if (ret  != 0 ||
 103                r[0] != 0x55 ||
 104                r[1] != s[1] ||
 105                r[2] != cmd ||
 106                (rlen > 0 && r[3] != rlen)) {
 107                warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
 108                kfree(s);
 109                kfree(r);
 110                return -EIO;
 111        }
 112
 113        if (rlen > 0)
 114                memcpy(rbuf, &r[4], rlen);
 115
 116        kfree(s);
 117        kfree(r);
 118
 119        return 0;
 120}
 121
 122/* ci */
 123static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
 124{
 125        int ret;
 126        u8 rx[60];/* (64 -4) */
 127        ret = ttusb2_msg(d, cmd, data, write_len, rx, read_len);
 128        if (!ret)
 129                memcpy(data, rx, read_len);
 130        return ret;
 131}
 132
 133static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
 134{
 135        struct dvb_usb_device *d = ca->data;
 136        struct ttusb2_state *state = d->priv;
 137        int ret;
 138
 139        mutex_lock(&state->ca_mutex);
 140        ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
 141        mutex_unlock(&state->ca_mutex);
 142
 143        return ret;
 144}
 145
 146static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
 147{
 148        u8 buf[3];
 149        int ret = 0;
 150
 151        if (slot)
 152                return -EINVAL;
 153
 154        buf[0] = (address >> 8) & 0x0F;
 155        buf[1] = address;
 156
 157
 158        ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3);
 159
 160        ci_dbg("%04x -> %d 0x%02x", address, ret, buf[2]);
 161
 162        if (ret < 0)
 163                return ret;
 164
 165        return buf[2];
 166}
 167
 168static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
 169{
 170        u8 buf[3];
 171
 172        ci_dbg("%d 0x%04x 0x%02x", slot, address, value);
 173
 174        if (slot)
 175                return -EINVAL;
 176
 177        buf[0] = (address >> 8) & 0x0F;
 178        buf[1] = address;
 179        buf[2] = value;
 180
 181        return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3);
 182}
 183
 184static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
 185{
 186        u8 buf[2];
 187        int ret;
 188
 189        if (slot)
 190                return -EINVAL;
 191
 192        buf[0] = address & 3;
 193
 194        ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2);
 195
 196        ci_dbg("0x%02x -> %d 0x%02x", address, ret, buf[1]);
 197
 198        if (ret < 0)
 199                return ret;
 200
 201        return buf[1];
 202}
 203
 204static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
 205{
 206        u8 buf[2];
 207
 208        ci_dbg("%d 0x%02x 0x%02x", slot, address, value);
 209
 210        if (slot)
 211                return -EINVAL;
 212
 213        buf[0] = address;
 214        buf[1] = value;
 215
 216        return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2);
 217}
 218
 219static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca, int slot, int enable)
 220{
 221        u8 buf[1];
 222        int ret;
 223
 224        ci_dbg("%d %d", slot, enable);
 225
 226        if (slot)
 227                return -EINVAL;
 228
 229        buf[0] = enable;
 230
 231        ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
 232        if (ret < 0)
 233                return ret;
 234
 235        if (enable != buf[0]) {
 236                err("CI not %sabled.", enable ? "en" : "dis");
 237                return -EIO;
 238        }
 239
 240        return 0;
 241}
 242
 243static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
 244{
 245        return tt3650_ci_set_video_port(ca, slot, 0);
 246}
 247
 248static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
 249{
 250        return tt3650_ci_set_video_port(ca, slot, 1);
 251}
 252
 253static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
 254{
 255        struct dvb_usb_device *d = ca->data;
 256        struct ttusb2_state *state = d->priv;
 257        u8 buf[1];
 258        int ret;
 259
 260        ci_dbg("%d", slot);
 261
 262        if (slot)
 263                return -EINVAL;
 264
 265        buf[0] = 0;
 266
 267        mutex_lock(&state->ca_mutex);
 268
 269        ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
 270        if (ret)
 271                goto failed;
 272
 273        msleep(500);
 274
 275        buf[0] = 1;
 276
 277        ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
 278        if (ret)
 279                goto failed;
 280
 281        msleep(500);
 282
 283        buf[0] = 0; /* FTA */
 284
 285        ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
 286
 287        msleep(1100);
 288
 289 failed:
 290        mutex_unlock(&state->ca_mutex);
 291
 292        return ret;
 293}
 294
 295static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
 296{
 297        u8 buf[1];
 298        int ret;
 299
 300        if (slot)
 301                return -EINVAL;
 302
 303        ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1);
 304        if (ret)
 305                return ret;
 306
 307        if (1 == buf[0]) {
 308                return DVB_CA_EN50221_POLL_CAM_PRESENT |
 309                        DVB_CA_EN50221_POLL_CAM_READY;
 310        }
 311        return 0;
 312}
 313
 314static void tt3650_ci_uninit(struct dvb_usb_device *d)
 315{
 316        struct ttusb2_state *state;
 317
 318        ci_dbg("");
 319
 320        if (NULL == d)
 321                return;
 322
 323        state = d->priv;
 324        if (NULL == state)
 325                return;
 326
 327        if (NULL == state->ca.data)
 328                return;
 329
 330        dvb_ca_en50221_release(&state->ca);
 331
 332        memset(&state->ca, 0, sizeof(state->ca));
 333}
 334
 335static int tt3650_ci_init(struct dvb_usb_adapter *a)
 336{
 337        struct dvb_usb_device *d = a->dev;
 338        struct ttusb2_state *state = d->priv;
 339        int ret;
 340
 341        ci_dbg("");
 342
 343        mutex_init(&state->ca_mutex);
 344
 345        state->ca.owner = THIS_MODULE;
 346        state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
 347        state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
 348        state->ca.read_cam_control = tt3650_ci_read_cam_control;
 349        state->ca.write_cam_control = tt3650_ci_write_cam_control;
 350        state->ca.slot_reset = tt3650_ci_slot_reset;
 351        state->ca.slot_shutdown = tt3650_ci_slot_shutdown;
 352        state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
 353        state->ca.poll_slot_status = tt3650_ci_poll_slot_status;
 354        state->ca.data = d;
 355
 356        ret = dvb_ca_en50221_init(&a->dvb_adap,
 357                                  &state->ca,
 358                                  /* flags */ 0,
 359                                  /* n_slots */ 1);
 360        if (ret) {
 361                err("Cannot initialize CI: Error %d.", ret);
 362                memset(&state->ca, 0, sizeof(state->ca));
 363                return ret;
 364        }
 365
 366        info("CI initialized.");
 367
 368        return 0;
 369}
 370
 371static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
 372{
 373        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 374        static u8 obuf[60], ibuf[60];
 375        int i, write_read, read;
 376
 377        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 378                return -EAGAIN;
 379
 380        if (num > 2)
 381                warn("more than 2 i2c messages at a time is not handled yet. TODO.");
 382
 383        for (i = 0; i < num; i++) {
 384                write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
 385                read = msg[i].flags & I2C_M_RD;
 386
 387                if (3 + msg[i].len > sizeof(obuf)) {
 388                        err("i2c wr len=%d too high", msg[i].len);
 389                        break;
 390                }
 391                if (write_read) {
 392                        if (3 + msg[i+1].len > sizeof(ibuf)) {
 393                                err("i2c rd len=%d too high", msg[i+1].len);
 394                                break;
 395                        }
 396                } else if (read) {
 397                        if (3 + msg[i].len > sizeof(ibuf)) {
 398                                err("i2c rd len=%d too high", msg[i].len);
 399                                break;
 400                        }
 401                }
 402
 403                obuf[0] = (msg[i].addr << 1) | (write_read | read);
 404                if (read)
 405                        obuf[1] = 0;
 406                else
 407                        obuf[1] = msg[i].len;
 408
 409                /* read request */
 410                if (write_read)
 411                        obuf[2] = msg[i+1].len;
 412                else if (read)
 413                        obuf[2] = msg[i].len;
 414                else
 415                        obuf[2] = 0;
 416
 417                memcpy(&obuf[3], msg[i].buf, msg[i].len);
 418
 419                if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) {
 420                        err("i2c transfer failed.");
 421                        break;
 422                }
 423
 424                if (write_read) {
 425                        memcpy(msg[i+1].buf, &ibuf[3], msg[i+1].len);
 426                        i++;
 427                } else if (read)
 428                        memcpy(msg[i].buf, &ibuf[3], msg[i].len);
 429        }
 430
 431        mutex_unlock(&d->i2c_mutex);
 432        return i;
 433}
 434
 435static u32 ttusb2_i2c_func(struct i2c_adapter *adapter)
 436{
 437        return I2C_FUNC_I2C;
 438}
 439
 440static struct i2c_algorithm ttusb2_i2c_algo = {
 441        .master_xfer   = ttusb2_i2c_xfer,
 442        .functionality = ttusb2_i2c_func,
 443};
 444
 445/* command to poll IR receiver (copied from pctv452e.c) */
 446#define CMD_GET_IR_CODE     0x1b
 447
 448/* IR */
 449static int tt3650_rc_query(struct dvb_usb_device *d)
 450{
 451        int ret;
 452        u8 rx[9]; /* A CMD_GET_IR_CODE reply is 9 bytes long */
 453        struct ttusb2_state *st = d->priv;
 454        ret = ttusb2_msg(d, CMD_GET_IR_CODE, NULL, 0, rx, sizeof(rx));
 455        if (ret != 0)
 456                return ret;
 457
 458        if (rx[8] & 0x01) {
 459                /* got a "press" event */
 460                st->last_rc_key = RC_SCANCODE_RC5(rx[3], rx[2]);
 461                deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]);
 462                rc_keydown(d->rc_dev, RC_PROTO_RC5, st->last_rc_key, rx[1]);
 463        } else if (st->last_rc_key) {
 464                rc_keyup(d->rc_dev);
 465                st->last_rc_key = 0;
 466        }
 467
 468        return 0;
 469}
 470
 471
 472/* Callbacks for DVB USB */
 473static int ttusb2_identify_state (struct usb_device *udev, struct
 474                dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
 475                int *cold)
 476{
 477        *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
 478        return 0;
 479}
 480
 481static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
 482{
 483        u8 b = onoff;
 484        ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
 485        return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
 486}
 487
 488
 489static struct tda10086_config tda10086_config = {
 490        .demod_address = 0x0e,
 491        .invert = 0,
 492        .diseqc_tone = 1,
 493        .xtal_freq = TDA10086_XTAL_16M,
 494};
 495
 496static struct tda10023_config tda10023_config = {
 497        .demod_address = 0x0c,
 498        .invert = 0,
 499        .xtal = 16000000,
 500        .pll_m = 11,
 501        .pll_p = 3,
 502        .pll_n = 1,
 503        .deltaf = 0xa511,
 504};
 505
 506static struct tda10048_config tda10048_config = {
 507        .demod_address    = 0x10 >> 1,
 508        .output_mode      = TDA10048_PARALLEL_OUTPUT,
 509        .inversion        = TDA10048_INVERSION_ON,
 510        .dtv6_if_freq_khz = TDA10048_IF_4000,
 511        .dtv7_if_freq_khz = TDA10048_IF_4500,
 512        .dtv8_if_freq_khz = TDA10048_IF_5000,
 513        .clk_freq_khz     = TDA10048_CLK_16000,
 514        .no_firmware      = 1,
 515        .set_pll          = true ,
 516        .pll_m            = 5,
 517        .pll_n            = 3,
 518        .pll_p            = 0,
 519};
 520
 521static struct tda827x_config tda827x_config = {
 522        .config = 0,
 523};
 524
 525static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
 526{
 527        if (usb_set_interface(adap->dev->udev,0,3) < 0)
 528                err("set interface to alts=3 failed");
 529
 530        if ((adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) {
 531                deb_info("TDA10086 attach failed\n");
 532                return -ENODEV;
 533        }
 534
 535        return 0;
 536}
 537
 538static int ttusb2_ct3650_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 539{
 540        struct dvb_usb_adapter *adap = fe->dvb->priv;
 541
 542        return adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, enable);
 543}
 544
 545static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
 546{
 547        if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
 548                err("set interface to alts=3 failed");
 549
 550        if (adap->fe_adap[0].fe == NULL) {
 551                /* FE 0 DVB-C */
 552                adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
 553                        &tda10023_config, &adap->dev->i2c_adap, 0x48);
 554
 555                if (adap->fe_adap[0].fe == NULL) {
 556                        deb_info("TDA10023 attach failed\n");
 557                        return -ENODEV;
 558                }
 559                tt3650_ci_init(adap);
 560        } else {
 561                adap->fe_adap[1].fe = dvb_attach(tda10048_attach,
 562                        &tda10048_config, &adap->dev->i2c_adap);
 563
 564                if (adap->fe_adap[1].fe == NULL) {
 565                        deb_info("TDA10048 attach failed\n");
 566                        return -ENODEV;
 567                }
 568
 569                /* tuner is behind TDA10023 I2C-gate */
 570                adap->fe_adap[1].fe->ops.i2c_gate_ctrl = ttusb2_ct3650_i2c_gate_ctrl;
 571
 572        }
 573
 574        return 0;
 575}
 576
 577static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
 578{
 579        struct dvb_frontend *fe;
 580
 581        /* MFE: select correct FE to attach tuner since that's called twice */
 582        if (adap->fe_adap[1].fe == NULL)
 583                fe = adap->fe_adap[0].fe;
 584        else
 585                fe = adap->fe_adap[1].fe;
 586
 587        /* attach tuner */
 588        if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) {
 589                printk(KERN_ERR "%s: No tda827x found!\n", __func__);
 590                return -ENODEV;
 591        }
 592        return 0;
 593}
 594
 595static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap)
 596{
 597        if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
 598                deb_info("TDA8263 attach failed\n");
 599                return -ENODEV;
 600        }
 601
 602        if (dvb_attach(lnbp21_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0, 0) == NULL) {
 603                deb_info("LNBP21 attach failed\n");
 604                return -ENODEV;
 605        }
 606        return 0;
 607}
 608
 609/* DVB USB Driver stuff */
 610static struct dvb_usb_device_properties ttusb2_properties;
 611static struct dvb_usb_device_properties ttusb2_properties_s2400;
 612static struct dvb_usb_device_properties ttusb2_properties_ct3650;
 613
 614static void ttusb2_usb_disconnect(struct usb_interface *intf)
 615{
 616        struct dvb_usb_device *d = usb_get_intfdata(intf);
 617
 618        tt3650_ci_uninit(d);
 619        dvb_usb_device_exit(intf);
 620}
 621
 622static int ttusb2_probe(struct usb_interface *intf,
 623                const struct usb_device_id *id)
 624{
 625        if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
 626                                     THIS_MODULE, NULL, adapter_nr) ||
 627            0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
 628                                     THIS_MODULE, NULL, adapter_nr) ||
 629            0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650,
 630                                     THIS_MODULE, NULL, adapter_nr))
 631                return 0;
 632        return -ENODEV;
 633}
 634
 635static struct usb_device_id ttusb2_table [] = {
 636        { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
 637        { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
 638        { USB_DEVICE(USB_VID_TECHNOTREND,
 639                USB_PID_TECHNOTREND_CONNECT_S2400) },
 640        { USB_DEVICE(USB_VID_TECHNOTREND,
 641                USB_PID_TECHNOTREND_CONNECT_CT3650) },
 642        { USB_DEVICE(USB_VID_TECHNOTREND,
 643                USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM) },
 644        {}              /* Terminating entry */
 645};
 646MODULE_DEVICE_TABLE (usb, ttusb2_table);
 647
 648static struct dvb_usb_device_properties ttusb2_properties = {
 649        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 650
 651        .usb_ctrl = CYPRESS_FX2,
 652        .firmware = "dvb-usb-pctv-400e-01.fw",
 653
 654        .size_of_priv = sizeof(struct ttusb2_state),
 655
 656        .num_adapters = 1,
 657        .adapter = {
 658                {
 659                .num_frontends = 1,
 660                .fe = {{
 661                        .streaming_ctrl   = NULL, // ttusb2_streaming_ctrl,
 662
 663                        .frontend_attach  = ttusb2_frontend_tda10086_attach,
 664                        .tuner_attach     = ttusb2_tuner_tda826x_attach,
 665
 666                        /* parameter for the MPEG2-data transfer */
 667                        .stream = {
 668                                .type = USB_ISOC,
 669                                .count = 5,
 670                                .endpoint = 0x02,
 671                                .u = {
 672                                        .isoc = {
 673                                                .framesperurb = 4,
 674                                                .framesize = 940,
 675                                                .interval = 1,
 676                                        }
 677                                }
 678                        }
 679                }},
 680                }
 681        },
 682
 683        .power_ctrl       = ttusb2_power_ctrl,
 684        .identify_state   = ttusb2_identify_state,
 685
 686        .i2c_algo         = &ttusb2_i2c_algo,
 687
 688        .generic_bulk_ctrl_endpoint = 0x01,
 689
 690        .num_device_descs = 2,
 691        .devices = {
 692                {   "Pinnacle 400e DVB-S USB2.0",
 693                        { &ttusb2_table[0], NULL },
 694                        { NULL },
 695                },
 696                {   "Pinnacle 450e DVB-S USB2.0",
 697                        { &ttusb2_table[1], NULL },
 698                        { NULL },
 699                },
 700        }
 701};
 702
 703static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
 704        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 705
 706        .usb_ctrl = CYPRESS_FX2,
 707        .firmware = "dvb-usb-tt-s2400-01.fw",
 708
 709        .size_of_priv = sizeof(struct ttusb2_state),
 710
 711        .num_adapters = 1,
 712        .adapter = {
 713                {
 714                .num_frontends = 1,
 715                .fe = {{
 716                        .streaming_ctrl   = NULL,
 717
 718                        .frontend_attach  = ttusb2_frontend_tda10086_attach,
 719                        .tuner_attach     = ttusb2_tuner_tda826x_attach,
 720
 721                        /* parameter for the MPEG2-data transfer */
 722                        .stream = {
 723                                .type = USB_ISOC,
 724                                .count = 5,
 725                                .endpoint = 0x02,
 726                                .u = {
 727                                        .isoc = {
 728                                                .framesperurb = 4,
 729                                                .framesize = 940,
 730                                                .interval = 1,
 731                                        }
 732                                }
 733                        }
 734                }},
 735                }
 736        },
 737
 738        .power_ctrl       = ttusb2_power_ctrl,
 739        .identify_state   = ttusb2_identify_state,
 740
 741        .i2c_algo         = &ttusb2_i2c_algo,
 742
 743        .generic_bulk_ctrl_endpoint = 0x01,
 744
 745        .num_device_descs = 2,
 746        .devices = {
 747                {   "Technotrend TT-connect S-2400",
 748                        { &ttusb2_table[2], NULL },
 749                        { NULL },
 750                },
 751                {   "Technotrend TT-connect S-2400 (8kB EEPROM)",
 752                        { &ttusb2_table[4], NULL },
 753                        { NULL },
 754                },
 755        }
 756};
 757
 758static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
 759        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 760
 761        .usb_ctrl = CYPRESS_FX2,
 762
 763        .size_of_priv = sizeof(struct ttusb2_state),
 764
 765        .rc.core = {
 766                .rc_interval      = 150, /* Less than IR_KEYPRESS_TIMEOUT */
 767                .rc_codes         = RC_MAP_TT_1500,
 768                .rc_query         = tt3650_rc_query,
 769                .allowed_protos   = RC_PROTO_BIT_RC5,
 770        },
 771
 772        .num_adapters = 1,
 773        .adapter = {
 774                {
 775                .num_frontends = 2,
 776                .fe = {{
 777                        .streaming_ctrl   = NULL,
 778
 779                        .frontend_attach  = ttusb2_frontend_tda10023_attach,
 780                        .tuner_attach = ttusb2_tuner_tda827x_attach,
 781
 782                        /* parameter for the MPEG2-data transfer */
 783                        .stream = {
 784                                .type = USB_ISOC,
 785                                .count = 5,
 786                                .endpoint = 0x02,
 787                                .u = {
 788                                        .isoc = {
 789                                                .framesperurb = 4,
 790                                                .framesize = 940,
 791                                                .interval = 1,
 792                                        }
 793                                }
 794                        }
 795                }, {
 796                        .streaming_ctrl   = NULL,
 797
 798                        .frontend_attach  = ttusb2_frontend_tda10023_attach,
 799                        .tuner_attach = ttusb2_tuner_tda827x_attach,
 800
 801                        /* parameter for the MPEG2-data transfer */
 802                        .stream = {
 803                                .type = USB_ISOC,
 804                                .count = 5,
 805                                .endpoint = 0x02,
 806                                .u = {
 807                                        .isoc = {
 808                                                .framesperurb = 4,
 809                                                .framesize = 940,
 810                                                .interval = 1,
 811                                        }
 812                                }
 813                        }
 814                }},
 815                },
 816        },
 817
 818        .power_ctrl       = ttusb2_power_ctrl,
 819        .identify_state   = ttusb2_identify_state,
 820
 821        .i2c_algo         = &ttusb2_i2c_algo,
 822
 823        .generic_bulk_ctrl_endpoint = 0x01,
 824
 825        .num_device_descs = 1,
 826        .devices = {
 827                {   "Technotrend TT-connect CT-3650",
 828                        .warm_ids = { &ttusb2_table[3], NULL },
 829                },
 830        }
 831};
 832
 833static struct usb_driver ttusb2_driver = {
 834        .name           = "dvb_usb_ttusb2",
 835        .probe          = ttusb2_probe,
 836        .disconnect     = ttusb2_usb_disconnect,
 837        .id_table       = ttusb2_table,
 838};
 839
 840module_usb_driver(ttusb2_driver);
 841
 842MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 843MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");
 844MODULE_VERSION("1.0");
 845MODULE_LICENSE("GPL");
 846