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