linux/drivers/media/usb/dvb-usb-v2/az6007.c
<<
>>
Prefs
   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);
 984