root/drivers/media/usb/dvb-usb-v2/az6007.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. drxk_gate_ctrl
  2. __az6007_read
  3. az6007_read
  4. __az6007_write
  5. az6007_write
  6. az6007_streaming_ctrl
  7. az6007_rc_query
  8. az6007_get_rc_config
  9. az6007_ci_read_attribute_mem
  10. az6007_ci_write_attribute_mem
  11. az6007_ci_read_cam_control
  12. az6007_ci_write_cam_control
  13. CI_CamReady
  14. az6007_ci_slot_reset
  15. az6007_ci_slot_shutdown
  16. az6007_ci_slot_ts_enable
  17. az6007_ci_poll_slot_status
  18. az6007_ci_uninit
  19. az6007_ci_init
  20. az6007_read_mac_addr
  21. az6007_frontend_attach
  22. az6007_cablestar_hdci_frontend_attach
  23. az6007_tuner_attach
  24. az6007_power_ctrl
  25. az6007_i2c_xfer
  26. az6007_i2c_func
  27. az6007_identify_state
  28. az6007_usb_disconnect
  29. az6007_download_firmware
  30. az6007_suspend
  31. az6007_resume

   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 
  24 static int az6007_xfer_debug;
  25 module_param_named(xfer_debug, az6007_xfer_debug, int, 0644);
  26 MODULE_PARM_DESC(xfer_debug, "Enable xfer debug");
  27 
  28 DVB_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 
  41 struct 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 
  50 static 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 
  63 static 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 
  76 static 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 
  95 static struct mt2063_config az6007_mt2063_config = {
  96         .tuner_address = 0x60,
  97         .refclock = 36125000,
  98 };
  99 
 100 static 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 
 125 static 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 
 141 static 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 
 172 static 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 
 188 static 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) */
 199 static 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 
 232 static 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 
 247 static 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 
 288 static 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 
 320 static 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 
 365 static 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 
 394 failed:
 395         mutex_unlock(&state->ca_mutex);
 396         return ret;
 397 }
 398 
 399 static 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 
 430 static 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 
 476 failed:
 477         mutex_unlock(&state->ca_mutex);
 478         return ret;
 479 }
 480 
 481 static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
 482 {
 483         return 0;
 484 }
 485 
 486 static 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 
 510 failed:
 511         mutex_unlock(&state->ca_mutex);
 512         return ret;
 513 }
 514 
 515 static 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 
 554 static 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 
 576 static 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 
 611 static 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 
 626 static 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 
 647 static 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 
 668 static 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 
 688 static 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 */
 742 static 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         }
 817 err:
 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 
 827 static u32 az6007_i2c_func(struct i2c_adapter *adapter)
 828 {
 829         return I2C_FUNC_I2C;
 830 }
 831 
 832 static struct i2c_algorithm az6007_i2c_algo = {
 833         .master_xfer = az6007_i2c_xfer,
 834         .functionality = az6007_i2c_func,
 835 };
 836 
 837 static 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 
 868 static 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 
 875 static 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 */
 884 static 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 
 906 static 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 
 929 static 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 
 941 MODULE_DEVICE_TABLE(usb, az6007_usb_table);
 942 
 943 static 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 
 951 static 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 */
 961 static 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 
 976 module_usb_driver(az6007_usb_driver);
 977 
 978 MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>");
 979 MODULE_AUTHOR("Mauro Carvalho Chehab");
 980 MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones");
 981 MODULE_VERSION("2.0");
 982 MODULE_LICENSE("GPL");
 983 MODULE_FIRMWARE(AZ6007_FIRMWARE);

/* [<][>][^][v][top][bottom][index][help] */