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 <linux/module.h>
  23#include <linux/slab.h>
  24#include <linux/init.h>
  25#include <linux/device.h>
  26#include <linux/suspend.h>
  27#include <media/v4l2-common.h>
  28#include <media/tuner.h>
  29
  30#include "au0828.h"
  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};
  92
  93static struct xc5000_config hauppauge_xc5000c_config = {
  94        .i2c_address      = 0x61,
  95        .if_khz           = 6000,
  96        .chip_id          = XC5000C,
  97};
  98
  99static struct mxl5007t_config mxl5007t_hvr950q_config = {
 100        .xtal_freq_hz = MxL_XTAL_24_MHZ,
 101        .if_freq_hz = MxL_IF_6_MHZ,
 102};
 103
 104static struct tda18271_config hauppauge_woodbury_tunerconfig = {
 105        .gate    = TDA18271_GATE_DIGITAL,
 106};
 107
 108static void au0828_restart_dvb_streaming(struct work_struct *work);
 109
 110/*-------------------------------------------------------------------*/
 111static void urb_completion(struct urb *purb)
 112{
 113        struct au0828_dev *dev = purb->context;
 114        int ptype = usb_pipetype(purb->pipe);
 115        unsigned char *ptr;
 116
 117        dprintk(2, "%s: %d\n", __func__, purb->actual_length);
 118
 119        if (!dev) {
 120                dprintk(2, "%s: no dev!\n", __func__);
 121                return;
 122        }
 123
 124        if (dev->urb_streaming == 0) {
 125                dprintk(2, "%s: not streaming!\n", __func__);
 126                return;
 127        }
 128
 129        if (ptype != PIPE_BULK) {
 130                printk(KERN_ERR "%s: Unsupported URB type %d\n",
 131                       __func__, ptype);
 132                return;
 133        }
 134
 135        /* See if the stream is corrupted (to work around a hardware
 136           bug where the stream gets misaligned */
 137        ptr = purb->transfer_buffer;
 138        if (purb->actual_length > 0 && ptr[0] != 0x47) {
 139                dprintk(1, "Need to restart streaming %02x len=%d!\n",
 140                        ptr[0], purb->actual_length);
 141                schedule_work(&dev->restart_streaming);
 142                return;
 143        }
 144
 145        /* Feed the transport payload into the kernel demux */
 146        dvb_dmx_swfilter_packets(&dev->dvb.demux,
 147                purb->transfer_buffer, purb->actual_length / 188);
 148
 149        /* Clean the buffer before we requeue */
 150        memset(purb->transfer_buffer, 0, URB_BUFSIZE);
 151
 152        /* Requeue URB */
 153        usb_submit_urb(purb, GFP_ATOMIC);
 154}
 155
 156static int stop_urb_transfer(struct au0828_dev *dev)
 157{
 158        int i;
 159
 160        dprintk(2, "%s()\n", __func__);
 161
 162        dev->urb_streaming = 0;
 163        for (i = 0; i < URB_COUNT; i++) {
 164                if (dev->urbs[i]) {
 165                        usb_kill_urb(dev->urbs[i]);
 166                        if (!preallocate_big_buffers)
 167                                kfree(dev->urbs[i]->transfer_buffer);
 168
 169                        usb_free_urb(dev->urbs[i]);
 170                }
 171        }
 172
 173        return 0;
 174}
 175
 176static int start_urb_transfer(struct au0828_dev *dev)
 177{
 178        struct urb *purb;
 179        int i, ret = -ENOMEM;
 180
 181        dprintk(2, "%s()\n", __func__);
 182
 183        if (dev->urb_streaming) {
 184                dprintk(2, "%s: bulk xfer already running!\n", __func__);
 185                return 0;
 186        }
 187
 188        for (i = 0; i < URB_COUNT; i++) {
 189
 190                dev->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
 191                if (!dev->urbs[i])
 192                        goto err;
 193
 194                purb = dev->urbs[i];
 195
 196                if (preallocate_big_buffers)
 197                        purb->transfer_buffer = dev->dig_transfer_buffer[i];
 198                else
 199                        purb->transfer_buffer = kzalloc(URB_BUFSIZE,
 200                                        GFP_KERNEL);
 201
 202                if (!purb->transfer_buffer) {
 203                        usb_free_urb(purb);
 204                        dev->urbs[i] = NULL;
 205                        printk(KERN_ERR
 206                               "%s: failed big buffer allocation, err = %d\n",
 207                               __func__, ret);
 208                        goto err;
 209                }
 210
 211                purb->status = -EINPROGRESS;
 212                usb_fill_bulk_urb(purb,
 213                                  dev->usbdev,
 214                                  usb_rcvbulkpipe(dev->usbdev,
 215                                        _AU0828_BULKPIPE),
 216                                  purb->transfer_buffer,
 217                                  URB_BUFSIZE,
 218                                  urb_completion,
 219                                  dev);
 220
 221        }
 222
 223        for (i = 0; i < URB_COUNT; i++) {
 224                ret = usb_submit_urb(dev->urbs[i], GFP_ATOMIC);
 225                if (ret != 0) {
 226                        stop_urb_transfer(dev);
 227                        printk(KERN_ERR "%s: failed urb submission, "
 228                               "err = %d\n", __func__, ret);
 229                        return ret;
 230                }
 231        }
 232
 233        dev->urb_streaming = 1;
 234        ret = 0;
 235
 236err:
 237        return ret;
 238}
 239
 240static void au0828_start_transport(struct au0828_dev *dev)
 241{
 242        au0828_write(dev, 0x608, 0x90);
 243        au0828_write(dev, 0x609, 0x72);
 244        au0828_write(dev, 0x60a, 0x71);
 245        au0828_write(dev, 0x60b, 0x01);
 246
 247}
 248
 249static void au0828_stop_transport(struct au0828_dev *dev, int full_stop)
 250{
 251        if (full_stop) {
 252                au0828_write(dev, 0x608, 0x00);
 253                au0828_write(dev, 0x609, 0x00);
 254                au0828_write(dev, 0x60a, 0x00);
 255        }
 256        au0828_write(dev, 0x60b, 0x00);
 257}
 258
 259static int au0828_dvb_start_feed(struct dvb_demux_feed *feed)
 260{
 261        struct dvb_demux *demux = feed->demux;
 262        struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
 263        struct au0828_dvb *dvb = &dev->dvb;
 264        int ret = 0;
 265
 266        dprintk(1, "%s()\n", __func__);
 267
 268        if (!demux->dmx.frontend)
 269                return -EINVAL;
 270
 271        if (dvb) {
 272                mutex_lock(&dvb->lock);
 273                dvb->start_count++;
 274                dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__,
 275                        dvb->start_count, dvb->stop_count);
 276                if (dvb->feeding++ == 0) {
 277                        /* Start transport */
 278                        au0828_start_transport(dev);
 279                        ret = start_urb_transfer(dev);
 280                        if (ret < 0) {
 281                                au0828_stop_transport(dev, 0);
 282                                dvb->feeding--; /* We ran out of memory... */
 283                        }
 284                }
 285                mutex_unlock(&dvb->lock);
 286        }
 287
 288        return ret;
 289}
 290
 291static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
 292{
 293        struct dvb_demux *demux = feed->demux;
 294        struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
 295        struct au0828_dvb *dvb = &dev->dvb;
 296        int ret = 0;
 297
 298        dprintk(1, "%s()\n", __func__);
 299
 300        if (dvb) {
 301                cancel_work_sync(&dev->restart_streaming);
 302
 303                mutex_lock(&dvb->lock);
 304                dvb->stop_count++;
 305                dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__,
 306                        dvb->start_count, dvb->stop_count);
 307                if (dvb->feeding > 0) {
 308                        dvb->feeding--;
 309                        if (dvb->feeding == 0) {
 310                                /* Stop transport */
 311                                ret = stop_urb_transfer(dev);
 312                                au0828_stop_transport(dev, 0);
 313                        }
 314                }
 315                mutex_unlock(&dvb->lock);
 316        }
 317
 318        return ret;
 319}
 320
 321static void au0828_restart_dvb_streaming(struct work_struct *work)
 322{
 323        struct au0828_dev *dev = container_of(work, struct au0828_dev,
 324                                              restart_streaming);
 325        struct au0828_dvb *dvb = &dev->dvb;
 326
 327        if (dev->urb_streaming == 0)
 328                return;
 329
 330        dprintk(1, "Restarting streaming...!\n");
 331
 332        mutex_lock(&dvb->lock);
 333
 334        /* Stop transport */
 335        stop_urb_transfer(dev);
 336        au0828_stop_transport(dev, 1);
 337
 338        /* Start transport */
 339        au0828_start_transport(dev);
 340        start_urb_transfer(dev);
 341
 342        mutex_unlock(&dvb->lock);
 343}
 344
 345static int au0828_set_frontend(struct dvb_frontend *fe)
 346{
 347        struct au0828_dev *dev = fe->dvb->priv;
 348        struct au0828_dvb *dvb = &dev->dvb;
 349        int ret, was_streaming;
 350
 351        mutex_lock(&dvb->lock);
 352        was_streaming = dev->urb_streaming;
 353        if (was_streaming) {
 354                au0828_stop_transport(dev, 1);
 355
 356                /*
 357                 * We can't hold a mutex here, as the restart_streaming
 358                 * kthread may also hold it.
 359                 */
 360                mutex_unlock(&dvb->lock);
 361                cancel_work_sync(&dev->restart_streaming);
 362                mutex_lock(&dvb->lock);
 363
 364                stop_urb_transfer(dev);
 365        }
 366        mutex_unlock(&dvb->lock);
 367
 368        ret = dvb->set_frontend(fe);
 369
 370        if (was_streaming) {
 371                mutex_lock(&dvb->lock);
 372                au0828_start_transport(dev);
 373                start_urb_transfer(dev);
 374                mutex_unlock(&dvb->lock);
 375        }
 376
 377        return ret;
 378}
 379
 380static int dvb_register(struct au0828_dev *dev)
 381{
 382        struct au0828_dvb *dvb = &dev->dvb;
 383        int result;
 384
 385        dprintk(1, "%s()\n", __func__);
 386
 387        if (preallocate_big_buffers) {
 388                int i;
 389                for (i = 0; i < URB_COUNT; i++) {
 390                        dev->dig_transfer_buffer[i] = kzalloc(URB_BUFSIZE,
 391                                        GFP_KERNEL);
 392
 393                        if (!dev->dig_transfer_buffer[i]) {
 394                                result = -ENOMEM;
 395
 396                                printk(KERN_ERR
 397                                       "%s: failed buffer allocation (errno = %d)\n",
 398                                       DRIVER_NAME, result);
 399                                goto fail_adapter;
 400                        }
 401                }
 402        }
 403
 404        INIT_WORK(&dev->restart_streaming, au0828_restart_dvb_streaming);
 405
 406        /* register adapter */
 407        result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
 408                                      &dev->usbdev->dev, adapter_nr);
 409        if (result < 0) {
 410                printk(KERN_ERR "%s: dvb_register_adapter failed "
 411                       "(errno = %d)\n", DRIVER_NAME, result);
 412                goto fail_adapter;
 413        }
 414        dvb->adapter.priv = dev;
 415
 416        /* register frontend */
 417        result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
 418        if (result < 0) {
 419                printk(KERN_ERR "%s: dvb_register_frontend failed "
 420                       "(errno = %d)\n", DRIVER_NAME, result);
 421                goto fail_frontend;
 422        }
 423
 424        /* Hook dvb frontend */
 425        dvb->set_frontend = dvb->frontend->ops.set_frontend;
 426        dvb->frontend->ops.set_frontend = au0828_set_frontend;
 427
 428        /* register demux stuff */
 429        dvb->demux.dmx.capabilities =
 430                DMX_TS_FILTERING | DMX_SECTION_FILTERING |
 431                DMX_MEMORY_BASED_FILTERING;
 432        dvb->demux.priv       = dev;
 433        dvb->demux.filternum  = 256;
 434        dvb->demux.feednum    = 256;
 435        dvb->demux.start_feed = au0828_dvb_start_feed;
 436        dvb->demux.stop_feed  = au0828_dvb_stop_feed;
 437        result = dvb_dmx_init(&dvb->demux);
 438        if (result < 0) {
 439                printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
 440                       DRIVER_NAME, result);
 441                goto fail_dmx;
 442        }
 443
 444        dvb->dmxdev.filternum    = 256;
 445        dvb->dmxdev.demux        = &dvb->demux.dmx;
 446        dvb->dmxdev.capabilities = 0;
 447        result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
 448        if (result < 0) {
 449                printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
 450                       DRIVER_NAME, result);
 451                goto fail_dmxdev;
 452        }
 453
 454        dvb->fe_hw.source = DMX_FRONTEND_0;
 455        result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 456        if (result < 0) {
 457                printk(KERN_ERR "%s: add_frontend failed "
 458                       "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
 459                goto fail_fe_hw;
 460        }
 461
 462        dvb->fe_mem.source = DMX_MEMORY_FE;
 463        result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 464        if (result < 0) {
 465                printk(KERN_ERR "%s: add_frontend failed "
 466                       "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
 467                goto fail_fe_mem;
 468        }
 469
 470        result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 471        if (result < 0) {
 472                printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
 473                       DRIVER_NAME, result);
 474                goto fail_fe_conn;
 475        }
 476
 477        /* register network adapter */
 478        dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
 479
 480        dvb->start_count = 0;
 481        dvb->stop_count = 0;
 482        return 0;
 483
 484fail_fe_conn:
 485        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 486fail_fe_mem:
 487        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 488fail_fe_hw:
 489        dvb_dmxdev_release(&dvb->dmxdev);
 490fail_dmxdev:
 491        dvb_dmx_release(&dvb->demux);
 492fail_dmx:
 493        dvb_unregister_frontend(dvb->frontend);
 494fail_frontend:
 495        dvb_frontend_detach(dvb->frontend);
 496        dvb_unregister_adapter(&dvb->adapter);
 497fail_adapter:
 498
 499        if (preallocate_big_buffers) {
 500                int i;
 501                for (i = 0; i < URB_COUNT; i++)
 502                        kfree(dev->dig_transfer_buffer[i]);
 503        }
 504
 505        return result;
 506}
 507
 508void au0828_dvb_unregister(struct au0828_dev *dev)
 509{
 510        struct au0828_dvb *dvb = &dev->dvb;
 511
 512        dprintk(1, "%s()\n", __func__);
 513
 514        if (dvb->frontend == NULL)
 515                return;
 516
 517        cancel_work_sync(&dev->restart_streaming);
 518
 519        dvb_net_release(&dvb->net);
 520        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 521        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 522        dvb_dmxdev_release(&dvb->dmxdev);
 523        dvb_dmx_release(&dvb->demux);
 524        dvb_unregister_frontend(dvb->frontend);
 525        dvb_frontend_detach(dvb->frontend);
 526        dvb_unregister_adapter(&dvb->adapter);
 527
 528        if (preallocate_big_buffers) {
 529                int i;
 530                for (i = 0; i < URB_COUNT; i++)
 531                        kfree(dev->dig_transfer_buffer[i]);
 532        }
 533
 534
 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                printk(KERN_WARNING "The frontend of your DVB/ATSC card "
 600                       "isn't supported yet\n");
 601                break;
 602        }
 603        if (NULL == dvb->frontend) {
 604                printk(KERN_ERR "%s() Frontend initialization failed\n",
 605                       __func__);
 606                return -1;
 607        }
 608        /* define general-purpose callback pointer */
 609        dvb->frontend->callback = au0828_tuner_callback;
 610
 611        /* register everything */
 612        ret = dvb_register(dev);
 613        if (ret < 0) {
 614                if (dvb->frontend->ops.release)
 615                        dvb->frontend->ops.release(dvb->frontend);
 616                return ret;
 617        }
 618
 619        return 0;
 620}
 621