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/media/dvb-drivers/dvb-usb.rst 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 <media/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,
 474                                 const struct dvb_usb_device_properties *props,
 475                                 const struct dvb_usb_device_description **desc,
 476                                 int *cold)
 477{
 478        *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
 479        return 0;
 480}
 481
 482static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
 483{
 484        u8 b = onoff;
 485        ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
 486        return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
 487}
 488
 489
 490static struct tda10086_config tda10086_config = {
 491        .demod_address = 0x0e,
 492        .invert = 0,
 493        .diseqc_tone = 1,
 494        .xtal_freq = TDA10086_XTAL_16M,
 495};
 496
 497static struct tda10023_config tda10023_config = {
 498        .demod_address = 0x0c,
 499        .invert = 0,
 500        .xtal = 16000000,
 501        .pll_m = 11,
 502        .pll_p = 3,
 503        .pll_n = 1,
 504        .deltaf = 0xa511,
 505};
 506
 507static struct tda10048_config tda10048_config = {
 508        .demod_address    = 0x10 >> 1,
 509        .output_mode      = TDA10048_PARALLEL_OUTPUT,
 510        .inversion        = TDA10048_INVERSION_ON,
 511        .dtv6_if_freq_khz = TDA10048_IF_4000,
 512        .dtv7_if_freq_khz = TDA10048_IF_4500,
 513        .dtv8_if_freq_khz = TDA10048_IF_5000,
 514        .clk_freq_khz     = TDA10048_CLK_16000,
 515        .no_firmware      = 1,
 516        .set_pll          = true ,
 517        .pll_m            = 5,
 518        .pll_n            = 3,
 519        .pll_p            = 0,
 520};
 521
 522static struct tda827x_config tda827x_config = {
 523        .config = 0,
 524};
 525
 526static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
 527{
 528        if (usb_set_interface(adap->dev->udev,0,3) < 0)
 529                err("set interface to alts=3 failed");
 530
 531        if ((adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) {
 532                deb_info("TDA10086 attach failed\n");
 533                return -ENODEV;
 534        }
 535
 536        return 0;
 537}
 538
 539static int ttusb2_ct3650_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 540{
 541        struct dvb_usb_adapter *adap = fe->dvb->priv;
 542
 543        return adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, enable);
 544}
 545
 546static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
 547{
 548        if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
 549                err("set interface to alts=3 failed");
 550
 551        if (adap->fe_adap[0].fe == NULL) {
 552                /* FE 0 DVB-C */
 553                adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
 554                        &tda10023_config, &adap->dev->i2c_adap, 0x48);
 555
 556                if (adap->fe_adap[0].fe == NULL) {
 557                        deb_info("TDA10023 attach failed\n");
 558                        return -ENODEV;
 559                }
 560                tt3650_ci_init(adap);
 561        } else {
 562                adap->fe_adap[1].fe = dvb_attach(tda10048_attach,
 563                        &tda10048_config, &adap->dev->i2c_adap);
 564
 565                if (adap->fe_adap[1].fe == NULL) {
 566                        deb_info("TDA10048 attach failed\n");
 567                        return -ENODEV;
 568                }
 569
 570                /* tuner is behind TDA10023 I2C-gate */
 571                adap->fe_adap[1].fe->ops.i2c_gate_ctrl = ttusb2_ct3650_i2c_gate_ctrl;
 572
 573        }
 574
 575        return 0;
 576}
 577
 578static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
 579{
 580        struct dvb_frontend *fe;
 581
 582        /* MFE: select correct FE to attach tuner since that's called twice */
 583        if (adap->fe_adap[1].fe == NULL)
 584                fe = adap->fe_adap[0].fe;
 585        else
 586                fe = adap->fe_adap[1].fe;
 587
 588        /* attach tuner */
 589        if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) {
 590                printk(KERN_ERR "%s: No tda827x found!\n", __func__);
 591                return -ENODEV;
 592        }
 593        return 0;
 594}
 595
 596static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap)
 597{
 598        if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
 599                deb_info("TDA8263 attach failed\n");
 600                return -ENODEV;
 601        }
 602
 603        if (dvb_attach(lnbp21_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0, 0) == NULL) {
 604                deb_info("LNBP21 attach failed\n");
 605                return -ENODEV;
 606        }
 607        return 0;
 608}
 609
 610/* DVB USB Driver stuff */
 611static struct dvb_usb_device_properties ttusb2_properties;
 612static struct dvb_usb_device_properties ttusb2_properties_s2400;
 613static struct dvb_usb_device_properties ttusb2_properties_ct3650;
 614
 615static void ttusb2_usb_disconnect(struct usb_interface *intf)
 616{
 617        struct dvb_usb_device *d = usb_get_intfdata(intf);
 618
 619        tt3650_ci_uninit(d);
 620        dvb_usb_device_exit(intf);
 621}
 622
 623static int ttusb2_probe(struct usb_interface *intf,
 624                const struct usb_device_id *id)
 625{
 626        if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
 627                                     THIS_MODULE, NULL, adapter_nr) ||
 628            0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
 629                                     THIS_MODULE, NULL, adapter_nr) ||
 630            0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650,
 631                                     THIS_MODULE, NULL, adapter_nr))
 632                return 0;
 633        return -ENODEV;
 634}
 635
 636static struct usb_device_id ttusb2_table [] = {
 637        { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
 638        { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
 639        { USB_DEVICE(USB_VID_TECHNOTREND,
 640                USB_PID_TECHNOTREND_CONNECT_S2400) },
 641        { USB_DEVICE(USB_VID_TECHNOTREND,
 642                USB_PID_TECHNOTREND_CONNECT_CT3650) },
 643        { USB_DEVICE(USB_VID_TECHNOTREND,
 644                USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM) },
 645        {}              /* Terminating entry */
 646};
 647MODULE_DEVICE_TABLE (usb, ttusb2_table);
 648
 649static struct dvb_usb_device_properties ttusb2_properties = {
 650        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 651
 652        .usb_ctrl = CYPRESS_FX2,
 653        .firmware = "dvb-usb-pctv-400e-01.fw",
 654
 655        .size_of_priv = sizeof(struct ttusb2_state),
 656
 657        .num_adapters = 1,
 658        .adapter = {
 659                {
 660                .num_frontends = 1,
 661                .fe = {{
 662                        .streaming_ctrl   = NULL, // ttusb2_streaming_ctrl,
 663
 664                        .frontend_attach  = ttusb2_frontend_tda10086_attach,
 665                        .tuner_attach     = ttusb2_tuner_tda826x_attach,
 666
 667                        /* parameter for the MPEG2-data transfer */
 668                        .stream = {
 669                                .type = USB_ISOC,
 670                                .count = 5,
 671                                .endpoint = 0x02,
 672                                .u = {
 673                                        .isoc = {
 674                                                .framesperurb = 4,
 675                                                .framesize = 940,
 676                                                .interval = 1,
 677                                        }
 678                                }
 679                        }
 680                }},
 681                }
 682        },
 683
 684        .power_ctrl       = ttusb2_power_ctrl,
 685        .identify_state   = ttusb2_identify_state,
 686
 687        .i2c_algo         = &ttusb2_i2c_algo,
 688
 689        .generic_bulk_ctrl_endpoint = 0x01,
 690
 691        .num_device_descs = 2,
 692        .devices = {
 693                {   "Pinnacle 400e DVB-S USB2.0",
 694                        { &ttusb2_table[0], NULL },
 695                        { NULL },
 696                },
 697                {   "Pinnacle 450e DVB-S USB2.0",
 698                        { &ttusb2_table[1], NULL },
 699                        { NULL },
 700                },
 701        }
 702};
 703
 704static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
 705        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 706
 707        .usb_ctrl = CYPRESS_FX2,
 708        .firmware = "dvb-usb-tt-s2400-01.fw",
 709
 710        .size_of_priv = sizeof(struct ttusb2_state),
 711
 712        .num_adapters = 1,
 713        .adapter = {
 714                {
 715                .num_frontends = 1,
 716                .fe = {{
 717                        .streaming_ctrl   = NULL,
 718
 719                        .frontend_attach  = ttusb2_frontend_tda10086_attach,
 720                        .tuner_attach     = ttusb2_tuner_tda826x_attach,
 721
 722                        /* parameter for the MPEG2-data transfer */
 723                        .stream = {
 724                                .type = USB_ISOC,
 725                                .count = 5,
 726                                .endpoint = 0x02,
 727                                .u = {
 728                                        .isoc = {
 729                                                .framesperurb = 4,
 730                                                .framesize = 940,
 731                                                .interval = 1,
 732                                        }
 733                                }
 734                        }
 735                }},
 736                }
 737        },
 738
 739        .power_ctrl       = ttusb2_power_ctrl,
 740        .identify_state   = ttusb2_identify_state,
 741
 742        .i2c_algo         = &ttusb2_i2c_algo,
 743
 744        .generic_bulk_ctrl_endpoint = 0x01,
 745
 746        .num_device_descs = 2,
 747        .devices = {
 748                {   "Technotrend TT-connect S-2400",
 749                        { &ttusb2_table[2], NULL },
 750                        { NULL },
 751                },
 752                {   "Technotrend TT-connect S-2400 (8kB EEPROM)",
 753                        { &ttusb2_table[4], NULL },
 754                        { NULL },
 755                },
 756        }
 757};
 758
 759static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
 760        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 761
 762        .usb_ctrl = CYPRESS_FX2,
 763
 764        .size_of_priv = sizeof(struct ttusb2_state),
 765
 766        .rc.core = {
 767                .rc_interval      = 150, /* Less than IR_KEYPRESS_TIMEOUT */
 768                .rc_codes         = RC_MAP_TT_1500,
 769                .rc_query         = tt3650_rc_query,
 770                .allowed_protos   = RC_PROTO_BIT_RC5,
 771        },
 772
 773        .num_adapters = 1,
 774        .adapter = {
 775                {
 776                .num_frontends = 2,
 777                .fe = {{
 778                        .streaming_ctrl   = NULL,
 779
 780                        .frontend_attach  = ttusb2_frontend_tda10023_attach,
 781                        .tuner_attach = ttusb2_tuner_tda827x_attach,
 782
 783                        /* parameter for the MPEG2-data transfer */
 784                        .stream = {
 785                                .type = USB_ISOC,
 786                                .count = 5,
 787                                .endpoint = 0x02,
 788                                .u = {
 789                                        .isoc = {
 790                                                .framesperurb = 4,
 791                                                .framesize = 940,
 792                                                .interval = 1,
 793                                        }
 794                                }
 795                        }
 796                }, {
 797                        .streaming_ctrl   = NULL,
 798
 799                        .frontend_attach  = ttusb2_frontend_tda10023_attach,
 800                        .tuner_attach = ttusb2_tuner_tda827x_attach,
 801
 802                        /* parameter for the MPEG2-data transfer */
 803                        .stream = {
 804                                .type = USB_ISOC,
 805                                .count = 5,
 806                                .endpoint = 0x02,
 807                                .u = {
 808                                        .isoc = {
 809                                                .framesperurb = 4,
 810                                                .framesize = 940,
 811                                                .interval = 1,
 812                                        }
 813                                }
 814                        }
 815                }},
 816                },
 817        },
 818
 819        .power_ctrl       = ttusb2_power_ctrl,
 820        .identify_state   = ttusb2_identify_state,
 821
 822        .i2c_algo         = &ttusb2_i2c_algo,
 823
 824        .generic_bulk_ctrl_endpoint = 0x01,
 825
 826        .num_device_descs = 1,
 827        .devices = {
 828                {   "Technotrend TT-connect CT-3650",
 829                        .warm_ids = { &ttusb2_table[3], NULL },
 830                },
 831        }
 832};
 833
 834static struct usb_driver ttusb2_driver = {
 835        .name           = "dvb_usb_ttusb2",
 836        .probe          = ttusb2_probe,
 837        .disconnect     = ttusb2_usb_disconnect,
 838        .id_table       = ttusb2_table,
 839};
 840
 841module_usb_driver(ttusb2_driver);
 842
 843MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 844MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");
 845MODULE_VERSION("1.0");
 846MODULE_LICENSE("GPL");
 847