1/* 2 * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones 3 * 4 * Copyright (c) Henry Wang <Henry.wang@AzureWave.com> 5 * 6 * This driver was made publicly available by Terratec, at: 7 * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz 8 * The original driver's license is GPL, as declared with MODULE_LICENSE() 9 * 10 * Copyright (c) 2010-2012 Mauro Carvalho Chehab 11 * Driver modified by in order to work with upstream drxk driver, and 12 * tons of bugs got fixed, and converted to use dvb-usb-v2. 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation under version 2 of the License. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 */ 23 24#include "drxk.h" 25#include "mt2063.h" 26#include "dvb_ca_en50221.h" 27#include "dvb_usb.h" 28#include "cypress_firmware.h" 29 30#define AZ6007_FIRMWARE "dvb-usb-terratec-h7-az6007.fw" 31 32static int az6007_xfer_debug; 33module_param_named(xfer_debug, az6007_xfer_debug, int, 0644); 34MODULE_PARM_DESC(xfer_debug, "Enable xfer debug"); 35 36DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 37 38/* Known requests (Cypress FX2 firmware + az6007 "private" ones*/ 39 40#define FX2_OED 0xb5 41#define AZ6007_READ_DATA 0xb7 42#define AZ6007_I2C_RD 0xb9 43#define AZ6007_POWER 0xbc 44#define AZ6007_I2C_WR 0xbd 45#define FX2_SCON1 0xc0 46#define AZ6007_TS_THROUGH 0xc7 47#define AZ6007_READ_IR 0xb4 48 49struct az6007_device_state { 50 struct mutex mutex; 51 struct mutex ca_mutex; 52 struct dvb_ca_en50221 ca; 53 unsigned warm:1; 54 int (*gate_ctrl) (struct dvb_frontend *, int); 55 unsigned char data[4096]; 56}; 57 58static struct drxk_config terratec_h7_drxk = { 59 .adr = 0x29, 60 .parallel_ts = true, 61 .dynamic_clk = true, 62 .single_master = true, 63 .enable_merr_cfg = true, 64 .no_i2c_bridge = false, 65 .chunk_size = 64, 66 .mpeg_out_clk_strength = 0x02, 67 .qam_demod_parameter_count = 2, 68 .microcode_name = "dvb-usb-terratec-h7-drxk.fw", 69}; 70 71static struct drxk_config cablestar_hdci_drxk = { 72 .adr = 0x29, 73 .parallel_ts = true, 74 .dynamic_clk = true, 75 .single_master = true, 76 .enable_merr_cfg = true, 77 .no_i2c_bridge = false, 78 .chunk_size = 64, 79 .mpeg_out_clk_strength = 0x02, 80 .qam_demod_parameter_count = 2, 81 .microcode_name = "dvb-usb-technisat-cablestar-hdci-drxk.fw", 82}; 83 84static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 85{ 86 struct az6007_device_state *st = fe_to_priv(fe); 87 struct dvb_usb_adapter *adap = fe->sec_priv; 88 int status = 0; 89 90 pr_debug("%s: %s\n", __func__, enable ? "enable" : "disable"); 91 92 if (!adap || !st) 93 return -EINVAL; 94 95 if (enable) 96 status = st->gate_ctrl(fe, 1); 97 else 98 status = st->gate_ctrl(fe, 0); 99 100 return status; 101} 102 103static struct mt2063_config az6007_mt2063_config = { 104 .tuner_address = 0x60, 105 .refclock = 36125000, 106}; 107 108static int __az6007_read(struct usb_device *udev, u8 req, u16 value, 109 u16 index, u8 *b, int blen) 110{ 111 int ret; 112 113 ret = usb_control_msg(udev, 114 usb_rcvctrlpipe(udev, 0), 115 req, 116 USB_TYPE_VENDOR | USB_DIR_IN, 117 value, index, b, blen, 5000); 118 if (ret < 0) { 119 pr_warn("usb read operation failed. (%d)\n", ret); 120 return -EIO; 121 } 122 123 if (az6007_xfer_debug) { 124 printk(KERN_DEBUG "az6007: IN req: %02x, value: %04x, index: %04x\n", 125 req, value, index); 126 print_hex_dump_bytes("az6007: payload: ", 127 DUMP_PREFIX_NONE, b, blen); 128 } 129 130 return ret; 131} 132 133static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value, 134 u16 index, u8 *b, int blen) 135{ 136 struct az6007_device_state *st = d->priv; 137 int ret; 138 139 if (mutex_lock_interruptible(&st->mutex) < 0) 140 return -EAGAIN; 141 142 ret = __az6007_read(d->udev, req, value, index, b, blen); 143 144 mutex_unlock(&st->mutex); 145 146 return ret; 147} 148 149static int __az6007_write(struct usb_device *udev, u8 req, u16 value, 150 u16 index, u8 *b, int blen) 151{ 152 int ret; 153 154 if (az6007_xfer_debug) { 155 printk(KERN_DEBUG "az6007: OUT req: %02x, value: %04x, index: %04x\n", 156 req, value, index); 157 print_hex_dump_bytes("az6007: payload: ", 158 DUMP_PREFIX_NONE, b, blen); 159 } 160 161 if (blen > 64) { 162 pr_err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n", 163 blen); 164 return -EOPNOTSUPP; 165 } 166 167 ret = usb_control_msg(udev, 168 usb_sndctrlpipe(udev, 0), 169 req, 170 USB_TYPE_VENDOR | USB_DIR_OUT, 171 value, index, b, blen, 5000); 172 if (ret != blen) { 173 pr_err("usb write operation failed. (%d)\n", ret); 174 return -EIO; 175 } 176 177 return 0; 178} 179 180static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value, 181 u16 index, u8 *b, int blen) 182{ 183 struct az6007_device_state *st = d->priv; 184 int ret; 185 186 if (mutex_lock_interruptible(&st->mutex) < 0) 187 return -EAGAIN; 188 189 ret = __az6007_write(d->udev, req, value, index, b, blen); 190 191 mutex_unlock(&st->mutex); 192 193 return ret; 194} 195 196static int az6007_streaming_ctrl(struct dvb_frontend *fe, int onoff) 197{ 198 struct dvb_usb_device *d = fe_to_d(fe); 199 200 pr_debug("%s: %s\n", __func__, onoff ? "enable" : "disable"); 201 202 return az6007_write(d, 0xbc, onoff, 0, NULL, 0); 203} 204 205#if IS_ENABLED(CONFIG_RC_CORE) 206/* remote control stuff (does not work with my box) */ 207static int az6007_rc_query(struct dvb_usb_device *d) 208{ 209 struct az6007_device_state *st = d_to_priv(d); 210 unsigned code; 211 212 az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); 213 214 if (st->data[1] == 0x44) 215 return 0; 216 217 if ((st->data[3] ^ st->data[4]) == 0xff) { 218 if ((st->data[1] ^ st->data[2]) == 0xff) 219 code = RC_SCANCODE_NEC(st->data[1], st->data[3]); 220 else 221 code = RC_SCANCODE_NECX(st->data[1] << 8 | st->data[2], 222 st->data[3]); 223 } else { 224 code = RC_SCANCODE_NEC32(st->data[1] << 24 | 225 st->data[2] << 16 | 226 st->data[3] << 8 | 227 st->data[4]); 228 } 229 230 rc_keydown(d->rc_dev, RC_TYPE_NEC, code, st->data[5]); 231 232 return 0; 233} 234 235static int az6007_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) 236{ 237 pr_debug("Getting az6007 Remote Control properties\n"); 238 239 rc->allowed_protos = RC_BIT_NEC; 240 rc->query = az6007_rc_query; 241 rc->interval = 400; 242 243 return 0; 244} 245#else 246 #define az6007_get_rc_config NULL 247#endif 248 249static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, 250 int slot, 251 int address) 252{ 253 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 254 struct az6007_device_state *state = d_to_priv(d); 255 256 int ret; 257 u8 req; 258 u16 value; 259 u16 index; 260 int blen; 261 u8 *b; 262 263 if (slot != 0) 264 return -EINVAL; 265 266 b = kmalloc(12, GFP_KERNEL); 267 if (!b) 268 return -ENOMEM; 269 270 mutex_lock(&state->ca_mutex); 271 272 req = 0xC1; 273 value = address; 274 index = 0; 275 blen = 1; 276 277 ret = az6007_read(d, req, value, index, b, blen); 278 if (ret < 0) { 279 pr_warn("usb in operation failed. (%d)\n", ret); 280 ret = -EINVAL; 281 } else { 282 ret = b[0]; 283 } 284 285 mutex_unlock(&state->ca_mutex); 286 kfree(b); 287 return ret; 288} 289 290static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, 291 int slot, 292 int address, 293 u8 value) 294{ 295 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 296 struct az6007_device_state *state = d_to_priv(d); 297 298 int ret; 299 u8 req; 300 u16 value1; 301 u16 index; 302 int blen; 303 304 pr_debug("%s(), slot %d\n", __func__, slot); 305 if (slot != 0) 306 return -EINVAL; 307 308 mutex_lock(&state->ca_mutex); 309 req = 0xC2; 310 value1 = address; 311 index = value; 312 blen = 0; 313 314 ret = az6007_write(d, req, value1, index, NULL, blen); 315 if (ret != 0) 316 pr_warn("usb out operation failed. (%d)\n", ret); 317 318 mutex_unlock(&state->ca_mutex); 319 return ret; 320} 321 322static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca, 323 int slot, 324 u8 address) 325{ 326 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 327 struct az6007_device_state *state = d_to_priv(d); 328 329 int ret; 330 u8 req; 331 u16 value; 332 u16 index; 333 int blen; 334 u8 *b; 335 336 if (slot != 0) 337 return -EINVAL; 338 339 b = kmalloc(12, GFP_KERNEL); 340 if (!b) 341 return -ENOMEM; 342 343 mutex_lock(&state->ca_mutex); 344 345 req = 0xC3; 346 value = address; 347 index = 0; 348 blen = 2; 349 350 ret = az6007_read(d, req, value, index, b, blen); 351 if (ret < 0) { 352 pr_warn("usb in operation failed. (%d)\n", ret); 353 ret = -EINVAL; 354 } else { 355 if (b[0] == 0) 356 pr_warn("Read CI IO error\n"); 357 358 ret = b[1]; 359 pr_debug("read cam data = %x from 0x%x\n", b[1], value); 360 } 361 362 mutex_unlock(&state->ca_mutex); 363 kfree(b); 364 return ret; 365} 366 367static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca, 368 int slot, 369 u8 address, 370 u8 value) 371{ 372 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 373 struct az6007_device_state *state = d_to_priv(d); 374 375 int ret; 376 u8 req; 377 u16 value1; 378 u16 index; 379 int blen; 380 381 if (slot != 0) 382 return -EINVAL; 383 384 mutex_lock(&state->ca_mutex); 385 req = 0xC4; 386 value1 = address; 387 index = value; 388 blen = 0; 389 390 ret = az6007_write(d, req, value1, index, NULL, blen); 391 if (ret != 0) { 392 pr_warn("usb out operation failed. (%d)\n", ret); 393 goto failed; 394 } 395 396failed: 397 mutex_unlock(&state->ca_mutex); 398 return ret; 399} 400 401static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) 402{ 403 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 404 405 int ret; 406 u8 req; 407 u16 value; 408 u16 index; 409 int blen; 410 u8 *b; 411 412 b = kmalloc(12, GFP_KERNEL); 413 if (!b) 414 return -ENOMEM; 415 416 req = 0xC8; 417 value = 0; 418 index = 0; 419 blen = 1; 420 421 ret = az6007_read(d, req, value, index, b, blen); 422 if (ret < 0) { 423 pr_warn("usb in operation failed. (%d)\n", ret); 424 ret = -EIO; 425 } else{ 426 ret = b[0]; 427 } 428 kfree(b); 429 return ret; 430} 431 432static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) 433{ 434 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 435 struct az6007_device_state *state = d_to_priv(d); 436 437 int ret, i; 438 u8 req; 439 u16 value; 440 u16 index; 441 int blen; 442 443 mutex_lock(&state->ca_mutex); 444 445 req = 0xC6; 446 value = 1; 447 index = 0; 448 blen = 0; 449 450 ret = az6007_write(d, req, value, index, NULL, blen); 451 if (ret != 0) { 452 pr_warn("usb out operation failed. (%d)\n", ret); 453 goto failed; 454 } 455 456 msleep(500); 457 req = 0xC6; 458 value = 0; 459 index = 0; 460 blen = 0; 461 462 ret = az6007_write(d, req, value, index, NULL, blen); 463 if (ret != 0) { 464 pr_warn("usb out operation failed. (%d)\n", ret); 465 goto failed; 466 } 467 468 for (i = 0; i < 15; i++) { 469 msleep(100); 470 471 if (CI_CamReady(ca, slot)) { 472 pr_debug("CAM Ready\n"); 473 break; 474 } 475 } 476 msleep(5000); 477 478failed: 479 mutex_unlock(&state->ca_mutex); 480 return ret; 481} 482 483static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) 484{ 485 return 0; 486} 487 488static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) 489{ 490 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 491 struct az6007_device_state *state = d_to_priv(d); 492 493 int ret; 494 u8 req; 495 u16 value; 496 u16 index; 497 int blen; 498 499 pr_debug("%s()\n", __func__); 500 mutex_lock(&state->ca_mutex); 501 req = 0xC7; 502 value = 1; 503 index = 0; 504 blen = 0; 505 506 ret = az6007_write(d, req, value, index, NULL, blen); 507 if (ret != 0) { 508 pr_warn("usb out operation failed. (%d)\n", ret); 509 goto failed; 510 } 511 512failed: 513 mutex_unlock(&state->ca_mutex); 514 return ret; 515} 516 517static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) 518{ 519 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 520 struct az6007_device_state *state = d_to_priv(d); 521 int ret; 522 u8 req; 523 u16 value; 524 u16 index; 525 int blen; 526 u8 *b; 527 528 b = kmalloc(12, GFP_KERNEL); 529 if (!b) 530 return -ENOMEM; 531 mutex_lock(&state->ca_mutex); 532 533 req = 0xC5; 534 value = 0; 535 index = 0; 536 blen = 1; 537 538 ret = az6007_read(d, req, value, index, b, blen); 539 if (ret < 0) { 540 pr_warn("usb in operation failed. (%d)\n", ret); 541 ret = -EIO; 542 } else 543 ret = 0; 544 545 if (!ret && b[0] == 1) { 546 ret = DVB_CA_EN50221_POLL_CAM_PRESENT | 547 DVB_CA_EN50221_POLL_CAM_READY; 548 } 549 550 mutex_unlock(&state->ca_mutex); 551 kfree(b); 552 return ret; 553} 554 555 556static void az6007_ci_uninit(struct dvb_usb_device *d) 557{ 558 struct az6007_device_state *state; 559 560 pr_debug("%s()\n", __func__); 561 562 if (NULL == d) 563 return; 564 565 state = d_to_priv(d); 566 if (NULL == state) 567 return; 568 569 if (NULL == state->ca.data) 570 return; 571 572 dvb_ca_en50221_release(&state->ca); 573 574 memset(&state->ca, 0, sizeof(state->ca)); 575} 576 577 578static int az6007_ci_init(struct dvb_usb_adapter *adap) 579{ 580 struct dvb_usb_device *d = adap_to_d(adap); 581 struct az6007_device_state *state = adap_to_priv(adap); 582 int ret; 583 584 pr_debug("%s()\n", __func__); 585 586 mutex_init(&state->ca_mutex); 587 state->ca.owner = THIS_MODULE; 588 state->ca.read_attribute_mem = az6007_ci_read_attribute_mem; 589 state->ca.write_attribute_mem = az6007_ci_write_attribute_mem; 590 state->ca.read_cam_control = az6007_ci_read_cam_control; 591 state->ca.write_cam_control = az6007_ci_write_cam_control; 592 state->ca.slot_reset = az6007_ci_slot_reset; 593 state->ca.slot_shutdown = az6007_ci_slot_shutdown; 594 state->ca.slot_ts_enable = az6007_ci_slot_ts_enable; 595 state->ca.poll_slot_status = az6007_ci_poll_slot_status; 596 state->ca.data = d; 597 598 ret = dvb_ca_en50221_init(&adap->dvb_adap, 599 &state->ca, 600 0, /* flags */ 601 1);/* n_slots */ 602 if (ret != 0) { 603 pr_err("Cannot initialize CI: Error %d.\n", ret); 604 memset(&state->ca, 0, sizeof(state->ca)); 605 return ret; 606 } 607 608 pr_debug("CI initialized.\n"); 609 610 return 0; 611} 612 613static int az6007_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6]) 614{ 615 struct dvb_usb_device *d = adap_to_d(adap); 616 struct az6007_device_state *st = adap_to_priv(adap); 617 int ret; 618 619 ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6); 620 memcpy(mac, st->data, 6); 621 622 if (ret > 0) 623 pr_debug("%s: mac is %pM\n", __func__, mac); 624 625 return ret; 626} 627 628static int az6007_frontend_attach(struct dvb_usb_adapter *adap) 629{ 630 struct az6007_device_state *st = adap_to_priv(adap); 631 struct dvb_usb_device *d = adap_to_d(adap); 632 633 pr_debug("attaching demod drxk\n"); 634 635 adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk, 636 &d->i2c_adap); 637 if (!adap->fe[0]) 638 return -EINVAL; 639 640 adap->fe[0]->sec_priv = adap; 641 st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl; 642 adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; 643 644 az6007_ci_init(adap); 645 646 return 0; 647} 648 649static int az6007_cablestar_hdci_frontend_attach(struct dvb_usb_adapter *adap) 650{ 651 struct az6007_device_state *st = adap_to_priv(adap); 652 struct dvb_usb_device *d = adap_to_d(adap); 653 654 pr_debug("attaching demod drxk\n"); 655 656 adap->fe[0] = dvb_attach(drxk_attach, &cablestar_hdci_drxk, 657 &d->i2c_adap); 658 if (!adap->fe[0]) 659 return -EINVAL; 660 661 adap->fe[0]->sec_priv = adap; 662 st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl; 663 adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; 664 665 az6007_ci_init(adap); 666 667 return 0; 668} 669 670static int az6007_tuner_attach(struct dvb_usb_adapter *adap) 671{ 672 struct dvb_usb_device *d = adap_to_d(adap); 673 674 pr_debug("attaching tuner mt2063\n"); 675 676 /* Attach mt2063 to DVB-C frontend */ 677 if (adap->fe[0]->ops.i2c_gate_ctrl) 678 adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1); 679 if (!dvb_attach(mt2063_attach, adap->fe[0], 680 &az6007_mt2063_config, 681 &d->i2c_adap)) 682 return -EINVAL; 683 684 if (adap->fe[0]->ops.i2c_gate_ctrl) 685 adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0); 686 687 return 0; 688} 689 690static int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) 691{ 692 struct az6007_device_state *state = d_to_priv(d); 693 int ret; 694 695 pr_debug("%s()\n", __func__); 696 697 if (!state->warm) { 698 mutex_init(&state->mutex); 699 700 ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0); 701 if (ret < 0) 702 return ret; 703 msleep(60); 704 ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0); 705 if (ret < 0) 706 return ret; 707 msleep(100); 708 ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0); 709 if (ret < 0) 710 return ret; 711 msleep(20); 712 ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0); 713 if (ret < 0) 714 return ret; 715 716 msleep(400); 717 ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0); 718 if (ret < 0) 719 return ret; 720 msleep(150); 721 ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0); 722 if (ret < 0) 723 return ret; 724 msleep(430); 725 ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); 726 if (ret < 0) 727 return ret; 728 729 state->warm = true; 730 731 return 0; 732 } 733 734 if (!onoff) 735 return 0; 736 737 az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); 738 az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0); 739 740 return 0; 741} 742 743/* I2C */ 744static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], 745 int num) 746{ 747 struct dvb_usb_device *d = i2c_get_adapdata(adap); 748 struct az6007_device_state *st = d_to_priv(d); 749 int i, j, len; 750 int ret = 0; 751 u16 index; 752 u16 value; 753 int length; 754 u8 req, addr; 755 756 if (mutex_lock_interruptible(&st->mutex) < 0) 757 return -EAGAIN; 758 759 for (i = 0; i < num; i++) { 760 addr = msgs[i].addr << 1; 761 if (((i + 1) < num) 762 && (msgs[i].len == 1) 763 && ((msgs[i].flags & I2C_M_RD) != I2C_M_RD) 764 && (msgs[i + 1].flags & I2C_M_RD) 765 && (msgs[i].addr == msgs[i + 1].addr)) { 766 /* 767 * A write + read xfer for the same address, where 768 * the first xfer has just 1 byte length. 769 * Need to join both into one operation 770 */ 771 if (az6007_xfer_debug) 772 printk(KERN_DEBUG "az6007: I2C W/R addr=0x%x len=%d/%d\n", 773 addr, msgs[i].len, msgs[i + 1].len); 774 req = AZ6007_I2C_RD; 775 index = msgs[i].buf[0]; 776 value = addr | (1 << 8); 777 length = 6 + msgs[i + 1].len; 778 len = msgs[i + 1].len; 779 ret = __az6007_read(d->udev, req, value, index, 780 st->data, length); 781 if (ret >= len) { 782 for (j = 0; j < len; j++) 783 msgs[i + 1].buf[j] = st->data[j + 5]; 784 } else 785 ret = -EIO; 786 i++; 787 } else if (!(msgs[i].flags & I2C_M_RD)) { 788 /* write bytes */ 789 if (az6007_xfer_debug) 790 printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n", 791 addr, msgs[i].len); 792 req = AZ6007_I2C_WR; 793 index = msgs[i].buf[0]; 794 value = addr | (1 << 8); 795 length = msgs[i].len - 1; 796 len = msgs[i].len - 1; 797 for (j = 0; j < len; j++) 798 st->data[j] = msgs[i].buf[j + 1]; 799 ret = __az6007_write(d->udev, req, value, index, 800 st->data, length); 801 } else { 802 /* read bytes */ 803 if (az6007_xfer_debug) 804 printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n", 805 addr, msgs[i].len); 806 req = AZ6007_I2C_RD; 807 index = msgs[i].buf[0]; 808 value = addr; 809 length = msgs[i].len + 6; 810 len = msgs[i].len; 811 ret = __az6007_read(d->udev, req, value, index, 812 st->data, length); 813 for (j = 0; j < len; j++) 814 msgs[i].buf[j] = st->data[j + 5]; 815 } 816 if (ret < 0) 817 goto err; 818 } 819err: 820 mutex_unlock(&st->mutex); 821 822 if (ret < 0) { 823 pr_info("%s ERROR: %i\n", __func__, ret); 824 return ret; 825 } 826 return num; 827} 828 829static u32 az6007_i2c_func(struct i2c_adapter *adapter) 830{ 831 return I2C_FUNC_I2C; 832} 833 834static struct i2c_algorithm az6007_i2c_algo = { 835 .master_xfer = az6007_i2c_xfer, 836 .functionality = az6007_i2c_func, 837}; 838 839static int az6007_identify_state(struct dvb_usb_device *d, const char **name) 840{ 841 int ret; 842 u8 *mac; 843 844 pr_debug("Identifying az6007 state\n"); 845 846 mac = kmalloc(6, GFP_ATOMIC); 847 if (!mac) 848 return -ENOMEM; 849 850 /* Try to read the mac address */ 851 ret = __az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6); 852 if (ret == 6) 853 ret = WARM; 854 else 855 ret = COLD; 856 857 kfree(mac); 858 859 if (ret == COLD) { 860 __az6007_write(d->udev, 0x09, 1, 0, NULL, 0); 861 __az6007_write(d->udev, 0x00, 0, 0, NULL, 0); 862 __az6007_write(d->udev, 0x00, 0, 0, NULL, 0); 863 } 864 865 pr_debug("Device is on %s state\n", 866 ret == WARM ? "warm" : "cold"); 867 return ret; 868} 869 870static void az6007_usb_disconnect(struct usb_interface *intf) 871{ 872 struct dvb_usb_device *d = usb_get_intfdata(intf); 873 az6007_ci_uninit(d); 874 dvb_usbv2_disconnect(intf); 875} 876 877static int az6007_download_firmware(struct dvb_usb_device *d, 878 const struct firmware *fw) 879{ 880 pr_debug("Loading az6007 firmware\n"); 881 882 return cypress_load_firmware(d->udev, fw, CYPRESS_FX2); 883} 884 885/* DVB USB Driver stuff */ 886static struct dvb_usb_device_properties az6007_props = { 887 .driver_name = KBUILD_MODNAME, 888 .owner = THIS_MODULE, 889 .firmware = AZ6007_FIRMWARE, 890 891 .adapter_nr = adapter_nr, 892 .size_of_priv = sizeof(struct az6007_device_state), 893 .i2c_algo = &az6007_i2c_algo, 894 .tuner_attach = az6007_tuner_attach, 895 .frontend_attach = az6007_frontend_attach, 896 .streaming_ctrl = az6007_streaming_ctrl, 897 .get_rc_config = az6007_get_rc_config, 898 .read_mac_address = az6007_read_mac_addr, 899 .download_firmware = az6007_download_firmware, 900 .identify_state = az6007_identify_state, 901 .power_ctrl = az6007_power_ctrl, 902 .num_adapters = 1, 903 .adapter = { 904 { .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), } 905 } 906}; 907 908static struct dvb_usb_device_properties az6007_cablestar_hdci_props = { 909 .driver_name = KBUILD_MODNAME, 910 .owner = THIS_MODULE, 911 .firmware = AZ6007_FIRMWARE, 912 913 .adapter_nr = adapter_nr, 914 .size_of_priv = sizeof(struct az6007_device_state), 915 .i2c_algo = &az6007_i2c_algo, 916 .tuner_attach = az6007_tuner_attach, 917 .frontend_attach = az6007_cablestar_hdci_frontend_attach, 918 .streaming_ctrl = az6007_streaming_ctrl, 919/* ditch get_rc_config as it can't work (TS35 remote, I believe it's rc5) */ 920 .get_rc_config = NULL, 921 .read_mac_address = az6007_read_mac_addr, 922 .download_firmware = az6007_download_firmware, 923 .identify_state = az6007_identify_state, 924 .power_ctrl = az6007_power_ctrl, 925 .num_adapters = 1, 926 .adapter = { 927 { .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), } 928 } 929}; 930 931static struct usb_device_id az6007_usb_table[] = { 932 {DVB_USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007, 933 &az6007_props, "Azurewave 6007", RC_MAP_EMPTY)}, 934 {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7, 935 &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)}, 936 {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2, 937 &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)}, 938 {DVB_USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_CABLESTAR_HDCI, 939 &az6007_cablestar_hdci_props, "Technisat CableStar Combo HD CI", RC_MAP_EMPTY)}, 940 {0}, 941}; 942 943MODULE_DEVICE_TABLE(usb, az6007_usb_table); 944 945static int az6007_suspend(struct usb_interface *intf, pm_message_t msg) 946{ 947 struct dvb_usb_device *d = usb_get_intfdata(intf); 948 949 az6007_ci_uninit(d); 950 return dvb_usbv2_suspend(intf, msg); 951} 952 953static int az6007_resume(struct usb_interface *intf) 954{ 955 struct dvb_usb_device *d = usb_get_intfdata(intf); 956 struct dvb_usb_adapter *adap = &d->adapter[0]; 957 958 az6007_ci_init(adap); 959 return dvb_usbv2_resume(intf); 960} 961 962/* usb specific object needed to register this driver with the usb subsystem */ 963static struct usb_driver az6007_usb_driver = { 964 .name = KBUILD_MODNAME, 965 .id_table = az6007_usb_table, 966 .probe = dvb_usbv2_probe, 967 .disconnect = az6007_usb_disconnect, 968 .no_dynamic_id = 1, 969 .soft_unbind = 1, 970 /* 971 * FIXME: need to implement reset_resume, likely with 972 * dvb-usb-v2 core support 973 */ 974 .suspend = az6007_suspend, 975 .resume = az6007_resume, 976}; 977 978module_usb_driver(az6007_usb_driver); 979 980MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>"); 981MODULE_AUTHOR("Mauro Carvalho Chehab"); 982MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones"); 983MODULE_VERSION("2.0"); 984MODULE_LICENSE("GPL"); 985MODULE_FIRMWARE(AZ6007_FIRMWARE); 986