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