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