linux/drivers/media/usb/tm6000/tm6000-dvb.c
<<
>>
Prefs
   1/*
   2 *  tm6000-dvb.c - dvb-t support for TM5600/TM6000/TM6010 USB video capture devices
   3 *
   4 *  Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
   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 version 2
   9 *
  10 *  This program is distributed in the hope that it will be useful,
  11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 *  GNU General Public License for more details.
  14 *
  15 *  You should have received a copy of the GNU General Public License
  16 *  along with this program; if not, write to the Free Software
  17 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18 */
  19
  20#include <linux/kernel.h>
  21#include <linux/slab.h>
  22#include <linux/usb.h>
  23
  24#include "tm6000.h"
  25#include "tm6000-regs.h"
  26
  27#include "zl10353.h"
  28
  29#include <media/tuner.h>
  30
  31#include "tuner-xc2028.h"
  32#include "xc5000.h"
  33
  34MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV cards");
  35MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
  36MODULE_LICENSE("GPL");
  37
  38MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},"
  39                        "{{Trident, tm6000},"
  40                        "{{Trident, tm6010}");
  41
  42static int debug;
  43
  44module_param(debug, int, 0644);
  45MODULE_PARM_DESC(debug, "enable debug message");
  46
  47static inline void print_err_status(struct tm6000_core *dev,
  48                                    int packet, int status)
  49{
  50        char *errmsg = "Unknown";
  51
  52        switch (status) {
  53        case -ENOENT:
  54                errmsg = "unlinked synchronuously";
  55                break;
  56        case -ECONNRESET:
  57                errmsg = "unlinked asynchronuously";
  58                break;
  59        case -ENOSR:
  60                errmsg = "Buffer error (overrun)";
  61                break;
  62        case -EPIPE:
  63                errmsg = "Stalled (device not responding)";
  64                break;
  65        case -EOVERFLOW:
  66                errmsg = "Babble (bad cable?)";
  67                break;
  68        case -EPROTO:
  69                errmsg = "Bit-stuff error (bad cable?)";
  70                break;
  71        case -EILSEQ:
  72                errmsg = "CRC/Timeout (could be anything)";
  73                break;
  74        case -ETIME:
  75                errmsg = "Device does not respond";
  76                break;
  77        }
  78        if (packet < 0) {
  79                dprintk(dev, 1, "URB status %d [%s].\n",
  80                        status, errmsg);
  81        } else {
  82                dprintk(dev, 1, "URB packet %d, status %d [%s].\n",
  83                        packet, status, errmsg);
  84        }
  85}
  86
  87static void tm6000_urb_received(struct urb *urb)
  88{
  89        int ret;
  90        struct tm6000_core *dev = urb->context;
  91
  92        switch (urb->status) {
  93        case 0:
  94        case -ETIMEDOUT:
  95                break;
  96        case -ENOENT:
  97        case -ECONNRESET:
  98        case -ESHUTDOWN:
  99                return;
 100        default:
 101                print_err_status(dev, 0, urb->status);
 102        }
 103
 104        if (urb->actual_length > 0)
 105                dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
 106                                                   urb->actual_length);
 107
 108        if (dev->dvb->streams > 0) {
 109                ret = usb_submit_urb(urb, GFP_ATOMIC);
 110                if (ret < 0) {
 111                        printk(KERN_ERR "tm6000:  error %s\n", __func__);
 112                        kfree(urb->transfer_buffer);
 113                        usb_free_urb(urb);
 114                }
 115        }
 116}
 117
 118static int tm6000_start_stream(struct tm6000_core *dev)
 119{
 120        int ret;
 121        unsigned int pipe, size;
 122        struct tm6000_dvb *dvb = dev->dvb;
 123
 124        printk(KERN_INFO "tm6000: got start stream request %s\n", __func__);
 125
 126        if (dev->mode != TM6000_MODE_DIGITAL) {
 127                tm6000_init_digital_mode(dev);
 128                dev->mode = TM6000_MODE_DIGITAL;
 129        }
 130
 131        dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
 132        if (dvb->bulk_urb == NULL) {
 133                printk(KERN_ERR "tm6000: couldn't allocate urb\n");
 134                return -ENOMEM;
 135        }
 136
 137        pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress
 138                                                          & USB_ENDPOINT_NUMBER_MASK);
 139
 140        size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
 141        size = size * 15; /* 512 x 8 or 12 or 15 */
 142
 143        dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
 144        if (dvb->bulk_urb->transfer_buffer == NULL) {
 145                usb_free_urb(dvb->bulk_urb);
 146                printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
 147                return -ENOMEM;
 148        }
 149
 150        usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
 151                                                 dvb->bulk_urb->transfer_buffer,
 152                                                 size,
 153                                                 tm6000_urb_received, dev);
 154
 155        ret = usb_clear_halt(dev->udev, pipe);
 156        if (ret < 0) {
 157                printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",
 158                                                        ret, __func__);
 159                return ret;
 160        } else
 161                printk(KERN_ERR "tm6000: pipe resetted\n");
 162
 163/*      mutex_lock(&tm6000_driver.open_close_mutex); */
 164        ret = usb_submit_urb(dvb->bulk_urb, GFP_ATOMIC);
 165
 166/*      mutex_unlock(&tm6000_driver.open_close_mutex); */
 167        if (ret) {
 168                printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",
 169                                                                        ret);
 170
 171                kfree(dvb->bulk_urb->transfer_buffer);
 172                usb_free_urb(dvb->bulk_urb);
 173                return ret;
 174        }
 175
 176        return 0;
 177}
 178
 179static void tm6000_stop_stream(struct tm6000_core *dev)
 180{
 181        struct tm6000_dvb *dvb = dev->dvb;
 182
 183        if (dvb->bulk_urb) {
 184                printk(KERN_INFO "urb killing\n");
 185                usb_kill_urb(dvb->bulk_urb);
 186                printk(KERN_INFO "urb buffer free\n");
 187                kfree(dvb->bulk_urb->transfer_buffer);
 188                usb_free_urb(dvb->bulk_urb);
 189                dvb->bulk_urb = NULL;
 190        }
 191}
 192
 193static int tm6000_start_feed(struct dvb_demux_feed *feed)
 194{
 195        struct dvb_demux *demux = feed->demux;
 196        struct tm6000_core *dev = demux->priv;
 197        struct tm6000_dvb *dvb = dev->dvb;
 198        printk(KERN_INFO "tm6000: got start feed request %s\n", __func__);
 199
 200        mutex_lock(&dvb->mutex);
 201        if (dvb->streams == 0) {
 202                dvb->streams = 1;
 203/*              mutex_init(&tm6000_dev->streming_mutex); */
 204                tm6000_start_stream(dev);
 205        } else
 206                ++(dvb->streams);
 207        mutex_unlock(&dvb->mutex);
 208
 209        return 0;
 210}
 211
 212static int tm6000_stop_feed(struct dvb_demux_feed *feed)
 213{
 214        struct dvb_demux *demux = feed->demux;
 215        struct tm6000_core *dev = demux->priv;
 216        struct tm6000_dvb *dvb = dev->dvb;
 217
 218        printk(KERN_INFO "tm6000: got stop feed request %s\n", __func__);
 219
 220        mutex_lock(&dvb->mutex);
 221
 222        printk(KERN_INFO "stream %#x\n", dvb->streams);
 223        --(dvb->streams);
 224        if (dvb->streams == 0) {
 225                printk(KERN_INFO "stop stream\n");
 226                tm6000_stop_stream(dev);
 227/*              mutex_destroy(&tm6000_dev->streaming_mutex); */
 228        }
 229        mutex_unlock(&dvb->mutex);
 230/*      mutex_destroy(&tm6000_dev->streaming_mutex); */
 231
 232        return 0;
 233}
 234
 235static int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
 236{
 237        struct tm6000_dvb *dvb = dev->dvb;
 238
 239        if (dev->caps.has_zl10353) {
 240                struct zl10353_config config = {
 241                                     .demod_address = dev->demod_addr,
 242                                     .no_tuner = 1,
 243                                     .parallel_ts = 1,
 244                                     .if2 = 45700,
 245                                     .disable_i2c_gate_ctrl = 1,
 246                                    };
 247
 248                dvb->frontend = dvb_attach(zl10353_attach, &config,
 249                                                           &dev->i2c_adap);
 250        } else {
 251                printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
 252                return -1;
 253        }
 254
 255        return (!dvb->frontend) ? -1 : 0;
 256}
 257
 258DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 259
 260static int register_dvb(struct tm6000_core *dev)
 261{
 262        int ret = -1;
 263        struct tm6000_dvb *dvb = dev->dvb;
 264
 265        mutex_init(&dvb->mutex);
 266
 267        dvb->streams = 0;
 268
 269        /* attach the frontend */
 270        ret = tm6000_dvb_attach_frontend(dev);
 271        if (ret < 0) {
 272                printk(KERN_ERR "tm6000: couldn't attach the frontend!\n");
 273                goto err;
 274        }
 275
 276        ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T",
 277                                        THIS_MODULE, &dev->udev->dev, adapter_nr);
 278        dvb->adapter.priv = dev;
 279
 280        if (dvb->frontend) {
 281                switch (dev->tuner_type) {
 282                case TUNER_XC2028: {
 283                        struct xc2028_config cfg = {
 284                                .i2c_adap = &dev->i2c_adap,
 285                                .i2c_addr = dev->tuner_addr,
 286                        };
 287
 288                        dvb->frontend->callback = tm6000_tuner_callback;
 289                        ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
 290                        if (ret < 0) {
 291                                printk(KERN_ERR
 292                                        "tm6000: couldn't register frontend\n");
 293                                goto adapter_err;
 294                        }
 295
 296                        if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) {
 297                                printk(KERN_ERR "tm6000: couldn't register "
 298                                                "frontend (xc3028)\n");
 299                                ret = -EINVAL;
 300                                goto frontend_err;
 301                        }
 302                        printk(KERN_INFO "tm6000: XC2028/3028 asked to be "
 303                                         "attached to frontend!\n");
 304                        break;
 305                        }
 306                case TUNER_XC5000: {
 307                        struct xc5000_config cfg = {
 308                                .i2c_address = dev->tuner_addr,
 309                        };
 310
 311                        dvb->frontend->callback = tm6000_xc5000_callback;
 312                        ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
 313                        if (ret < 0) {
 314                                printk(KERN_ERR
 315                                        "tm6000: couldn't register frontend\n");
 316                                goto adapter_err;
 317                        }
 318
 319                        if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) {
 320                                printk(KERN_ERR "tm6000: couldn't register "
 321                                                "frontend (xc5000)\n");
 322                                ret = -EINVAL;
 323                                goto frontend_err;
 324                        }
 325                        printk(KERN_INFO "tm6000: XC5000 asked to be "
 326                                         "attached to frontend!\n");
 327                        break;
 328                        }
 329                }
 330        } else
 331                printk(KERN_ERR "tm6000: no frontend found\n");
 332
 333        dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
 334                                                            | DMX_MEMORY_BASED_FILTERING;
 335        dvb->demux.priv = dev;
 336        dvb->demux.filternum = 8;
 337        dvb->demux.feednum = 8;
 338        dvb->demux.start_feed = tm6000_start_feed;
 339        dvb->demux.stop_feed = tm6000_stop_feed;
 340        dvb->demux.write_to_decoder = NULL;
 341        ret = dvb_dmx_init(&dvb->demux);
 342        if (ret < 0) {
 343                printk(KERN_ERR "tm6000: dvb_dmx_init failed (errno = %d)\n", ret);
 344                goto frontend_err;
 345        }
 346
 347        dvb->dmxdev.filternum = dev->dvb->demux.filternum;
 348        dvb->dmxdev.demux = &dev->dvb->demux.dmx;
 349        dvb->dmxdev.capabilities = 0;
 350
 351        ret =  dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
 352        if (ret < 0) {
 353                printk(KERN_ERR "tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret);
 354                goto dvb_dmx_err;
 355        }
 356
 357        return 0;
 358
 359dvb_dmx_err:
 360        dvb_dmx_release(&dvb->demux);
 361frontend_err:
 362        if (dvb->frontend) {
 363                dvb_unregister_frontend(dvb->frontend);
 364                dvb_frontend_detach(dvb->frontend);
 365        }
 366adapter_err:
 367        dvb_unregister_adapter(&dvb->adapter);
 368err:
 369        return ret;
 370}
 371
 372static void unregister_dvb(struct tm6000_core *dev)
 373{
 374        struct tm6000_dvb *dvb = dev->dvb;
 375
 376        if (dvb->bulk_urb != NULL) {
 377                struct urb *bulk_urb = dvb->bulk_urb;
 378
 379                kfree(bulk_urb->transfer_buffer);
 380                bulk_urb->transfer_buffer = NULL;
 381                usb_unlink_urb(bulk_urb);
 382                usb_free_urb(bulk_urb);
 383        }
 384
 385/*      mutex_lock(&tm6000_driver.open_close_mutex); */
 386        if (dvb->frontend) {
 387                dvb_unregister_frontend(dvb->frontend);
 388                dvb_frontend_detach(dvb->frontend);
 389        }
 390
 391        dvb_dmxdev_release(&dvb->dmxdev);
 392        dvb_dmx_release(&dvb->demux);
 393        dvb_unregister_adapter(&dvb->adapter);
 394        mutex_destroy(&dvb->mutex);
 395/*      mutex_unlock(&tm6000_driver.open_close_mutex); */
 396}
 397
 398static int dvb_init(struct tm6000_core *dev)
 399{
 400        struct tm6000_dvb *dvb;
 401        int rc;
 402
 403        if (!dev)
 404                return 0;
 405
 406        if (!dev->caps.has_dvb)
 407                return 0;
 408
 409        if (dev->udev->speed == USB_SPEED_FULL) {
 410                printk(KERN_INFO "This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)\n");
 411                return 0;
 412        }
 413
 414        dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL);
 415        if (!dvb) {
 416                printk(KERN_INFO "Cannot allocate memory\n");
 417                return -ENOMEM;
 418        }
 419
 420        dev->dvb = dvb;
 421
 422        rc = register_dvb(dev);
 423        if (rc < 0) {
 424                kfree(dvb);
 425                dev->dvb = NULL;
 426                return 0;
 427        }
 428
 429        return 0;
 430}
 431
 432static int dvb_fini(struct tm6000_core *dev)
 433{
 434        if (!dev)
 435                return 0;
 436
 437        if (!dev->caps.has_dvb)
 438                return 0;
 439
 440        if (dev->dvb) {
 441                unregister_dvb(dev);
 442                kfree(dev->dvb);
 443                dev->dvb = NULL;
 444        }
 445
 446        return 0;
 447}
 448
 449static struct tm6000_ops dvb_ops = {
 450        .type   = TM6000_DVB,
 451        .name   = "TM6000 dvb Extension",
 452        .init   = dvb_init,
 453        .fini   = dvb_fini,
 454};
 455
 456static int __init tm6000_dvb_register(void)
 457{
 458        return tm6000_register_extension(&dvb_ops);
 459}
 460
 461static void __exit tm6000_dvb_unregister(void)
 462{
 463        tm6000_unregister_extension(&dvb_ops);
 464}
 465
 466module_init(tm6000_dvb_register);
 467module_exit(tm6000_dvb_unregister);
 468