linux/drivers/media/usb/dvb-usb-v2/gl861.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* DVB USB compliant linux driver for GL861 USB2.0 devices.
   3 *
   4 * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
   5 */
   6#include <linux/string.h>
   7
   8#include "gl861.h"
   9
  10#include "zl10353.h"
  11#include "qt1010.h"
  12#include "tc90522.h"
  13#include "dvb-pll.h"
  14
  15DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  16
  17static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
  18                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
  19{
  20        u16 index;
  21        u16 value = addr << (8 + 1);
  22        int wo = (rbuf == NULL || rlen == 0); /* write-only */
  23        u8 req, type;
  24        u8 *buf;
  25        int ret;
  26
  27        if (wo) {
  28                req = GL861_REQ_I2C_WRITE;
  29                type = GL861_WRITE;
  30                buf = kmemdup(wbuf, wlen, GFP_KERNEL);
  31        } else { /* rw */
  32                req = GL861_REQ_I2C_READ;
  33                type = GL861_READ;
  34                buf = kmalloc(rlen, GFP_KERNEL);
  35        }
  36        if (!buf)
  37                return -ENOMEM;
  38
  39        switch (wlen) {
  40        case 1:
  41                index = wbuf[0];
  42                break;
  43        case 2:
  44                index = wbuf[0];
  45                value = value + wbuf[1];
  46                break;
  47        default:
  48                dev_err(&d->udev->dev, "%s: wlen=%d, aborting\n",
  49                                KBUILD_MODNAME, wlen);
  50                kfree(buf);
  51                return -EINVAL;
  52        }
  53
  54        usleep_range(1000, 2000); /* avoid I2C errors */
  55
  56        ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
  57                              value, index, buf, rlen, 2000);
  58
  59        if (!wo && ret > 0)
  60                memcpy(rbuf, buf, rlen);
  61
  62        kfree(buf);
  63        return ret;
  64}
  65
  66/* I2C */
  67static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
  68                          int num)
  69{
  70        struct dvb_usb_device *d = i2c_get_adapdata(adap);
  71        int i;
  72
  73        if (num > 2)
  74                return -EINVAL;
  75
  76        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  77                return -EAGAIN;
  78
  79        for (i = 0; i < num; i++) {
  80                /* write/read request */
  81                if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
  82                        if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
  83                                msg[i].len, msg[i+1].buf, msg[i+1].len) < 0)
  84                                break;
  85                        i++;
  86                } else
  87                        if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
  88                                          msg[i].len, NULL, 0) < 0)
  89                                break;
  90        }
  91
  92        mutex_unlock(&d->i2c_mutex);
  93        return i;
  94}
  95
  96static u32 gl861_i2c_func(struct i2c_adapter *adapter)
  97{
  98        return I2C_FUNC_I2C;
  99}
 100
 101static struct i2c_algorithm gl861_i2c_algo = {
 102        .master_xfer   = gl861_i2c_xfer,
 103        .functionality = gl861_i2c_func,
 104};
 105
 106/* Callbacks for DVB USB */
 107static struct zl10353_config gl861_zl10353_config = {
 108        .demod_address = 0x0f,
 109        .no_tuner = 1,
 110        .parallel_ts = 1,
 111};
 112
 113static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
 114{
 115
 116        adap->fe[0] = dvb_attach(zl10353_attach, &gl861_zl10353_config,
 117                &adap_to_d(adap)->i2c_adap);
 118        if (adap->fe[0] == NULL)
 119                return -EIO;
 120
 121        return 0;
 122}
 123
 124static struct qt1010_config gl861_qt1010_config = {
 125        .i2c_address = 0x62
 126};
 127
 128static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
 129{
 130        return dvb_attach(qt1010_attach,
 131                          adap->fe[0], &adap_to_d(adap)->i2c_adap,
 132                          &gl861_qt1010_config) == NULL ? -ENODEV : 0;
 133}
 134
 135static int gl861_init(struct dvb_usb_device *d)
 136{
 137        /*
 138         * There is 2 interfaces. Interface 0 is for TV and interface 1 is
 139         * for HID remote controller. Interface 0 has 2 alternate settings.
 140         * For some reason we need to set interface explicitly, defaulted
 141         * as alternate setting 1?
 142         */
 143        return usb_set_interface(d->udev, 0, 0);
 144}
 145
 146/* DVB USB Driver stuff */
 147static struct dvb_usb_device_properties gl861_props = {
 148        .driver_name = KBUILD_MODNAME,
 149        .owner = THIS_MODULE,
 150        .adapter_nr = adapter_nr,
 151
 152        .i2c_algo = &gl861_i2c_algo,
 153        .frontend_attach = gl861_frontend_attach,
 154        .tuner_attach = gl861_tuner_attach,
 155        .init = gl861_init,
 156
 157        .num_adapters = 1,
 158        .adapter = {
 159                {
 160                        .stream = DVB_USB_STREAM_BULK(0x81, 7, 512),
 161                }
 162        }
 163};
 164
 165
 166/*
 167 * For Friio
 168 */
 169
 170struct friio_priv {
 171        struct i2c_adapter *demod_sub_i2c;
 172        struct i2c_client  *i2c_client_demod;
 173        struct i2c_client  *i2c_client_tuner;
 174        struct i2c_adapter tuner_adap;
 175};
 176
 177struct friio_config {
 178        struct i2c_board_info demod_info;
 179        struct tc90522_config demod_cfg;
 180
 181        struct i2c_board_info tuner_info;
 182        struct dvb_pll_config tuner_cfg;
 183};
 184
 185static const struct friio_config friio_config = {
 186        .demod_info = { I2C_BOARD_INFO(TC90522_I2C_DEV_TER, 0x18), },
 187        .tuner_info = { I2C_BOARD_INFO("tua6034_friio", 0x60), },
 188};
 189
 190/* For another type of I2C:
 191 * message sent by a USB control-read/write transaction with data stage.
 192 * Used in init/config of Friio.
 193 */
 194static int
 195gl861_i2c_write_ex(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen)
 196{
 197        u8 *buf;
 198        int ret;
 199
 200        buf = kmemdup(wbuf, wlen, GFP_KERNEL);
 201        if (!buf)
 202                return -ENOMEM;
 203
 204        ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
 205                                 GL861_REQ_I2C_RAW, GL861_WRITE,
 206                                 addr << (8 + 1), 0x0100, buf, wlen, 2000);
 207        kfree(buf);
 208        return ret;
 209}
 210
 211static int
 212gl861_i2c_read_ex(struct dvb_usb_device *d, u8 addr, u8 *rbuf, u16 rlen)
 213{
 214        u8 *buf;
 215        int ret;
 216
 217        buf = kmalloc(rlen, GFP_KERNEL);
 218        if (!buf)
 219                return -ENOMEM;
 220
 221        ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
 222                                 GL861_REQ_I2C_READ, GL861_READ,
 223                                 addr << (8 + 1), 0x0100, buf, rlen, 2000);
 224        if (ret > 0 && rlen > 0)
 225                memcpy(buf, rbuf, rlen);
 226        kfree(buf);
 227        return ret;
 228}
 229
 230/* For I2C transactions to the tuner of Friio (dvb_pll).
 231 *
 232 * Friio uses irregular USB encapsulation for tuner i2c transactions:
 233 * write transacions are encapsulated with a different USB 'request' value.
 234 *
 235 * Although all transactions are sent via the demod(tc90522)
 236 * and the demod provides an i2c adapter for them, it cannot be used in Friio
 237 * since it assumes using the same parent adapter with the demod,
 238 * which does not use the request value and uses same one for both read/write.
 239 * So we define a dedicated i2c adapter here.
 240 */
 241
 242static int
 243friio_i2c_tuner_read(struct dvb_usb_device *d, struct i2c_msg *msg)
 244{
 245        struct friio_priv *priv;
 246        u8 addr;
 247
 248        priv = d_to_priv(d);
 249        addr = priv->i2c_client_demod->addr;
 250        return gl861_i2c_read_ex(d, addr, msg->buf, msg->len);
 251}
 252
 253static int
 254friio_i2c_tuner_write(struct dvb_usb_device *d, struct i2c_msg *msg)
 255{
 256        u8 *buf;
 257        int ret;
 258        struct friio_priv *priv;
 259
 260        priv = d_to_priv(d);
 261
 262        if (msg->len < 1)
 263                return -EINVAL;
 264
 265        buf = kmalloc(msg->len + 1, GFP_KERNEL);
 266        if (!buf)
 267                return -ENOMEM;
 268        buf[0] = msg->addr << 1;
 269        memcpy(buf + 1, msg->buf, msg->len);
 270
 271        ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
 272                                 GL861_REQ_I2C_RAW, GL861_WRITE,
 273                                 priv->i2c_client_demod->addr << (8 + 1),
 274                                 0xFE, buf, msg->len + 1, 2000);
 275        kfree(buf);
 276        return ret;
 277}
 278
 279static int friio_tuner_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 280                                int num)
 281{
 282        struct dvb_usb_device *d = i2c_get_adapdata(adap);
 283        int i;
 284
 285        if (num > 2)
 286                return -EINVAL;
 287
 288        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 289                return -EAGAIN;
 290
 291        for (i = 0; i < num; i++) {
 292                int ret;
 293
 294                if (msg[i].flags & I2C_M_RD)
 295                        ret = friio_i2c_tuner_read(d, &msg[i]);
 296                else
 297                        ret = friio_i2c_tuner_write(d, &msg[i]);
 298
 299                if (ret < 0)
 300                        break;
 301
 302                usleep_range(1000, 2000); /* avoid I2C errors */
 303        }
 304
 305        mutex_unlock(&d->i2c_mutex);
 306        return i;
 307}
 308
 309static struct i2c_algorithm friio_tuner_i2c_algo = {
 310        .master_xfer   = friio_tuner_i2c_xfer,
 311        .functionality = gl861_i2c_func,
 312};
 313
 314/* GPIO control in Friio */
 315
 316#define FRIIO_CTL_LNB (1 << 0)
 317#define FRIIO_CTL_STROBE (1 << 1)
 318#define FRIIO_CTL_CLK (1 << 2)
 319#define FRIIO_CTL_LED (1 << 3)
 320
 321#define FRIIO_LED_RUNNING 0x6400ff64
 322#define FRIIO_LED_STOPPED 0x96ff00ff
 323
 324/* control PIC16F676 attached to Friio */
 325static int friio_ext_ctl(struct dvb_usb_device *d,
 326                            u32 sat_color, int power_on)
 327{
 328        int i, ret;
 329        struct i2c_msg msg;
 330        u8 *buf;
 331        u32 mask;
 332        u8 power = (power_on) ? FRIIO_CTL_LNB : 0;
 333
 334        buf = kmalloc(2, GFP_KERNEL);
 335        if (!buf)
 336                return -ENOMEM;
 337
 338        msg.addr = 0x00;
 339        msg.flags = 0;
 340        msg.len = 2;
 341        msg.buf = buf;
 342        buf[0] = 0x00;
 343
 344        /* send 2bit header (&B10) */
 345        buf[1] = power | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
 346        ret = i2c_transfer(&d->i2c_adap, &msg, 1);
 347        buf[1] |= FRIIO_CTL_CLK;
 348        ret += i2c_transfer(&d->i2c_adap, &msg, 1);
 349
 350        buf[1] = power | FRIIO_CTL_STROBE;
 351        ret += i2c_transfer(&d->i2c_adap, &msg, 1);
 352        buf[1] |= FRIIO_CTL_CLK;
 353        ret += i2c_transfer(&d->i2c_adap, &msg, 1);
 354
 355        /* send 32bit(satur, R, G, B) data in serial */
 356        mask = 1UL << 31;
 357        for (i = 0; i < 32; i++) {
 358                buf[1] = power | FRIIO_CTL_STROBE;
 359                if (sat_color & mask)
 360                        buf[1] |= FRIIO_CTL_LED;
 361                ret += i2c_transfer(&d->i2c_adap, &msg, 1);
 362                buf[1] |= FRIIO_CTL_CLK;
 363                ret += i2c_transfer(&d->i2c_adap, &msg, 1);
 364                mask >>= 1;
 365        }
 366
 367        /* set the strobe off */
 368        buf[1] = power;
 369        ret += i2c_transfer(&d->i2c_adap, &msg, 1);
 370        buf[1] |= FRIIO_CTL_CLK;
 371        ret += i2c_transfer(&d->i2c_adap, &msg, 1);
 372
 373        kfree(buf);
 374        return (ret == 70) ? 0 : -EREMOTEIO;
 375}
 376
 377/* init/config of gl861 for Friio */
 378/* NOTE:
 379 * This function cannot be moved to friio_init()/dvb_usbv2_init(),
 380 * because the init defined here must be done before any activities like I2C,
 381 * but friio_init() is called by dvb-usbv2 after {_frontend, _tuner}_attach(),
 382 * where I2C communication is used.
 383 * Thus this function is set to be called from _power_ctl().
 384 *
 385 * Since it will be called on the early init stage
 386 * where the i2c adapter is not initialized yet,
 387 * we cannot use i2c_transfer() here.
 388 */
 389static int friio_reset(struct dvb_usb_device *d)
 390{
 391        int i, ret;
 392        u8 wbuf[2], rbuf[2];
 393
 394        static const u8 friio_init_cmds[][2] = {
 395                {0x33, 0x08}, {0x37, 0x40}, {0x3a, 0x1f}, {0x3b, 0xff},
 396                {0x3c, 0x1f}, {0x3d, 0xff}, {0x38, 0x00}, {0x35, 0x00},
 397                {0x39, 0x00}, {0x36, 0x00},
 398        };
 399
 400        ret = usb_set_interface(d->udev, 0, 0);
 401        if (ret < 0)
 402                return ret;
 403
 404        wbuf[0] = 0x11;
 405        wbuf[1] = 0x02;
 406        ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
 407        if (ret < 0)
 408                return ret;
 409        usleep_range(2000, 3000);
 410
 411        wbuf[0] = 0x11;
 412        wbuf[1] = 0x00;
 413        ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
 414        if (ret < 0)
 415                return ret;
 416
 417        /*
 418         * Check if the dev is really a Friio White, since it might be
 419         * another device, Friio Black, with the same VID/PID.
 420         */
 421
 422        usleep_range(1000, 2000);
 423        wbuf[0] = 0x03;
 424        wbuf[1] = 0x80;
 425        ret = gl861_i2c_write_ex(d, 0x09, wbuf, 2);
 426        if (ret < 0)
 427                return ret;
 428
 429        usleep_range(2000, 3000);
 430        ret = gl861_i2c_read_ex(d, 0x09, rbuf, 2);
 431        if (ret < 0)
 432                return ret;
 433        if (rbuf[0] != 0xff || rbuf[1] != 0xff)
 434                return -ENODEV;
 435
 436
 437        usleep_range(1000, 2000);
 438        ret = gl861_i2c_write_ex(d, 0x48, wbuf, 2);
 439        if (ret < 0)
 440                return ret;
 441
 442        usleep_range(2000, 3000);
 443        ret = gl861_i2c_read_ex(d, 0x48, rbuf, 2);
 444        if (ret < 0)
 445                return ret;
 446        if (rbuf[0] != 0xff || rbuf[1] != 0xff)
 447                return -ENODEV;
 448
 449        wbuf[0] = 0x30;
 450        wbuf[1] = 0x04;
 451        ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
 452        if (ret < 0)
 453                return ret;
 454
 455        wbuf[0] = 0x00;
 456        wbuf[1] = 0x01;
 457        ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
 458        if (ret < 0)
 459                return ret;
 460
 461        wbuf[0] = 0x06;
 462        wbuf[1] = 0x0f;
 463        ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
 464        if (ret < 0)
 465                return ret;
 466
 467        for (i = 0; i < ARRAY_SIZE(friio_init_cmds); i++) {
 468                ret = gl861_i2c_msg(d, 0x00, (u8 *)friio_init_cmds[i], 2,
 469                                      NULL, 0);
 470                if (ret < 0)
 471                        return ret;
 472        }
 473        return 0;
 474}
 475
 476/*
 477 * DVB callbacks for Friio
 478 */
 479
 480static int friio_power_ctrl(struct dvb_usb_device *d, int onoff)
 481{
 482        return onoff ? friio_reset(d) : 0;
 483}
 484
 485static int friio_frontend_attach(struct dvb_usb_adapter *adap)
 486{
 487        const struct i2c_board_info *info;
 488        struct dvb_usb_device *d;
 489        struct tc90522_config cfg;
 490        struct i2c_client *cl;
 491        struct friio_priv *priv;
 492
 493        info = &friio_config.demod_info;
 494        d = adap_to_d(adap);
 495        cl = dvb_module_probe("tc90522", info->type,
 496                              &d->i2c_adap, info->addr, &cfg);
 497        if (!cl)
 498                return -ENODEV;
 499        adap->fe[0] = cfg.fe;
 500
 501        /* ignore cfg.tuner_i2c and create new one */
 502        priv = adap_to_priv(adap);
 503        priv->i2c_client_demod = cl;
 504        priv->tuner_adap.algo = &friio_tuner_i2c_algo;
 505        priv->tuner_adap.dev.parent = &d->udev->dev;
 506        strscpy(priv->tuner_adap.name, d->name, sizeof(priv->tuner_adap.name));
 507        strlcat(priv->tuner_adap.name, "-tuner", sizeof(priv->tuner_adap.name));
 508        priv->demod_sub_i2c = &priv->tuner_adap;
 509        i2c_set_adapdata(&priv->tuner_adap, d);
 510
 511        return i2c_add_adapter(&priv->tuner_adap);
 512}
 513
 514static int friio_frontend_detach(struct dvb_usb_adapter *adap)
 515{
 516        struct friio_priv *priv;
 517
 518        priv = adap_to_priv(adap);
 519        i2c_del_adapter(&priv->tuner_adap);
 520        dvb_module_release(priv->i2c_client_demod);
 521        return 0;
 522}
 523
 524static int friio_tuner_attach(struct dvb_usb_adapter *adap)
 525{
 526        const struct i2c_board_info *info;
 527        struct dvb_pll_config cfg;
 528        struct i2c_client *cl;
 529        struct friio_priv *priv;
 530
 531        priv = adap_to_priv(adap);
 532        info = &friio_config.tuner_info;
 533        cfg = friio_config.tuner_cfg;
 534        cfg.fe = adap->fe[0];
 535
 536        cl = dvb_module_probe("dvb_pll", info->type,
 537                              priv->demod_sub_i2c, info->addr, &cfg);
 538        if (!cl)
 539                return -ENODEV;
 540        priv->i2c_client_tuner = cl;
 541        return 0;
 542}
 543
 544static int friio_tuner_detach(struct dvb_usb_adapter *adap)
 545{
 546        struct friio_priv *priv;
 547
 548        priv = adap_to_priv(adap);
 549        dvb_module_release(priv->i2c_client_tuner);
 550        return 0;
 551}
 552
 553static int friio_init(struct dvb_usb_device *d)
 554{
 555        int i;
 556        int ret;
 557        struct friio_priv *priv;
 558
 559        static const u8 demod_init[][2] = {
 560                {0x01, 0x40}, {0x04, 0x38}, {0x05, 0x40}, {0x07, 0x40},
 561                {0x0f, 0x4f}, {0x11, 0x21}, {0x12, 0x0b}, {0x13, 0x2f},
 562                {0x14, 0x31}, {0x16, 0x02}, {0x21, 0xc4}, {0x22, 0x20},
 563                {0x2c, 0x79}, {0x2d, 0x34}, {0x2f, 0x00}, {0x30, 0x28},
 564                {0x31, 0x31}, {0x32, 0xdf}, {0x38, 0x01}, {0x39, 0x78},
 565                {0x3b, 0x33}, {0x3c, 0x33}, {0x48, 0x90}, {0x51, 0x68},
 566                {0x5e, 0x38}, {0x71, 0x00}, {0x72, 0x08}, {0x77, 0x00},
 567                {0xc0, 0x21}, {0xc1, 0x10}, {0xe4, 0x1a}, {0xea, 0x1f},
 568                {0x77, 0x00}, {0x71, 0x00}, {0x71, 0x00}, {0x76, 0x0c},
 569        };
 570
 571        /* power on LNA? */
 572        ret = friio_ext_ctl(d, FRIIO_LED_STOPPED, true);
 573        if (ret < 0)
 574                return ret;
 575        msleep(20);
 576
 577        /* init/config demod */
 578        priv = d_to_priv(d);
 579        for (i = 0; i < ARRAY_SIZE(demod_init); i++) {
 580                int ret;
 581
 582                ret = i2c_master_send(priv->i2c_client_demod, demod_init[i], 2);
 583                if (ret < 0)
 584                        return ret;
 585        }
 586        msleep(100);
 587        return 0;
 588}
 589
 590static void friio_exit(struct dvb_usb_device *d)
 591{
 592        friio_ext_ctl(d, FRIIO_LED_STOPPED, false);
 593}
 594
 595static int friio_streaming_ctrl(struct dvb_frontend *fe, int onoff)
 596{
 597        u32 led_color;
 598
 599        led_color = onoff ? FRIIO_LED_RUNNING : FRIIO_LED_STOPPED;
 600        return friio_ext_ctl(fe_to_d(fe), led_color, true);
 601}
 602
 603
 604static struct dvb_usb_device_properties friio_props = {
 605        .driver_name = KBUILD_MODNAME,
 606        .owner = THIS_MODULE,
 607        .adapter_nr = adapter_nr,
 608
 609        .size_of_priv = sizeof(struct friio_priv),
 610
 611        .i2c_algo = &gl861_i2c_algo,
 612        .power_ctrl = friio_power_ctrl,
 613        .frontend_attach = friio_frontend_attach,
 614        .frontend_detach = friio_frontend_detach,
 615        .tuner_attach = friio_tuner_attach,
 616        .tuner_detach = friio_tuner_detach,
 617        .init = friio_init,
 618        .exit = friio_exit,
 619        .streaming_ctrl = friio_streaming_ctrl,
 620
 621        .num_adapters = 1,
 622        .adapter = {
 623                {
 624                        .stream = DVB_USB_STREAM_BULK(0x01, 8, 16384),
 625                }
 626        }
 627};
 628
 629static const struct usb_device_id gl861_id_table[] = {
 630        { DVB_USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801,
 631                &gl861_props, "MSI Mega Sky 55801 DVB-T USB2.0", NULL) },
 632        { DVB_USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU,
 633                &gl861_props, "A-LINK DTU DVB-T USB2.0", NULL) },
 634        { DVB_USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE,
 635                &friio_props, "774 Friio White ISDB-T USB2.0", NULL) },
 636        { }
 637};
 638MODULE_DEVICE_TABLE(usb, gl861_id_table);
 639
 640static struct usb_driver gl861_usb_driver = {
 641        .name = KBUILD_MODNAME,
 642        .id_table = gl861_id_table,
 643        .probe = dvb_usbv2_probe,
 644        .disconnect = dvb_usbv2_disconnect,
 645        .suspend = dvb_usbv2_suspend,
 646        .resume = dvb_usbv2_resume,
 647        .reset_resume = dvb_usbv2_reset_resume,
 648        .no_dynamic_id = 1,
 649        .soft_unbind = 1,
 650};
 651
 652module_usb_driver(gl861_usb_driver);
 653
 654MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
 655MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
 656MODULE_VERSION("0.1");
 657MODULE_LICENSE("GPL");
 658