root/drivers/media/pci/cx88/cx88-mpeg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. request_module_async
  2. request_modules
  3. flush_request_modules
  4. cx8802_start_dma
  5. cx8802_stop_dma
  6. cx8802_restart_queue
  7. cx8802_buf_prepare
  8. cx8802_buf_queue
  9. do_cancel_buffers
  10. cx8802_cancel_buffers
  11. cx8802_mpeg_irq
  12. cx8802_irq
  13. cx8802_init_common
  14. cx8802_fini_common
  15. cx8802_suspend_common
  16. cx8802_resume_common
  17. cx8802_get_driver
  18. cx8802_request_acquire
  19. cx8802_request_release
  20. cx8802_check_driver
  21. cx8802_register_driver
  22. cx8802_unregister_driver
  23. cx8802_probe
  24. cx8802_remove

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

/* [<][>][^][v][top][bottom][index][help] */