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