linux/drivers/media/video/cx88/cx88-mpeg.c
<<
>>
Prefs
   1/*
   2 *
   3 *  Support for the mpeg transport stream transfers
   4 *  PCI function #2 of the cx2388x.
   5 *
   6 *    (c) 2004 Jelle Foks <jelle@foks.us>
   7 *    (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
   8 *    (c) 2004 Gerd Knorr <kraxel@bytesex.org>
   9 *
  10 *  This program is free software; you can redistribute it and/or modify
  11 *  it under the terms of the GNU General Public License as published by
  12 *  the Free Software Foundation; either version 2 of the License, or
  13 *  (at your option) any later version.
  14 *
  15 *  This program is distributed in the hope that it will be useful,
  16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 *  GNU General Public License for more details.
  19 *
  20 *  You should have received a copy of the GNU General Public License
  21 *  along with this program; if not, write to the Free Software
  22 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23 */
  24
  25#include <linux/module.h>
  26#include <linux/slab.h>
  27#include <linux/init.h>
  28#include <linux/device.h>
  29#include <linux/dma-mapping.h>
  30#include <linux/interrupt.h>
  31#include <asm/delay.h>
  32
  33#include "cx88.h"
  34
  35/* ------------------------------------------------------------------ */
  36
  37MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards");
  38MODULE_AUTHOR("Jelle Foks <jelle@foks.us>");
  39MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
  40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
  41MODULE_LICENSE("GPL");
  42
  43static unsigned int debug;
  44module_param(debug,int,0644);
  45MODULE_PARM_DESC(debug,"enable debug messages [mpeg]");
  46
  47#define dprintk(level,fmt, arg...)      if (debug >= level) \
  48        printk(KERN_DEBUG "%s/2-mpeg: " fmt, dev->core->name, ## arg)
  49
  50#define mpeg_dbg(level,fmt, arg...)     if (debug >= level) \
  51        printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg)
  52
  53#if defined(CONFIG_MODULES) && defined(MODULE)
  54static void request_module_async(struct work_struct *work)
  55{
  56        struct cx8802_dev *dev=container_of(work, struct cx8802_dev, request_module_wk);
  57
  58        if (dev->core->board.mpeg & CX88_MPEG_DVB)
  59                request_module("cx88-dvb");
  60        if (dev->core->board.mpeg & CX88_MPEG_BLACKBIRD)
  61                request_module("cx88-blackbird");
  62}
  63
  64static void request_modules(struct cx8802_dev *dev)
  65{
  66        INIT_WORK(&dev->request_module_wk, request_module_async);
  67        schedule_work(&dev->request_module_wk);
  68}
  69
  70static void flush_request_modules(struct cx8802_dev *dev)
  71{
  72        flush_work_sync(&dev->request_module_wk);
  73}
  74#else
  75#define request_modules(dev)
  76#define flush_request_modules(dev)
  77#endif /* CONFIG_MODULES */
  78
  79
  80static LIST_HEAD(cx8802_devlist);
  81/* ------------------------------------------------------------------ */
  82
  83static int cx8802_start_dma(struct cx8802_dev    *dev,
  84                            struct cx88_dmaqueue *q,
  85                            struct cx88_buffer   *buf)
  86{
  87        struct cx88_core *core = dev->core;
  88
  89        dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n",
  90                buf->vb.width, buf->vb.height, buf->vb.field);
  91
  92        /* setup fifo + format */
  93        cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
  94                                dev->ts_packet_size, buf->risc.dma);
  95
  96        /* write TS length to chip */
  97        cx_write(MO_TS_LNGTH, buf->vb.width);
  98
  99        /* FIXME: this needs a review.
 100         * also: move to cx88-blackbird + cx88-dvb source files? */
 101
 102        dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id);
 103
 104        if ( (core->active_type_id == CX88_MPEG_DVB) &&
 105                (core->board.mpeg & CX88_MPEG_DVB) ) {
 106
 107                dprintk( 1, "cx8802_start_dma doing .dvb\n");
 108                /* negedge driven & software reset */
 109                cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl);
 110                udelay(100);
 111                cx_write(MO_PINMUX_IO, 0x00);
 112                cx_write(TS_HW_SOP_CNTRL, 0x47<<16|188<<4|0x01);
 113                switch (core->boardnr) {
 114                case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
 115                case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
 116                case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
 117                case CX88_BOARD_PCHDTV_HD5500:
 118                        cx_write(TS_SOP_STAT, 1<<13);
 119                        break;
 120                case CX88_BOARD_SAMSUNG_SMT_7020:
 121                        cx_write(TS_SOP_STAT, 0x00);
 122                        break;
 123                case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
 124                case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
 125                        cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
 126                        udelay(100);
 127                        break;
 128                case CX88_BOARD_HAUPPAUGE_HVR1300:
 129                        /* Enable MPEG parallel IO and video signal pins */
 130                        cx_write(MO_PINMUX_IO, 0x88);
 131                        cx_write(TS_SOP_STAT, 0);
 132                        cx_write(TS_VALERR_CNTRL, 0);
 133                        break;
 134                case CX88_BOARD_PINNACLE_PCTV_HD_800i:
 135                        /* Enable MPEG parallel IO and video signal pins */
 136                        cx_write(MO_PINMUX_IO, 0x88);
 137                        cx_write(TS_HW_SOP_CNTRL, (0x47 << 16) | (188 << 4));
 138                        dev->ts_gen_cntrl = 5;
 139                        cx_write(TS_SOP_STAT, 0);
 140                        cx_write(TS_VALERR_CNTRL, 0);
 141                        udelay(100);
 142                        break;
 143                default:
 144                        cx_write(TS_SOP_STAT, 0x00);
 145                        break;
 146                }
 147                cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
 148                udelay(100);
 149        } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) &&
 150                (core->board.mpeg & CX88_MPEG_BLACKBIRD) ) {
 151                dprintk( 1, "cx8802_start_dma doing .blackbird\n");
 152                cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
 153
 154                cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
 155                udelay(100);
 156
 157                cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */
 158                cx_write(TS_VALERR_CNTRL, 0x2000);
 159
 160                cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
 161                udelay(100);
 162        } else {
 163                printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __func__,
 164                        core->board.mpeg );
 165                return -EINVAL;
 166        }
 167
 168        /* reset counter */
 169        cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET);
 170        q->count = 1;
 171
 172        /* enable irqs */
 173        dprintk( 1, "setting the interrupt mask\n" );
 174        cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_TSINT);
 175        cx_set(MO_TS_INTMSK,  0x1f0011);
 176
 177        /* start dma */
 178        cx_set(MO_DEV_CNTRL2, (1<<5));
 179        cx_set(MO_TS_DMACNTRL, 0x11);
 180        return 0;
 181}
 182
 183static int cx8802_stop_dma(struct cx8802_dev *dev)
 184{
 185        struct cx88_core *core = dev->core;
 186        dprintk( 1, "cx8802_stop_dma\n" );
 187
 188        /* stop dma */
 189        cx_clear(MO_TS_DMACNTRL, 0x11);
 190
 191        /* disable irqs */
 192        cx_clear(MO_PCI_INTMSK, PCI_INT_TSINT);
 193        cx_clear(MO_TS_INTMSK, 0x1f0011);
 194
 195        /* Reset the controller */
 196        cx_write(TS_GEN_CNTRL, 0xcd);
 197        return 0;
 198}
 199
 200static int cx8802_restart_queue(struct cx8802_dev    *dev,
 201                                struct cx88_dmaqueue *q)
 202{
 203        struct cx88_buffer *buf;
 204
 205        dprintk( 1, "cx8802_restart_queue\n" );
 206        if (list_empty(&q->active))
 207        {
 208                struct cx88_buffer *prev;
 209                prev = NULL;
 210
 211                dprintk(1, "cx8802_restart_queue: queue is empty\n" );
 212
 213                for (;;) {
 214                        if (list_empty(&q->queued))
 215                                return 0;
 216                        buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
 217                        if (NULL == prev) {
 218                                list_del(&buf->vb.queue);
 219                                list_add_tail(&buf->vb.queue,&q->active);
 220                                cx8802_start_dma(dev, q, buf);
 221                                buf->vb.state = VIDEOBUF_ACTIVE;
 222                                buf->count    = q->count++;
 223                                mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
 224                                dprintk(1,"[%p/%d] restart_queue - first active\n",
 225                                        buf,buf->vb.i);
 226
 227                        } else if (prev->vb.width  == buf->vb.width  &&
 228                                   prev->vb.height == buf->vb.height &&
 229                                   prev->fmt       == buf->fmt) {
 230                                list_del(&buf->vb.queue);
 231                                list_add_tail(&buf->vb.queue,&q->active);
 232                                buf->vb.state = VIDEOBUF_ACTIVE;
 233                                buf->count    = q->count++;
 234                                prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 235                                dprintk(1,"[%p/%d] restart_queue - move to active\n",
 236                                        buf,buf->vb.i);
 237                        } else {
 238                                return 0;
 239                        }
 240                        prev = buf;
 241                }
 242                return 0;
 243        }
 244
 245        buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
 246        dprintk(2,"restart_queue [%p/%d]: restart dma\n",
 247                buf, buf->vb.i);
 248        cx8802_start_dma(dev, q, buf);
 249        list_for_each_entry(buf, &q->active, vb.queue)
 250                buf->count = q->count++;
 251        mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
 252        return 0;
 253}
 254
 255/* ------------------------------------------------------------------ */
 256
 257int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
 258                        struct cx88_buffer *buf, enum v4l2_field field)
 259{
 260        int size = dev->ts_packet_size * dev->ts_packet_count;
 261        struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 262        int rc;
 263
 264        dprintk(1, "%s: %p\n", __func__, buf);
 265        if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
 266                return -EINVAL;
 267
 268        if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
 269                buf->vb.width  = dev->ts_packet_size;
 270                buf->vb.height = dev->ts_packet_count;
 271                buf->vb.size   = size;
 272                buf->vb.field  = field /*V4L2_FIELD_TOP*/;
 273
 274                if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
 275                        goto fail;
 276                cx88_risc_databuffer(dev->pci, &buf->risc,
 277                                     dma->sglist,
 278                                     buf->vb.width, buf->vb.height, 0);
 279        }
 280        buf->vb.state = VIDEOBUF_PREPARED;
 281        return 0;
 282
 283 fail:
 284        cx88_free_buffer(q,buf);
 285        return rc;
 286}
 287
 288void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
 289{
 290        struct cx88_buffer    *prev;
 291        struct cx88_dmaqueue  *cx88q = &dev->mpegq;
 292
 293        dprintk( 1, "cx8802_buf_queue\n" );
 294        /* add jump to stopper */
 295        buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
 296        buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
 297
 298        if (list_empty(&cx88q->active)) {
 299                dprintk( 1, "queue is empty - first active\n" );
 300                list_add_tail(&buf->vb.queue,&cx88q->active);
 301                cx8802_start_dma(dev, cx88q, buf);
 302                buf->vb.state = VIDEOBUF_ACTIVE;
 303                buf->count    = cx88q->count++;
 304                mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
 305                dprintk(1,"[%p/%d] %s - first active\n",
 306                        buf, buf->vb.i, __func__);
 307
 308        } else {
 309                dprintk( 1, "queue is not empty - append to active\n" );
 310                prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue);
 311                list_add_tail(&buf->vb.queue,&cx88q->active);
 312                buf->vb.state = VIDEOBUF_ACTIVE;
 313                buf->count    = cx88q->count++;
 314                prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 315                dprintk( 1, "[%p/%d] %s - append to active\n",
 316                        buf, buf->vb.i, __func__);
 317        }
 318}
 319
 320/* ----------------------------------------------------------- */
 321
 322static void do_cancel_buffers(struct cx8802_dev *dev, const char *reason, int restart)
 323{
 324        struct cx88_dmaqueue *q = &dev->mpegq;
 325        struct cx88_buffer *buf;
 326        unsigned long flags;
 327
 328        spin_lock_irqsave(&dev->slock,flags);
 329        while (!list_empty(&q->active)) {
 330                buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
 331                list_del(&buf->vb.queue);
 332                buf->vb.state = VIDEOBUF_ERROR;
 333                wake_up(&buf->vb.done);
 334                dprintk(1,"[%p/%d] %s - dma=0x%08lx\n",
 335                        buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
 336        }
 337        if (restart)
 338        {
 339                dprintk(1, "restarting queue\n" );
 340                cx8802_restart_queue(dev,q);
 341        }
 342        spin_unlock_irqrestore(&dev->slock,flags);
 343}
 344
 345void cx8802_cancel_buffers(struct cx8802_dev *dev)
 346{
 347        struct cx88_dmaqueue *q = &dev->mpegq;
 348
 349        dprintk( 1, "cx8802_cancel_buffers" );
 350        del_timer_sync(&q->timeout);
 351        cx8802_stop_dma(dev);
 352        do_cancel_buffers(dev,"cancel",0);
 353}
 354
 355static void cx8802_timeout(unsigned long data)
 356{
 357        struct cx8802_dev *dev = (struct cx8802_dev*)data;
 358
 359        dprintk(1, "%s\n",__func__);
 360
 361        if (debug)
 362                cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
 363        cx8802_stop_dma(dev);
 364        do_cancel_buffers(dev,"timeout",1);
 365}
 366
 367static const char * cx88_mpeg_irqs[32] = {
 368        "ts_risci1", NULL, NULL, NULL,
 369        "ts_risci2", NULL, NULL, NULL,
 370        "ts_oflow",  NULL, NULL, NULL,
 371        "ts_sync",   NULL, NULL, NULL,
 372        "opc_err", "par_err", "rip_err", "pci_abort",
 373        "ts_err?",
 374};
 375
 376static void cx8802_mpeg_irq(struct cx8802_dev *dev)
 377{
 378        struct cx88_core *core = dev->core;
 379        u32 status, mask, count;
 380
 381        dprintk( 1, "cx8802_mpeg_irq\n" );
 382        status = cx_read(MO_TS_INTSTAT);
 383        mask   = cx_read(MO_TS_INTMSK);
 384        if (0 == (status & mask))
 385                return;
 386
 387        cx_write(MO_TS_INTSTAT, status);
 388
 389        if (debug || (status & mask & ~0xff))
 390                cx88_print_irqbits(core->name, "irq mpeg ",
 391                                   cx88_mpeg_irqs, ARRAY_SIZE(cx88_mpeg_irqs),
 392                                   status, mask);
 393
 394        /* risc op code error */
 395        if (status & (1 << 16)) {
 396                printk(KERN_WARNING "%s: mpeg risc op code error\n",core->name);
 397                cx_clear(MO_TS_DMACNTRL, 0x11);
 398                cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
 399        }
 400
 401        /* risc1 y */
 402        if (status & 0x01) {
 403                dprintk( 1, "wake up\n" );
 404                spin_lock(&dev->slock);
 405                count = cx_read(MO_TS_GPCNT);
 406                cx88_wakeup(dev->core, &dev->mpegq, count);
 407                spin_unlock(&dev->slock);
 408        }
 409
 410        /* risc2 y */
 411        if (status & 0x10) {
 412                spin_lock(&dev->slock);
 413                cx8802_restart_queue(dev,&dev->mpegq);
 414                spin_unlock(&dev->slock);
 415        }
 416
 417        /* other general errors */
 418        if (status & 0x1f0100) {
 419                dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
 420                spin_lock(&dev->slock);
 421                cx8802_stop_dma(dev);
 422                cx8802_restart_queue(dev,&dev->mpegq);
 423                spin_unlock(&dev->slock);
 424        }
 425}
 426
 427#define MAX_IRQ_LOOP 10
 428
 429static irqreturn_t cx8802_irq(int irq, void *dev_id)
 430{
 431        struct cx8802_dev *dev = dev_id;
 432        struct cx88_core *core = dev->core;
 433        u32 status;
 434        int loop, handled = 0;
 435
 436        for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
 437                status = cx_read(MO_PCI_INTSTAT) &
 438                        (core->pci_irqmask | PCI_INT_TSINT);
 439                if (0 == status)
 440                        goto out;
 441                dprintk( 1, "cx8802_irq\n" );
 442                dprintk( 1, "    loop: %d/%d\n", loop, MAX_IRQ_LOOP );
 443                dprintk( 1, "    status: %d\n", status );
 444                handled = 1;
 445                cx_write(MO_PCI_INTSTAT, status);
 446
 447                if (status & core->pci_irqmask)
 448                        cx88_core_irq(core,status);
 449                if (status & PCI_INT_TSINT)
 450                        cx8802_mpeg_irq(dev);
 451        };
 452        if (MAX_IRQ_LOOP == loop) {
 453                dprintk( 0, "clearing mask\n" );
 454                printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
 455                       core->name);
 456                cx_write(MO_PCI_INTMSK,0);
 457        }
 458
 459 out:
 460        return IRQ_RETVAL(handled);
 461}
 462
 463static int cx8802_init_common(struct cx8802_dev *dev)
 464{
 465        struct cx88_core *core = dev->core;
 466        int err;
 467
 468        /* pci init */
 469        if (pci_enable_device(dev->pci))
 470                return -EIO;
 471        pci_set_master(dev->pci);
 472        if (!pci_dma_supported(dev->pci,DMA_BIT_MASK(32))) {
 473                printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
 474                return -EIO;
 475        }
 476
 477        pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
 478        pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER,  &dev->pci_lat);
 479        printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
 480               "latency: %d, mmio: 0x%llx\n", dev->core->name,
 481               pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
 482               dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0));
 483
 484        /* initialize driver struct */
 485        spin_lock_init(&dev->slock);
 486
 487        /* init dma queue */
 488        INIT_LIST_HEAD(&dev->mpegq.active);
 489        INIT_LIST_HEAD(&dev->mpegq.queued);
 490        dev->mpegq.timeout.function = cx8802_timeout;
 491        dev->mpegq.timeout.data     = (unsigned long)dev;
 492        init_timer(&dev->mpegq.timeout);
 493        cx88_risc_stopper(dev->pci,&dev->mpegq.stopper,
 494                          MO_TS_DMACNTRL,0x11,0x00);
 495
 496        /* get irq */
 497        err = request_irq(dev->pci->irq, cx8802_irq,
 498                          IRQF_SHARED | IRQF_DISABLED, dev->core->name, dev);
 499        if (err < 0) {
 500                printk(KERN_ERR "%s: can't get IRQ %d\n",
 501                       dev->core->name, dev->pci->irq);
 502                return err;
 503        }
 504        cx_set(MO_PCI_INTMSK, core->pci_irqmask);
 505
 506        /* everything worked */
 507        pci_set_drvdata(dev->pci,dev);
 508        return 0;
 509}
 510
 511static void cx8802_fini_common(struct cx8802_dev *dev)
 512{
 513        dprintk( 2, "cx8802_fini_common\n" );
 514        cx8802_stop_dma(dev);
 515        pci_disable_device(dev->pci);
 516
 517        /* unregister stuff */
 518        free_irq(dev->pci->irq, dev);
 519        pci_set_drvdata(dev->pci, NULL);
 520
 521        /* free memory */
 522        btcx_riscmem_free(dev->pci,&dev->mpegq.stopper);
 523}
 524
 525/* ----------------------------------------------------------- */
 526
 527static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
 528{
 529        struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
 530        struct cx88_core *core = dev->core;
 531
 532        /* stop mpeg dma */
 533        spin_lock(&dev->slock);
 534        if (!list_empty(&dev->mpegq.active)) {
 535                dprintk( 2, "suspend\n" );
 536                printk("%s: suspend mpeg\n", core->name);
 537                cx8802_stop_dma(dev);
 538                del_timer(&dev->mpegq.timeout);
 539        }
 540        spin_unlock(&dev->slock);
 541
 542        /* FIXME -- shutdown device */
 543        cx88_shutdown(dev->core);
 544
 545        pci_save_state(pci_dev);
 546        if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
 547                pci_disable_device(pci_dev);
 548                dev->state.disabled = 1;
 549        }
 550        return 0;
 551}
 552
 553static int cx8802_resume_common(struct pci_dev *pci_dev)
 554{
 555        struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
 556        struct cx88_core *core = dev->core;
 557        int err;
 558
 559        if (dev->state.disabled) {
 560                err=pci_enable_device(pci_dev);
 561                if (err) {
 562                        printk(KERN_ERR "%s: can't enable device\n",
 563                                               dev->core->name);
 564                        return err;
 565                }
 566                dev->state.disabled = 0;
 567        }
 568        err=pci_set_power_state(pci_dev, PCI_D0);
 569        if (err) {
 570                printk(KERN_ERR "%s: can't enable device\n",
 571                                               dev->core->name);
 572                pci_disable_device(pci_dev);
 573                dev->state.disabled = 1;
 574
 575                return err;
 576        }
 577        pci_restore_state(pci_dev);
 578
 579        /* FIXME: re-initialize hardware */
 580        cx88_reset(dev->core);
 581
 582        /* restart video+vbi capture */
 583        spin_lock(&dev->slock);
 584        if (!list_empty(&dev->mpegq.active)) {
 585                printk("%s: resume mpeg\n", core->name);
 586                cx8802_restart_queue(dev,&dev->mpegq);
 587        }
 588        spin_unlock(&dev->slock);
 589
 590        return 0;
 591}
 592
 593struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
 594{
 595        struct cx8802_driver *d;
 596
 597        list_for_each_entry(d, &dev->drvlist, drvlist)
 598                if (d->type_id == btype)
 599                        return d;
 600
 601        return NULL;
 602}
 603
 604/* Driver asked for hardware access. */
 605static int cx8802_request_acquire(struct cx8802_driver *drv)
 606{
 607        struct cx88_core *core = drv->core;
 608        unsigned int    i;
 609
 610        /* Fail a request for hardware if the device is busy. */
 611        if (core->active_type_id != CX88_BOARD_NONE &&
 612            core->active_type_id != drv->type_id)
 613                return -EBUSY;
 614
 615        core->input = 0;
 616        for (i = 0;
 617             i < (sizeof(core->board.input) / sizeof(struct cx88_input));
 618             i++) {
 619                if (core->board.input[i].type == CX88_VMUX_DVB) {
 620                        core->input = i;
 621                        break;
 622                }
 623        }
 624
 625        if (drv->advise_acquire)
 626        {
 627                mutex_lock(&drv->core->lock);
 628                core->active_ref++;
 629                if (core->active_type_id == CX88_BOARD_NONE) {
 630                        core->active_type_id = drv->type_id;
 631                        drv->advise_acquire(drv);
 632                }
 633                mutex_unlock(&drv->core->lock);
 634
 635                mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
 636        }
 637
 638        return 0;
 639}
 640
 641/* Driver asked to release hardware. */
 642static int cx8802_request_release(struct cx8802_driver *drv)
 643{
 644        struct cx88_core *core = drv->core;
 645
 646        mutex_lock(&drv->core->lock);
 647        if (drv->advise_release && --core->active_ref == 0)
 648        {
 649                drv->advise_release(drv);
 650                core->active_type_id = CX88_BOARD_NONE;
 651                mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
 652        }
 653        mutex_unlock(&drv->core->lock);
 654
 655        return 0;
 656}
 657
 658static int cx8802_check_driver(struct cx8802_driver *drv)
 659{
 660        if (drv == NULL)
 661                return -ENODEV;
 662
 663        if ((drv->type_id != CX88_MPEG_DVB) &&
 664                (drv->type_id != CX88_MPEG_BLACKBIRD))
 665                return -EINVAL;
 666
 667        if ((drv->hw_access != CX8802_DRVCTL_SHARED) &&
 668                (drv->hw_access != CX8802_DRVCTL_EXCLUSIVE))
 669                return -EINVAL;
 670
 671        if ((drv->probe == NULL) ||
 672                (drv->remove == NULL) ||
 673                (drv->advise_acquire == NULL) ||
 674                (drv->advise_release == NULL))
 675                return -EINVAL;
 676
 677        return 0;
 678}
 679
 680int cx8802_register_driver(struct cx8802_driver *drv)
 681{
 682        struct cx8802_dev *dev;
 683        struct cx8802_driver *driver;
 684        int err, i = 0;
 685
 686        printk(KERN_INFO
 687               "cx88/2: registering cx8802 driver, type: %s access: %s\n",
 688               drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
 689               drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
 690
 691        if ((err = cx8802_check_driver(drv)) != 0) {
 692                printk(KERN_ERR "cx88/2: cx8802_driver is invalid\n");
 693                return err;
 694        }
 695
 696        list_for_each_entry(dev, &cx8802_devlist, devlist) {
 697                printk(KERN_INFO
 698                       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
 699                       dev->core->name, dev->pci->subsystem_vendor,
 700                       dev->pci->subsystem_device, dev->core->board.name,
 701                       dev->core->boardnr);
 702
 703                /* Bring up a new struct for each driver instance */
 704                driver = kzalloc(sizeof(*drv),GFP_KERNEL);
 705                if (driver == NULL)
 706                        return -ENOMEM;
 707
 708                /* Snapshot of the driver registration data */
 709                drv->core = dev->core;
 710                drv->suspend = cx8802_suspend_common;
 711                drv->resume = cx8802_resume_common;
 712                drv->request_acquire = cx8802_request_acquire;
 713                drv->request_release = cx8802_request_release;
 714                memcpy(driver, drv, sizeof(*driver));
 715
 716                err = drv->probe(driver);
 717                if (err == 0) {
 718                        i++;
 719                        mutex_lock(&drv->core->lock);
 720                        list_add_tail(&driver->drvlist, &dev->drvlist);
 721                        mutex_unlock(&drv->core->lock);
 722                } else {
 723                        printk(KERN_ERR
 724                               "%s/2: cx8802 probe failed, err = %d\n",
 725                               dev->core->name, err);
 726                }
 727
 728        }
 729
 730        return i ? 0 : -ENODEV;
 731}
 732
 733int cx8802_unregister_driver(struct cx8802_driver *drv)
 734{
 735        struct cx8802_dev *dev;
 736        struct cx8802_driver *d, *dtmp;
 737        int err = 0;
 738
 739        printk(KERN_INFO
 740               "cx88/2: unregistering cx8802 driver, type: %s access: %s\n",
 741               drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
 742               drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
 743
 744        list_for_each_entry(dev, &cx8802_devlist, devlist) {
 745                printk(KERN_INFO
 746                       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
 747                       dev->core->name, dev->pci->subsystem_vendor,
 748                       dev->pci->subsystem_device, dev->core->board.name,
 749                       dev->core->boardnr);
 750
 751                list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
 752                        /* only unregister the correct driver type */
 753                        if (d->type_id != drv->type_id)
 754                                continue;
 755
 756                        err = d->remove(d);
 757                        if (err == 0) {
 758                                mutex_lock(&drv->core->lock);
 759                                list_del(&d->drvlist);
 760                                mutex_unlock(&drv->core->lock);
 761                                kfree(d);
 762                        } else
 763                                printk(KERN_ERR "%s/2: cx8802 driver remove "
 764                                       "failed (%d)\n", dev->core->name, err);
 765                }
 766
 767        }
 768
 769        return err;
 770}
 771
 772/* ----------------------------------------------------------- */
 773static int __devinit cx8802_probe(struct pci_dev *pci_dev,
 774                               const struct pci_device_id *pci_id)
 775{
 776        struct cx8802_dev *dev;
 777        struct cx88_core  *core;
 778        int err;
 779
 780        /* general setup */
 781        core = cx88_core_get(pci_dev);
 782        if (NULL == core)
 783                return -EINVAL;
 784
 785        printk("%s/2: cx2388x 8802 Driver Manager\n", core->name);
 786
 787        err = -ENODEV;
 788        if (!core->board.mpeg)
 789                goto fail_core;
 790
 791        err = -ENOMEM;
 792        dev = kzalloc(sizeof(*dev),GFP_KERNEL);
 793        if (NULL == dev)
 794                goto fail_core;
 795        dev->pci = pci_dev;
 796        dev->core = core;
 797
 798        /* Maintain a reference so cx88-video can query the 8802 device. */
 799        core->dvbdev = dev;
 800
 801        err = cx8802_init_common(dev);
 802        if (err != 0)
 803                goto fail_free;
 804
 805        INIT_LIST_HEAD(&dev->drvlist);
 806        list_add_tail(&dev->devlist,&cx8802_devlist);
 807
 808        /* now autoload cx88-dvb or cx88-blackbird */
 809        request_modules(dev);
 810        return 0;
 811
 812 fail_free:
 813        kfree(dev);
 814 fail_core:
 815        core->dvbdev = NULL;
 816        cx88_core_put(core,pci_dev);
 817        return err;
 818}
 819
 820static void __devexit cx8802_remove(struct pci_dev *pci_dev)
 821{
 822        struct cx8802_dev *dev;
 823
 824        dev = pci_get_drvdata(pci_dev);
 825
 826        dprintk( 1, "%s\n", __func__);
 827
 828        flush_request_modules(dev);
 829
 830        if (!list_empty(&dev->drvlist)) {
 831                struct cx8802_driver *drv, *tmp;
 832                int err;
 833
 834                printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver "
 835                       "while cx8802 sub-drivers still loaded?!\n",
 836                       dev->core->name);
 837
 838                list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
 839                        err = drv->remove(drv);
 840                        if (err == 0) {
 841                                mutex_lock(&drv->core->lock);
 842                                list_del(&drv->drvlist);
 843                                mutex_unlock(&drv->core->lock);
 844                        } else
 845                                printk(KERN_ERR "%s/2: cx8802 driver remove "
 846                                       "failed (%d)\n", dev->core->name, err);
 847                        kfree(drv);
 848                }
 849        }
 850
 851        /* Destroy any 8802 reference. */
 852        dev->core->dvbdev = NULL;
 853
 854        /* common */
 855        cx8802_fini_common(dev);
 856        cx88_core_put(dev->core,dev->pci);
 857        kfree(dev);
 858}
 859
 860static const struct pci_device_id cx8802_pci_tbl[] = {
 861        {
 862                .vendor       = 0x14f1,
 863                .device       = 0x8802,
 864                .subvendor    = PCI_ANY_ID,
 865                .subdevice    = PCI_ANY_ID,
 866        },{
 867                /* --- end of list --- */
 868        }
 869};
 870MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
 871
 872static struct pci_driver cx8802_pci_driver = {
 873        .name     = "cx88-mpeg driver manager",
 874        .id_table = cx8802_pci_tbl,
 875        .probe    = cx8802_probe,
 876        .remove   = __devexit_p(cx8802_remove),
 877};
 878
 879static int __init cx8802_init(void)
 880{
 881        printk(KERN_INFO "cx88/2: cx2388x MPEG-TS Driver Manager version %d.%d.%d loaded\n",
 882               (CX88_VERSION_CODE >> 16) & 0xff,
 883               (CX88_VERSION_CODE >>  8) & 0xff,
 884               CX88_VERSION_CODE & 0xff);
 885#ifdef SNAPSHOT
 886        printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
 887               SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
 888#endif
 889        return pci_register_driver(&cx8802_pci_driver);
 890}
 891
 892static void __exit cx8802_fini(void)
 893{
 894        pci_unregister_driver(&cx8802_pci_driver);
 895}
 896
 897module_init(cx8802_init);
 898module_exit(cx8802_fini);
 899EXPORT_SYMBOL(cx8802_buf_prepare);
 900EXPORT_SYMBOL(cx8802_buf_queue);
 901EXPORT_SYMBOL(cx8802_cancel_buffers);
 902
 903EXPORT_SYMBOL(cx8802_register_driver);
 904EXPORT_SYMBOL(cx8802_unregister_driver);
 905EXPORT_SYMBOL(cx8802_get_driver);
 906/* ----------------------------------------------------------- */
 907/*
 908 * Local variables:
 909 * c-basic-offset: 8
 910 * End:
 911 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
 912 */
 913