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