ttusb2.c (18994B)
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 */ 37static int dvb_usb_ttusb2_debug; 38#define deb_info(args...) dprintk(dvb_usb_ttusb2_debug,0x01,args) 39module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644); 40MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS); 41static int dvb_usb_ttusb2_debug_ci; 42module_param_named(debug_ci,dvb_usb_ttusb2_debug_ci, int, 0644); 43MODULE_PARM_DESC(debug_ci, "set debugging ci." DVB_USB_DEBUG_STATUS); 44 45DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 46 47#define ci_dbg(format, arg...) \ 48do { \ 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 54enum { 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 64struct ttusb2_state { 65 struct dvb_ca_en50221 ca; 66 struct mutex ca_mutex; 67 u8 id; 68 u16 last_rc_key; 69}; 70 71static 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 */ 120static 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 130static 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 143static 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 165static 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 181static 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 201static 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 216static 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 240static 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 245static 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 250static 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 292static 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 311static 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 332static 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 368static 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 432static u32 ttusb2_i2c_func(struct i2c_adapter *adapter) 433{ 434 return I2C_FUNC_I2C; 435} 436 437static 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 */ 446static 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 */ 470static 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 479static 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 487static struct tda10086_config tda10086_config = { 488 .demod_address = 0x0e, 489 .invert = 0, 490 .diseqc_tone = 1, 491 .xtal_freq = TDA10086_XTAL_16M, 492}; 493 494static 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 504static 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 519static struct tda827x_config tda827x_config = { 520 .config = 0, 521}; 522 523static 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 536static 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 543static 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 575static 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 593static 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 */ 608static struct dvb_usb_device_properties ttusb2_properties; 609static struct dvb_usb_device_properties ttusb2_properties_s2400; 610static struct dvb_usb_device_properties ttusb2_properties_ct3650; 611 612static 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 620static 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 633enum { 634 PINNACLE_PCTV_400E, 635 PINNACLE_PCTV_450E, 636 TECHNOTREND_CONNECT_S2400, 637 TECHNOTREND_CONNECT_CT3650, 638 TECHNOTREND_CONNECT_S2400_8KEEPROM, 639}; 640 641static struct usb_device_id ttusb2_table[] = { 642 DVB_USB_DEV(PINNACLE, PINNACLE_PCTV_400E), 643 DVB_USB_DEV(PINNACLE, PINNACLE_PCTV_450E), 644 DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_S2400), 645 DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_CT3650), 646 DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_S2400_8KEEPROM), 647 { } 648}; 649 650MODULE_DEVICE_TABLE (usb, ttusb2_table); 651 652static struct dvb_usb_device_properties ttusb2_properties = { 653 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 654 655 .usb_ctrl = CYPRESS_FX2, 656 .firmware = "dvb-usb-pctv-400e-01.fw", 657 658 .size_of_priv = sizeof(struct ttusb2_state), 659 660 .num_adapters = 1, 661 .adapter = { 662 { 663 .num_frontends = 1, 664 .fe = {{ 665 .streaming_ctrl = NULL, // ttusb2_streaming_ctrl, 666 667 .frontend_attach = ttusb2_frontend_tda10086_attach, 668 .tuner_attach = ttusb2_tuner_tda826x_attach, 669 670 /* parameter for the MPEG2-data transfer */ 671 .stream = { 672 .type = USB_ISOC, 673 .count = 5, 674 .endpoint = 0x02, 675 .u = { 676 .isoc = { 677 .framesperurb = 4, 678 .framesize = 940, 679 .interval = 1, 680 } 681 } 682 } 683 }}, 684 } 685 }, 686 687 .power_ctrl = ttusb2_power_ctrl, 688 .identify_state = ttusb2_identify_state, 689 690 .i2c_algo = &ttusb2_i2c_algo, 691 692 .generic_bulk_ctrl_endpoint = 0x01, 693 694 .num_device_descs = 2, 695 .devices = { 696 { "Pinnacle 400e DVB-S USB2.0", 697 { &ttusb2_table[PINNACLE_PCTV_400E], NULL }, 698 { NULL }, 699 }, 700 { "Pinnacle 450e DVB-S USB2.0", 701 { &ttusb2_table[PINNACLE_PCTV_450E], NULL }, 702 { NULL }, 703 }, 704 } 705}; 706 707static struct dvb_usb_device_properties ttusb2_properties_s2400 = { 708 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 709 710 .usb_ctrl = CYPRESS_FX2, 711 .firmware = "dvb-usb-tt-s2400-01.fw", 712 713 .size_of_priv = sizeof(struct ttusb2_state), 714 715 .num_adapters = 1, 716 .adapter = { 717 { 718 .num_frontends = 1, 719 .fe = {{ 720 .streaming_ctrl = NULL, 721 722 .frontend_attach = ttusb2_frontend_tda10086_attach, 723 .tuner_attach = ttusb2_tuner_tda826x_attach, 724 725 /* parameter for the MPEG2-data transfer */ 726 .stream = { 727 .type = USB_ISOC, 728 .count = 5, 729 .endpoint = 0x02, 730 .u = { 731 .isoc = { 732 .framesperurb = 4, 733 .framesize = 940, 734 .interval = 1, 735 } 736 } 737 } 738 }}, 739 } 740 }, 741 742 .power_ctrl = ttusb2_power_ctrl, 743 .identify_state = ttusb2_identify_state, 744 745 .i2c_algo = &ttusb2_i2c_algo, 746 747 .generic_bulk_ctrl_endpoint = 0x01, 748 749 .num_device_descs = 2, 750 .devices = { 751 { "Technotrend TT-connect S-2400", 752 { &ttusb2_table[TECHNOTREND_CONNECT_S2400], NULL }, 753 { NULL }, 754 }, 755 { "Technotrend TT-connect S-2400 (8kB EEPROM)", 756 { &ttusb2_table[TECHNOTREND_CONNECT_S2400_8KEEPROM], NULL }, 757 { NULL }, 758 }, 759 } 760}; 761 762static struct dvb_usb_device_properties ttusb2_properties_ct3650 = { 763 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 764 765 .usb_ctrl = CYPRESS_FX2, 766 767 .size_of_priv = sizeof(struct ttusb2_state), 768 769 .rc.core = { 770 .rc_interval = 150, /* Less than IR_KEYPRESS_TIMEOUT */ 771 .rc_codes = RC_MAP_TT_1500, 772 .rc_query = tt3650_rc_query, 773 .allowed_protos = RC_PROTO_BIT_RC5, 774 }, 775 776 .num_adapters = 1, 777 .adapter = { 778 { 779 .num_frontends = 2, 780 .fe = {{ 781 .streaming_ctrl = NULL, 782 783 .frontend_attach = ttusb2_frontend_tda10023_attach, 784 .tuner_attach = ttusb2_tuner_tda827x_attach, 785 786 /* parameter for the MPEG2-data transfer */ 787 .stream = { 788 .type = USB_ISOC, 789 .count = 5, 790 .endpoint = 0x02, 791 .u = { 792 .isoc = { 793 .framesperurb = 4, 794 .framesize = 940, 795 .interval = 1, 796 } 797 } 798 } 799 }, { 800 .streaming_ctrl = NULL, 801 802 .frontend_attach = ttusb2_frontend_tda10023_attach, 803 .tuner_attach = ttusb2_tuner_tda827x_attach, 804 805 /* parameter for the MPEG2-data transfer */ 806 .stream = { 807 .type = USB_ISOC, 808 .count = 5, 809 .endpoint = 0x02, 810 .u = { 811 .isoc = { 812 .framesperurb = 4, 813 .framesize = 940, 814 .interval = 1, 815 } 816 } 817 } 818 }}, 819 }, 820 }, 821 822 .power_ctrl = ttusb2_power_ctrl, 823 .identify_state = ttusb2_identify_state, 824 825 .i2c_algo = &ttusb2_i2c_algo, 826 827 .generic_bulk_ctrl_endpoint = 0x01, 828 829 .num_device_descs = 1, 830 .devices = { 831 { "Technotrend TT-connect CT-3650", 832 .warm_ids = { &ttusb2_table[TECHNOTREND_CONNECT_CT3650], NULL }, 833 }, 834 } 835}; 836 837static struct usb_driver ttusb2_driver = { 838 .name = "dvb_usb_ttusb2", 839 .probe = ttusb2_probe, 840 .disconnect = ttusb2_usb_disconnect, 841 .id_table = ttusb2_table, 842}; 843 844module_usb_driver(ttusb2_driver); 845 846MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>"); 847MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0"); 848MODULE_VERSION("1.0"); 849MODULE_LICENSE("GPL");