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