Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

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