linux/drivers/media/usb/au0828/au0828-dvb.c
<<
>>
Prefs
   1/*
   2 *  Driver for the Auvitek USB bridge
   3 *
   4 *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
   5 *
   6 *  This program is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; either version 2 of the License, or
   9 *  (at your option) any later version.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *
  15 *  GNU General Public License for more details.
  16 *
  17 *  You should have received a copy of the GNU General Public License
  18 *  along with this program; if not, write to the Free Software
  19 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20 */
  21
  22#include "au0828.h"
  23
  24#include <linux/module.h>
  25#include <linux/slab.h>
  26#include <linux/init.h>
  27#include <linux/device.h>
  28#include <media/v4l2-common.h>
  29#include <media/tuner.h>
  30
  31#include "au8522.h"
  32#include "xc5000.h"
  33#include "mxl5007t.h"
  34#include "tda18271.h"
  35
  36static int preallocate_big_buffers;
  37module_param_named(preallocate_big_buffers, preallocate_big_buffers, int, 0644);
  38MODULE_PARM_DESC(preallocate_big_buffers, "Preallocate the larger transfer buffers at module load time");
  39
  40DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  41
  42#define _AU0828_BULKPIPE 0x83
  43#define _BULKPIPESIZE 0xe522
  44
  45static u8 hauppauge_hvr950q_led_states[] = {
  46        0x00, /* off */
  47        0x02, /* yellow */
  48        0x04, /* green */
  49};
  50
  51static struct au8522_led_config hauppauge_hvr950q_led_cfg = {
  52        .gpio_output = 0x00e0,
  53        .gpio_output_enable  = 0x6006,
  54        .gpio_output_disable = 0x0660,
  55
  56        .gpio_leds = 0x00e2,
  57        .led_states  = hauppauge_hvr950q_led_states,
  58        .num_led_states = sizeof(hauppauge_hvr950q_led_states),
  59
  60        .vsb8_strong   = 20 /* dB */ * 10,
  61        .qam64_strong  = 25 /* dB */ * 10,
  62        .qam256_strong = 32 /* dB */ * 10,
  63};
  64
  65static struct au8522_config hauppauge_hvr950q_config = {
  66        .demod_address = 0x8e >> 1,
  67        .status_mode   = AU8522_DEMODLOCKING,
  68        .qam_if        = AU8522_IF_6MHZ,
  69        .vsb_if        = AU8522_IF_6MHZ,
  70        .led_cfg       = &hauppauge_hvr950q_led_cfg,
  71};
  72
  73static struct au8522_config fusionhdtv7usb_config = {
  74        .demod_address = 0x8e >> 1,
  75        .status_mode   = AU8522_DEMODLOCKING,
  76        .qam_if        = AU8522_IF_6MHZ,
  77        .vsb_if        = AU8522_IF_6MHZ,
  78};
  79
  80static struct au8522_config hauppauge_woodbury_config = {
  81        .demod_address = 0x8e >> 1,
  82        .status_mode   = AU8522_DEMODLOCKING,
  83        .qam_if        = AU8522_IF_4MHZ,
  84        .vsb_if        = AU8522_IF_3_25MHZ,
  85};
  86
  87static struct xc5000_config hauppauge_xc5000a_config = {
  88        .i2c_address      = 0x61,
  89        .if_khz           = 6000,
  90        .chip_id          = XC5000A,
  91        .output_amp       = 0x8f,
  92};
  93
  94static struct xc5000_config hauppauge_xc5000c_config = {
  95        .i2c_address      = 0x61,
  96        .if_khz           = 6000,
  97        .chip_id          = XC5000C,
  98        .output_amp       = 0x8f,
  99};
 100
 101static struct mxl5007t_config mxl5007t_hvr950q_config = {
 102        .xtal_freq_hz = MxL_XTAL_24_MHZ,
 103        .if_freq_hz = MxL_IF_6_MHZ,
 104};
 105
 106static struct tda18271_config hauppauge_woodbury_tunerconfig = {
 107        .gate    = TDA18271_GATE_DIGITAL,
 108};
 109
 110static void au0828_restart_dvb_streaming(struct work_struct *work);
 111
 112/*-------------------------------------------------------------------*/
 113static void urb_completion(struct urb *purb)
 114{
 115        struct au0828_dev *dev = purb->context;
 116        int ptype = usb_pipetype(purb->pipe);
 117        unsigned char *ptr;
 118
 119        dprintk(2, "%s: %d\n", __func__, purb->actual_length);
 120
 121        if (!dev) {
 122                dprintk(2, "%s: no dev!\n", __func__);
 123                return;
 124        }
 125
 126        if (!dev->urb_streaming) {
 127                dprintk(2, "%s: not streaming!\n", __func__);
 128                return;
 129        }
 130
 131        if (ptype != PIPE_BULK) {
 132                pr_err("%s: Unsupported URB type %d\n",
 133                       __func__, ptype);
 134                return;
 135        }
 136
 137        /* See if the stream is corrupted (to work around a hardware
 138           bug where the stream gets misaligned */
 139        ptr = purb->transfer_buffer;
 140        if (purb->actual_length > 0 && ptr[0] != 0x47) {
 141                dprintk(1, "Need to restart streaming %02x len=%d!\n",
 142                        ptr[0], purb->actual_length);
 143                schedule_work(&dev->restart_streaming);
 144                return;
 145        }
 146
 147        /* Feed the transport payload into the kernel demux */
 148        dvb_dmx_swfilter_packets(&dev->dvb.demux,
 149                purb->transfer_buffer, purb->actual_length / 188);
 150
 151        /* Clean the buffer before we requeue */
 152        memset(purb->transfer_buffer, 0, URB_BUFSIZE);
 153
 154        /* Requeue URB */
 155        usb_submit_urb(purb, GFP_ATOMIC);
 156}
 157
 158static int stop_urb_transfer(struct au0828_dev *dev)
 159{
 160        int i;
 161
 162        dprintk(2, "%s()\n", __func__);
 163
 164        if (!dev->urb_streaming)
 165                return 0;
 166
 167        dev->urb_streaming = false;
 168        for (i = 0; i < URB_COUNT; i++) {
 169                if (dev->urbs[i]) {
 170                        usb_kill_urb(dev->urbs[i]);
 171                        if (!preallocate_big_buffers)
 172                                kfree(dev->urbs[i]->transfer_buffer);
 173
 174                        usb_free_urb(dev->urbs[i]);
 175                }
 176        }
 177
 178        return 0;
 179}
 180
 181static int start_urb_transfer(struct au0828_dev *dev)
 182{
 183        struct urb *purb;
 184        int i, ret = -ENOMEM;
 185
 186        dprintk(2, "%s()\n", __func__);
 187
 188        if (dev->urb_streaming) {
 189                dprintk(2, "%s: bulk xfer already running!\n", __func__);
 190                return 0;
 191        }
 192
 193        for (i = 0; i < URB_COUNT; i++) {
 194
 195                dev->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
 196                if (!dev->urbs[i])
 197                        goto err;
 198
 199                purb = dev->urbs[i];
 200
 201                if (preallocate_big_buffers)
 202                        purb->transfer_buffer = dev->dig_transfer_buffer[i];
 203                else
 204                        purb->transfer_buffer = kzalloc(URB_BUFSIZE,
 205                                        GFP_KERNEL);
 206
 207                if (!purb->transfer_buffer) {
 208                        usb_free_urb(purb);
 209                        dev->urbs[i] = NULL;
 210                        pr_err("%s: failed big buffer allocation, err = %d\n",
 211                               __func__, ret);
 212                        goto err;
 213                }
 214
 215                purb->status = -EINPROGRESS;
 216                usb_fill_bulk_urb(purb,
 217                                  dev->usbdev,
 218                                  usb_rcvbulkpipe(dev->usbdev,
 219                                        _AU0828_BULKPIPE),
 220                                  purb->transfer_buffer,
 221                                  URB_BUFSIZE,
 222                                  urb_completion,
 223                                  dev);
 224
 225        }
 226
 227        for (i = 0; i < URB_COUNT; i++) {
 228                ret = usb_submit_urb(dev->urbs[i], GFP_ATOMIC);
 229                if (ret != 0) {
 230                        stop_urb_transfer(dev);
 231                        pr_err("%s: failed urb submission, err = %d\n",
 232                               __func__, ret);
 233                        return ret;
 234                }
 235        }
 236
 237        dev->urb_streaming = true;
 238        ret = 0;
 239
 240err:
 241        return ret;
 242}
 243
 244static void au0828_start_transport(struct au0828_dev *dev)
 245{
 246        au0828_write(dev, 0x608, 0x90);
 247        au0828_write(dev, 0x609, 0x72);
 248        au0828_write(dev, 0x60a, 0x71);
 249        au0828_write(dev, 0x60b, 0x01);
 250
 251}
 252
 253static void au0828_stop_transport(struct au0828_dev *dev, int full_stop)
 254{
 255        if (full_stop) {
 256                au0828_write(dev, 0x608, 0x00);
 257                au0828_write(dev, 0x609, 0x00);
 258                au0828_write(dev, 0x60a, 0x00);
 259        }
 260        au0828_write(dev, 0x60b, 0x00);
 261}
 262
 263static int au0828_dvb_start_feed(struct dvb_demux_feed *feed)
 264{
 265        struct dvb_demux *demux = feed->demux;
 266        struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
 267        struct au0828_dvb *dvb = &dev->dvb;
 268        int ret = 0;
 269
 270        dprintk(1, "%s()\n", __func__);
 271
 272        if (!demux->dmx.frontend)
 273                return -EINVAL;
 274
 275        if (dvb->frontend) {
 276                mutex_lock(&dvb->lock);
 277                dvb->start_count++;
 278                dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__,
 279                        dvb->start_count, dvb->stop_count);
 280                if (dvb->feeding++ == 0) {
 281                        /* Start transport */
 282                        au0828_start_transport(dev);
 283                        ret = start_urb_transfer(dev);
 284                        if (ret < 0) {
 285                                au0828_stop_transport(dev, 0);
 286                                dvb->feeding--; /* We ran out of memory... */
 287                        }
 288                }
 289                mutex_unlock(&dvb->lock);
 290        }
 291
 292        return ret;
 293}
 294
 295static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
 296{
 297        struct dvb_demux *demux = feed->demux;
 298        struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
 299        struct au0828_dvb *dvb = &dev->dvb;
 300        int ret = 0;
 301
 302        dprintk(1, "%s()\n", __func__);
 303
 304        if (dvb->frontend) {
 305                cancel_work_sync(&dev->restart_streaming);
 306
 307                mutex_lock(&dvb->lock);
 308                dvb->stop_count++;
 309                dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__,
 310                        dvb->start_count, dvb->stop_count);
 311                if (dvb->feeding > 0) {
 312                        dvb->feeding--;
 313                        if (dvb->feeding == 0) {
 314                                /* Stop transport */
 315                                ret = stop_urb_transfer(dev);
 316                                au0828_stop_transport(dev, 0);
 317                        }
 318                }
 319                mutex_unlock(&dvb->lock);
 320        }
 321
 322        return ret;
 323}
 324
 325static void au0828_restart_dvb_streaming(struct work_struct *work)
 326{
 327        struct au0828_dev *dev = container_of(work, struct au0828_dev,
 328                                              restart_streaming);
 329        struct au0828_dvb *dvb = &dev->dvb;
 330
 331        if (!dev->urb_streaming)
 332                return;
 333
 334        dprintk(1, "Restarting streaming...!\n");
 335
 336        mutex_lock(&dvb->lock);
 337
 338        /* Stop transport */
 339        stop_urb_transfer(dev);
 340        au0828_stop_transport(dev, 1);
 341
 342        /* Start transport */
 343        au0828_start_transport(dev);
 344        start_urb_transfer(dev);
 345
 346        mutex_unlock(&dvb->lock);
 347}
 348
 349static int au0828_set_frontend(struct dvb_frontend *fe)
 350{
 351        struct au0828_dev *dev = fe->dvb->priv;
 352        struct au0828_dvb *dvb = &dev->dvb;
 353        int ret, was_streaming;
 354
 355        mutex_lock(&dvb->lock);
 356        was_streaming = dev->urb_streaming;
 357        if (was_streaming) {
 358                au0828_stop_transport(dev, 1);
 359
 360                /*
 361                 * We can't hold a mutex here, as the restart_streaming
 362                 * kthread may also hold it.
 363                 */
 364                mutex_unlock(&dvb->lock);
 365                cancel_work_sync(&dev->restart_streaming);
 366                mutex_lock(&dvb->lock);
 367
 368                stop_urb_transfer(dev);
 369        }
 370        mutex_unlock(&dvb->lock);
 371
 372        ret = dvb->set_frontend(fe);
 373
 374        if (was_streaming) {
 375                mutex_lock(&dvb->lock);
 376                au0828_start_transport(dev);
 377                start_urb_transfer(dev);
 378                mutex_unlock(&dvb->lock);
 379        }
 380
 381        return ret;
 382}
 383
 384static int dvb_register(struct au0828_dev *dev)
 385{
 386        struct au0828_dvb *dvb = &dev->dvb;
 387        int result;
 388
 389        dprintk(1, "%s()\n", __func__);
 390
 391        if (preallocate_big_buffers) {
 392                int i;
 393                for (i = 0; i < URB_COUNT; i++) {
 394                        dev->dig_transfer_buffer[i] = kzalloc(URB_BUFSIZE,
 395                                        GFP_KERNEL);
 396
 397                        if (!dev->dig_transfer_buffer[i]) {
 398                                result = -ENOMEM;
 399
 400                                pr_err("failed buffer allocation (errno = %d)\n",
 401                                       result);
 402                                goto fail_adapter;
 403                        }
 404                }
 405        }
 406
 407        INIT_WORK(&dev->restart_streaming, au0828_restart_dvb_streaming);
 408
 409        /* register adapter */
 410        result = dvb_register_adapter(&dvb->adapter,
 411                                      KBUILD_MODNAME, THIS_MODULE,
 412                                      &dev->usbdev->dev, adapter_nr);
 413        if (result < 0) {
 414                pr_err("dvb_register_adapter failed (errno = %d)\n",
 415                       result);
 416                goto fail_adapter;
 417        }
 418        dvb->adapter.priv = dev;
 419
 420        /* register frontend */
 421        result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
 422        if (result < 0) {
 423                pr_err("dvb_register_frontend failed (errno = %d)\n",
 424                       result);
 425                goto fail_frontend;
 426        }
 427
 428        /* Hook dvb frontend */
 429        dvb->set_frontend = dvb->frontend->ops.set_frontend;
 430        dvb->frontend->ops.set_frontend = au0828_set_frontend;
 431
 432        /* register demux stuff */
 433        dvb->demux.dmx.capabilities =
 434                DMX_TS_FILTERING | DMX_SECTION_FILTERING |
 435                DMX_MEMORY_BASED_FILTERING;
 436        dvb->demux.priv       = dev;
 437        dvb->demux.filternum  = 256;
 438        dvb->demux.feednum    = 256;
 439        dvb->demux.start_feed = au0828_dvb_start_feed;
 440        dvb->demux.stop_feed  = au0828_dvb_stop_feed;
 441        result = dvb_dmx_init(&dvb->demux);
 442        if (result < 0) {
 443                pr_err("dvb_dmx_init failed (errno = %d)\n", result);
 444                goto fail_dmx;
 445        }
 446
 447        dvb->dmxdev.filternum    = 256;
 448        dvb->dmxdev.demux        = &dvb->demux.dmx;
 449        dvb->dmxdev.capabilities = 0;
 450        result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
 451        if (result < 0) {
 452                pr_err("dvb_dmxdev_init failed (errno = %d)\n", result);
 453                goto fail_dmxdev;
 454        }
 455
 456        dvb->fe_hw.source = DMX_FRONTEND_0;
 457        result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 458        if (result < 0) {
 459                pr_err("add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
 460                       result);
 461                goto fail_fe_hw;
 462        }
 463
 464        dvb->fe_mem.source = DMX_MEMORY_FE;
 465        result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 466        if (result < 0) {
 467                pr_err("add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
 468                       result);
 469                goto fail_fe_mem;
 470        }
 471
 472        result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 473        if (result < 0) {
 474                pr_err("connect_frontend failed (errno = %d)\n", result);
 475                goto fail_fe_conn;
 476        }
 477
 478        /* register network adapter */
 479        dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
 480
 481        dvb->start_count = 0;
 482        dvb->stop_count = 0;
 483        return 0;
 484
 485fail_fe_conn:
 486        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 487fail_fe_mem:
 488        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 489fail_fe_hw:
 490        dvb_dmxdev_release(&dvb->dmxdev);
 491fail_dmxdev:
 492        dvb_dmx_release(&dvb->demux);
 493fail_dmx:
 494        dvb_unregister_frontend(dvb->frontend);
 495fail_frontend:
 496        dvb_frontend_detach(dvb->frontend);
 497        dvb_unregister_adapter(&dvb->adapter);
 498fail_adapter:
 499
 500        if (preallocate_big_buffers) {
 501                int i;
 502                for (i = 0; i < URB_COUNT; i++)
 503                        kfree(dev->dig_transfer_buffer[i]);
 504        }
 505
 506        return result;
 507}
 508
 509void au0828_dvb_unregister(struct au0828_dev *dev)
 510{
 511        struct au0828_dvb *dvb = &dev->dvb;
 512
 513        dprintk(1, "%s()\n", __func__);
 514
 515        if (dvb->frontend == NULL)
 516                return;
 517
 518        cancel_work_sync(&dev->restart_streaming);
 519
 520        dvb_net_release(&dvb->net);
 521        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 522        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 523        dvb_dmxdev_release(&dvb->dmxdev);
 524        dvb_dmx_release(&dvb->demux);
 525        dvb_unregister_frontend(dvb->frontend);
 526        dvb_frontend_detach(dvb->frontend);
 527        dvb_unregister_adapter(&dvb->adapter);
 528
 529        if (preallocate_big_buffers) {
 530                int i;
 531                for (i = 0; i < URB_COUNT; i++)
 532                        kfree(dev->dig_transfer_buffer[i]);
 533        }
 534        dvb->frontend = NULL;
 535}
 536
 537/* All the DVB attach calls go here, this function get's modified
 538 * for each new card. No other function in this file needs
 539 * to change.
 540 */
 541int au0828_dvb_register(struct au0828_dev *dev)
 542{
 543        struct au0828_dvb *dvb = &dev->dvb;
 544        int ret;
 545
 546        dprintk(1, "%s()\n", __func__);
 547
 548        /* init frontend */
 549        switch (dev->boardnr) {
 550        case AU0828_BOARD_HAUPPAUGE_HVR850:
 551        case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 552                dvb->frontend = dvb_attach(au8522_attach,
 553                                &hauppauge_hvr950q_config,
 554                                &dev->i2c_adap);
 555                if (dvb->frontend != NULL)
 556                        switch (dev->board.tuner_type) {
 557                        default:
 558                        case TUNER_XC5000:
 559                                dvb_attach(xc5000_attach, dvb->frontend,
 560                                           &dev->i2c_adap,
 561                                           &hauppauge_xc5000a_config);
 562                                break;
 563                        case TUNER_XC5000C:
 564                                dvb_attach(xc5000_attach, dvb->frontend,
 565                                           &dev->i2c_adap,
 566                                           &hauppauge_xc5000c_config);
 567                                break;
 568                        }
 569                break;
 570        case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
 571                dvb->frontend = dvb_attach(au8522_attach,
 572                                &hauppauge_hvr950q_config,
 573                                &dev->i2c_adap);
 574                if (dvb->frontend != NULL)
 575                        dvb_attach(mxl5007t_attach, dvb->frontend,
 576                                   &dev->i2c_adap, 0x60,
 577                                   &mxl5007t_hvr950q_config);
 578                break;
 579        case AU0828_BOARD_HAUPPAUGE_WOODBURY:
 580                dvb->frontend = dvb_attach(au8522_attach,
 581                                &hauppauge_woodbury_config,
 582                                &dev->i2c_adap);
 583                if (dvb->frontend != NULL)
 584                        dvb_attach(tda18271_attach, dvb->frontend,
 585                                   0x60, &dev->i2c_adap,
 586                                   &hauppauge_woodbury_tunerconfig);
 587                break;
 588        case AU0828_BOARD_DVICO_FUSIONHDTV7:
 589                dvb->frontend = dvb_attach(au8522_attach,
 590                                &fusionhdtv7usb_config,
 591                                &dev->i2c_adap);
 592                if (dvb->frontend != NULL) {
 593                        dvb_attach(xc5000_attach, dvb->frontend,
 594                                &dev->i2c_adap,
 595                                &hauppauge_xc5000a_config);
 596                }
 597                break;
 598        default:
 599                pr_warn("The frontend of your DVB/ATSC card isn't supported yet\n");
 600                break;
 601        }
 602        if (NULL == dvb->frontend) {
 603                pr_err("%s() Frontend initialization failed\n",
 604                       __func__);
 605                return -1;
 606        }
 607        /* define general-purpose callback pointer */
 608        dvb->frontend->callback = au0828_tuner_callback;
 609
 610        /* register everything */
 611        ret = dvb_register(dev);
 612        if (ret < 0) {
 613                if (dvb->frontend->ops.release)
 614                        dvb->frontend->ops.release(dvb->frontend);
 615                dvb->frontend = NULL;
 616                return ret;
 617        }
 618
 619        return 0;
 620}
 621
 622void au0828_dvb_suspend(struct au0828_dev *dev)
 623{
 624        struct au0828_dvb *dvb = &dev->dvb;
 625        int rc;
 626
 627        if (dvb->frontend) {
 628                if (dev->urb_streaming) {
 629                        cancel_work_sync(&dev->restart_streaming);
 630                        /* Stop transport */
 631                        mutex_lock(&dvb->lock);
 632                        stop_urb_transfer(dev);
 633                        au0828_stop_transport(dev, 1);
 634                        mutex_unlock(&dvb->lock);
 635                        dev->need_urb_start = true;
 636                }
 637                /* suspend frontend - does tuner and fe to sleep */
 638                rc = dvb_frontend_suspend(dvb->frontend);
 639                pr_info("au0828_dvb_suspend(): Suspending DVB fe %d\n", rc);
 640        }
 641}
 642
 643void au0828_dvb_resume(struct au0828_dev *dev)
 644{
 645        struct au0828_dvb *dvb = &dev->dvb;
 646        int rc;
 647
 648        if (dvb->frontend) {
 649                /* resume frontend - does fe and tuner init */
 650                rc = dvb_frontend_resume(dvb->frontend);
 651                pr_info("au0828_dvb_resume(): Resuming DVB fe %d\n", rc);
 652                if (dev->need_urb_start) {
 653                        /* Start transport */
 654                        mutex_lock(&dvb->lock);
 655                        au0828_start_transport(dev);
 656                        start_urb_transfer(dev);
 657                        mutex_unlock(&dvb->lock);
 658                }
 659        }
 660}
 661