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

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

DEFINITIONS

This source file includes following definitions.
  1. cx88_risc_field
  2. cx88_risc_buffer
  3. cx88_risc_databuffer
  4. cx88_sram_channel_setup
  5. cx88_risc_decode
  6. cx88_sram_channel_dump
  7. cx88_print_irqbits
  8. cx88_core_irq
  9. cx88_wakeup
  10. cx88_shutdown
  11. cx88_reset
  12. norm_swidth
  13. norm_hdelay
  14. norm_vdelay
  15. norm_fsc8
  16. norm_htotal
  17. norm_vbipack
  18. cx88_set_scale
  19. set_pll
  20. cx88_start_audio_dma
  21. cx88_stop_audio_dma
  22. set_tvaudio
  23. cx88_set_tvnorm
  24. cx88_vdev_init
  25. cx88_core_get
  26. cx88_core_put

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * device driver for Conexant 2388x based TV cards
   4  * driver core
   5  *
   6  * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
   7  *
   8  * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org>
   9  *     - Multituner support
  10  *     - video_ioctl2 conversion
  11  *     - PAL/M fixes
  12  */
  13 
  14 #include "cx88.h"
  15 
  16 #include <linux/init.h>
  17 #include <linux/list.h>
  18 #include <linux/module.h>
  19 #include <linux/kernel.h>
  20 #include <linux/slab.h>
  21 #include <linux/kmod.h>
  22 #include <linux/sound.h>
  23 #include <linux/interrupt.h>
  24 #include <linux/pci.h>
  25 #include <linux/delay.h>
  26 #include <linux/videodev2.h>
  27 #include <linux/mutex.h>
  28 
  29 #include <media/v4l2-common.h>
  30 #include <media/v4l2-ioctl.h>
  31 
  32 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
  33 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
  34 MODULE_LICENSE("GPL v2");
  35 
  36 /* ------------------------------------------------------------------ */
  37 
  38 unsigned int cx88_core_debug;
  39 module_param_named(core_debug, cx88_core_debug, int, 0644);
  40 MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
  41 
  42 static unsigned int nicam;
  43 module_param(nicam, int, 0644);
  44 MODULE_PARM_DESC(nicam, "tv audio is nicam");
  45 
  46 static unsigned int nocomb;
  47 module_param(nocomb, int, 0644);
  48 MODULE_PARM_DESC(nocomb, "disable comb filter");
  49 
  50 #define dprintk0(fmt, arg...)                           \
  51         printk(KERN_DEBUG pr_fmt("%s: core:" fmt),      \
  52                 __func__, ##arg)                        \
  53 
  54 #define dprintk(level, fmt, arg...)     do {                    \
  55         if (cx88_core_debug >= level)                           \
  56                 printk(KERN_DEBUG pr_fmt("%s: core:" fmt),      \
  57                        __func__, ##arg);                        \
  58 } while (0)
  59 
  60 static unsigned int cx88_devcount;
  61 static LIST_HEAD(cx88_devlist);
  62 static DEFINE_MUTEX(devlist);
  63 
  64 #define NO_SYNC_LINE (-1U)
  65 
  66 /*
  67  * @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be
  68  * generated _after_ lpi lines are transferred.
  69  */
  70 static __le32 *cx88_risc_field(__le32 *rp, struct scatterlist *sglist,
  71                                unsigned int offset, u32 sync_line,
  72                                unsigned int bpl, unsigned int padding,
  73                                unsigned int lines, unsigned int lpi, bool jump)
  74 {
  75         struct scatterlist *sg;
  76         unsigned int line, todo, sol;
  77 
  78         if (jump) {
  79                 (*rp++) = cpu_to_le32(RISC_JUMP);
  80                 (*rp++) = 0;
  81         }
  82 
  83         /* sync instruction */
  84         if (sync_line != NO_SYNC_LINE)
  85                 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
  86 
  87         /* scan lines */
  88         sg = sglist;
  89         for (line = 0; line < lines; line++) {
  90                 while (offset && offset >= sg_dma_len(sg)) {
  91                         offset -= sg_dma_len(sg);
  92                         sg = sg_next(sg);
  93                 }
  94                 if (lpi && line > 0 && !(line % lpi))
  95                         sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
  96                 else
  97                         sol = RISC_SOL;
  98                 if (bpl <= sg_dma_len(sg) - offset) {
  99                         /* fits into current chunk */
 100                         *(rp++) = cpu_to_le32(RISC_WRITE | sol |
 101                                               RISC_EOL | bpl);
 102                         *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
 103                         offset += bpl;
 104                 } else {
 105                         /* scanline needs to be split */
 106                         todo = bpl;
 107                         *(rp++) = cpu_to_le32(RISC_WRITE | sol |
 108                                               (sg_dma_len(sg) - offset));
 109                         *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
 110                         todo -= (sg_dma_len(sg) - offset);
 111                         offset = 0;
 112                         sg = sg_next(sg);
 113                         while (todo > sg_dma_len(sg)) {
 114                                 *(rp++) = cpu_to_le32(RISC_WRITE |
 115                                                       sg_dma_len(sg));
 116                                 *(rp++) = cpu_to_le32(sg_dma_address(sg));
 117                                 todo -= sg_dma_len(sg);
 118                                 sg = sg_next(sg);
 119                         }
 120                         *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
 121                         *(rp++) = cpu_to_le32(sg_dma_address(sg));
 122                         offset += todo;
 123                 }
 124                 offset += padding;
 125         }
 126 
 127         return rp;
 128 }
 129 
 130 int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc,
 131                      struct scatterlist *sglist,
 132                      unsigned int top_offset, unsigned int bottom_offset,
 133                      unsigned int bpl, unsigned int padding, unsigned int lines)
 134 {
 135         u32 instructions, fields;
 136         __le32 *rp;
 137 
 138         fields = 0;
 139         if (top_offset != UNSET)
 140                 fields++;
 141         if (bottom_offset != UNSET)
 142                 fields++;
 143 
 144         /*
 145          * estimate risc mem: worst case is one write per page border +
 146          * one write per scan line + syncs + jump (all 2 dwords).  Padding
 147          * can cause next bpl to start close to a page border.  First DMA
 148          * region may be smaller than PAGE_SIZE
 149          */
 150         instructions  = fields * (1 + ((bpl + padding) * lines) /
 151                                   PAGE_SIZE + lines);
 152         instructions += 4;
 153         risc->size = instructions * 8;
 154         risc->dma = 0;
 155         risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma);
 156         if (!risc->cpu)
 157                 return -ENOMEM;
 158 
 159         /* write risc instructions */
 160         rp = risc->cpu;
 161         if (top_offset != UNSET)
 162                 rp = cx88_risc_field(rp, sglist, top_offset, 0,
 163                                      bpl, padding, lines, 0, true);
 164         if (bottom_offset != UNSET)
 165                 rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
 166                                      bpl, padding, lines, 0,
 167                                      top_offset == UNSET);
 168 
 169         /* save pointer to jmp instruction address */
 170         risc->jmp = rp;
 171         WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
 172         return 0;
 173 }
 174 EXPORT_SYMBOL(cx88_risc_buffer);
 175 
 176 int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc,
 177                          struct scatterlist *sglist, unsigned int bpl,
 178                          unsigned int lines, unsigned int lpi)
 179 {
 180         u32 instructions;
 181         __le32 *rp;
 182 
 183         /*
 184          * estimate risc mem: worst case is one write per page border +
 185          * one write per scan line + syncs + jump (all 2 dwords).  Here
 186          * there is no padding and no sync.  First DMA region may be smaller
 187          * than PAGE_SIZE
 188          */
 189         instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
 190         instructions += 3;
 191         risc->size = instructions * 8;
 192         risc->dma = 0;
 193         risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma);
 194         if (!risc->cpu)
 195                 return -ENOMEM;
 196 
 197         /* write risc instructions */
 198         rp = risc->cpu;
 199         rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
 200                              lines, lpi, !lpi);
 201 
 202         /* save pointer to jmp instruction address */
 203         risc->jmp = rp;
 204         WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
 205         return 0;
 206 }
 207 EXPORT_SYMBOL(cx88_risc_databuffer);
 208 
 209 /*
 210  * our SRAM memory layout
 211  */
 212 
 213 /*
 214  * we are going to put all thr risc programs into host memory, so we
 215  * can use the whole SDRAM for the DMA fifos.  To simplify things, we
 216  * use a static memory layout.  That surely will waste memory in case
 217  * we don't use all DMA channels at the same time (which will be the
 218  * case most of the time).  But that still gives us enough FIFO space
 219  * to be able to deal with insane long pci latencies ...
 220  *
 221  * FIFO space allocations:
 222  *    channel  21    (y video)  - 10.0k
 223  *    channel  22    (u video)  -  2.0k
 224  *    channel  23    (v video)  -  2.0k
 225  *    channel  24    (vbi)      -  4.0k
 226  *    channels 25+26 (audio)    -  4.0k
 227  *    channel  28    (mpeg)     -  4.0k
 228  *    channel  27    (audio rds)-  3.0k
 229  *    TOTAL                     = 29.0k
 230  *
 231  * Every channel has 160 bytes control data (64 bytes instruction
 232  * queue and 6 CDT entries), which is close to 2k total.
 233  *
 234  * Address layout:
 235  *    0x0000 - 0x03ff    CMDs / reserved
 236  *    0x0400 - 0x0bff    instruction queues + CDs
 237  *    0x0c00 -           FIFOs
 238  */
 239 
 240 const struct sram_channel cx88_sram_channels[] = {
 241         [SRAM_CH21] = {
 242                 .name       = "video y / packed",
 243                 .cmds_start = 0x180040,
 244                 .ctrl_start = 0x180400,
 245                 .cdt        = 0x180400 + 64,
 246                 .fifo_start = 0x180c00,
 247                 .fifo_size  = 0x002800,
 248                 .ptr1_reg   = MO_DMA21_PTR1,
 249                 .ptr2_reg   = MO_DMA21_PTR2,
 250                 .cnt1_reg   = MO_DMA21_CNT1,
 251                 .cnt2_reg   = MO_DMA21_CNT2,
 252         },
 253         [SRAM_CH22] = {
 254                 .name       = "video u",
 255                 .cmds_start = 0x180080,
 256                 .ctrl_start = 0x1804a0,
 257                 .cdt        = 0x1804a0 + 64,
 258                 .fifo_start = 0x183400,
 259                 .fifo_size  = 0x000800,
 260                 .ptr1_reg   = MO_DMA22_PTR1,
 261                 .ptr2_reg   = MO_DMA22_PTR2,
 262                 .cnt1_reg   = MO_DMA22_CNT1,
 263                 .cnt2_reg   = MO_DMA22_CNT2,
 264         },
 265         [SRAM_CH23] = {
 266                 .name       = "video v",
 267                 .cmds_start = 0x1800c0,
 268                 .ctrl_start = 0x180540,
 269                 .cdt        = 0x180540 + 64,
 270                 .fifo_start = 0x183c00,
 271                 .fifo_size  = 0x000800,
 272                 .ptr1_reg   = MO_DMA23_PTR1,
 273                 .ptr2_reg   = MO_DMA23_PTR2,
 274                 .cnt1_reg   = MO_DMA23_CNT1,
 275                 .cnt2_reg   = MO_DMA23_CNT2,
 276         },
 277         [SRAM_CH24] = {
 278                 .name       = "vbi",
 279                 .cmds_start = 0x180100,
 280                 .ctrl_start = 0x1805e0,
 281                 .cdt        = 0x1805e0 + 64,
 282                 .fifo_start = 0x184400,
 283                 .fifo_size  = 0x001000,
 284                 .ptr1_reg   = MO_DMA24_PTR1,
 285                 .ptr2_reg   = MO_DMA24_PTR2,
 286                 .cnt1_reg   = MO_DMA24_CNT1,
 287                 .cnt2_reg   = MO_DMA24_CNT2,
 288         },
 289         [SRAM_CH25] = {
 290                 .name       = "audio from",
 291                 .cmds_start = 0x180140,
 292                 .ctrl_start = 0x180680,
 293                 .cdt        = 0x180680 + 64,
 294                 .fifo_start = 0x185400,
 295                 .fifo_size  = 0x001000,
 296                 .ptr1_reg   = MO_DMA25_PTR1,
 297                 .ptr2_reg   = MO_DMA25_PTR2,
 298                 .cnt1_reg   = MO_DMA25_CNT1,
 299                 .cnt2_reg   = MO_DMA25_CNT2,
 300         },
 301         [SRAM_CH26] = {
 302                 .name       = "audio to",
 303                 .cmds_start = 0x180180,
 304                 .ctrl_start = 0x180720,
 305                 .cdt        = 0x180680 + 64,  /* same as audio IN */
 306                 .fifo_start = 0x185400,       /* same as audio IN */
 307                 .fifo_size  = 0x001000,       /* same as audio IN */
 308                 .ptr1_reg   = MO_DMA26_PTR1,
 309                 .ptr2_reg   = MO_DMA26_PTR2,
 310                 .cnt1_reg   = MO_DMA26_CNT1,
 311                 .cnt2_reg   = MO_DMA26_CNT2,
 312         },
 313         [SRAM_CH28] = {
 314                 .name       = "mpeg",
 315                 .cmds_start = 0x180200,
 316                 .ctrl_start = 0x1807C0,
 317                 .cdt        = 0x1807C0 + 64,
 318                 .fifo_start = 0x186400,
 319                 .fifo_size  = 0x001000,
 320                 .ptr1_reg   = MO_DMA28_PTR1,
 321                 .ptr2_reg   = MO_DMA28_PTR2,
 322                 .cnt1_reg   = MO_DMA28_CNT1,
 323                 .cnt2_reg   = MO_DMA28_CNT2,
 324         },
 325         [SRAM_CH27] = {
 326                 .name       = "audio rds",
 327                 .cmds_start = 0x1801C0,
 328                 .ctrl_start = 0x180860,
 329                 .cdt        = 0x180860 + 64,
 330                 .fifo_start = 0x187400,
 331                 .fifo_size  = 0x000C00,
 332                 .ptr1_reg   = MO_DMA27_PTR1,
 333                 .ptr2_reg   = MO_DMA27_PTR2,
 334                 .cnt1_reg   = MO_DMA27_CNT1,
 335                 .cnt2_reg   = MO_DMA27_CNT2,
 336         },
 337 };
 338 EXPORT_SYMBOL(cx88_sram_channels);
 339 
 340 int cx88_sram_channel_setup(struct cx88_core *core,
 341                             const struct sram_channel *ch,
 342                             unsigned int bpl, u32 risc)
 343 {
 344         unsigned int i, lines;
 345         u32 cdt;
 346 
 347         bpl   = (bpl + 7) & ~7; /* alignment */
 348         cdt   = ch->cdt;
 349         lines = ch->fifo_size / bpl;
 350         if (lines > 6)
 351                 lines = 6;
 352         WARN_ON(lines < 2);
 353 
 354         /* write CDT */
 355         for (i = 0; i < lines; i++)
 356                 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
 357 
 358         /* write CMDS */
 359         cx_write(ch->cmds_start +  0, risc);
 360         cx_write(ch->cmds_start +  4, cdt);
 361         cx_write(ch->cmds_start +  8, (lines * 16) >> 3);
 362         cx_write(ch->cmds_start + 12, ch->ctrl_start);
 363         cx_write(ch->cmds_start + 16, 64 >> 2);
 364         for (i = 20; i < 64; i += 4)
 365                 cx_write(ch->cmds_start + i, 0);
 366 
 367         /* fill registers */
 368         cx_write(ch->ptr1_reg, ch->fifo_start);
 369         cx_write(ch->ptr2_reg, cdt);
 370         cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
 371         cx_write(ch->cnt2_reg, (lines * 16) >> 3);
 372 
 373         dprintk(2, "sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
 374         return 0;
 375 }
 376 EXPORT_SYMBOL(cx88_sram_channel_setup);
 377 
 378 /* ------------------------------------------------------------------ */
 379 /* debug helper code                                                  */
 380 
 381 static int cx88_risc_decode(u32 risc)
 382 {
 383         static const char * const instr[16] = {
 384                 [RISC_SYNC    >> 28] = "sync",
 385                 [RISC_WRITE   >> 28] = "write",
 386                 [RISC_WRITEC  >> 28] = "writec",
 387                 [RISC_READ    >> 28] = "read",
 388                 [RISC_READC   >> 28] = "readc",
 389                 [RISC_JUMP    >> 28] = "jump",
 390                 [RISC_SKIP    >> 28] = "skip",
 391                 [RISC_WRITERM >> 28] = "writerm",
 392                 [RISC_WRITECM >> 28] = "writecm",
 393                 [RISC_WRITECR >> 28] = "writecr",
 394         };
 395         static int const incr[16] = {
 396                 [RISC_WRITE   >> 28] = 2,
 397                 [RISC_JUMP    >> 28] = 2,
 398                 [RISC_WRITERM >> 28] = 3,
 399                 [RISC_WRITECM >> 28] = 3,
 400                 [RISC_WRITECR >> 28] = 4,
 401         };
 402         static const char * const bits[] = {
 403                 "12",   "13",   "14",   "resync",
 404                 "cnt0", "cnt1", "18",   "19",
 405                 "20",   "21",   "22",   "23",
 406                 "irq1", "irq2", "eol",  "sol",
 407         };
 408         int i;
 409 
 410         dprintk0("0x%08x [ %s", risc,
 411                  instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
 412         for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--)
 413                 if (risc & (1 << (i + 12)))
 414                         pr_cont(" %s", bits[i]);
 415         pr_cont(" count=%d ]\n", risc & 0xfff);
 416         return incr[risc >> 28] ? incr[risc >> 28] : 1;
 417 }
 418 
 419 void cx88_sram_channel_dump(struct cx88_core *core,
 420                             const struct sram_channel *ch)
 421 {
 422         static const char * const name[] = {
 423                 "initial risc",
 424                 "cdt base",
 425                 "cdt size",
 426                 "iq base",
 427                 "iq size",
 428                 "risc pc",
 429                 "iq wr ptr",
 430                 "iq rd ptr",
 431                 "cdt current",
 432                 "pci target",
 433                 "line / byte",
 434         };
 435         u32 risc;
 436         unsigned int i, j, n;
 437 
 438         dprintk0("%s - dma channel status dump\n", ch->name);
 439         for (i = 0; i < ARRAY_SIZE(name); i++)
 440                 dprintk0("   cmds: %-12s: 0x%08x\n",
 441                          name[i], cx_read(ch->cmds_start + 4 * i));
 442         for (n = 1, i = 0; i < 4; i++) {
 443                 risc = cx_read(ch->cmds_start + 4 * (i + 11));
 444                 pr_cont("  risc%d: ", i);
 445                 if (--n)
 446                         pr_cont("0x%08x [ arg #%d ]\n", risc, n);
 447                 else
 448                         n = cx88_risc_decode(risc);
 449         }
 450         for (i = 0; i < 16; i += n) {
 451                 risc = cx_read(ch->ctrl_start + 4 * i);
 452                 dprintk0("  iq %x: ", i);
 453                 n = cx88_risc_decode(risc);
 454                 for (j = 1; j < n; j++) {
 455                         risc = cx_read(ch->ctrl_start + 4 * (i + j));
 456                         pr_cont("  iq %x: 0x%08x [ arg #%d ]\n",
 457                                 i + j, risc, j);
 458                 }
 459         }
 460 
 461         dprintk0("fifo: 0x%08x -> 0x%x\n",
 462                  ch->fifo_start, ch->fifo_start + ch->fifo_size);
 463         dprintk0("ctrl: 0x%08x -> 0x%x\n",
 464                  ch->ctrl_start, ch->ctrl_start + 6 * 16);
 465         dprintk0("  ptr1_reg: 0x%08x\n", cx_read(ch->ptr1_reg));
 466         dprintk0("  ptr2_reg: 0x%08x\n", cx_read(ch->ptr2_reg));
 467         dprintk0("  cnt1_reg: 0x%08x\n", cx_read(ch->cnt1_reg));
 468         dprintk0("  cnt2_reg: 0x%08x\n", cx_read(ch->cnt2_reg));
 469 }
 470 EXPORT_SYMBOL(cx88_sram_channel_dump);
 471 
 472 static const char *cx88_pci_irqs[32] = {
 473         "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
 474         "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
 475         "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
 476         "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
 477 };
 478 
 479 void cx88_print_irqbits(const char *tag, const char *strings[],
 480                         int len, u32 bits, u32 mask)
 481 {
 482         unsigned int i;
 483 
 484         dprintk0("%s [0x%x]", tag, bits);
 485         for (i = 0; i < len; i++) {
 486                 if (!(bits & (1 << i)))
 487                         continue;
 488                 if (strings[i])
 489                         pr_cont(" %s", strings[i]);
 490                 else
 491                         pr_cont(" %d", i);
 492                 if (!(mask & (1 << i)))
 493                         continue;
 494                 pr_cont("*");
 495         }
 496         pr_cont("\n");
 497 }
 498 EXPORT_SYMBOL(cx88_print_irqbits);
 499 
 500 /* ------------------------------------------------------------------ */
 501 
 502 int cx88_core_irq(struct cx88_core *core, u32 status)
 503 {
 504         int handled = 0;
 505 
 506         if (status & PCI_INT_IR_SMPINT) {
 507                 cx88_ir_irq(core);
 508                 handled++;
 509         }
 510         if (!handled)
 511                 cx88_print_irqbits("irq pci",
 512                                    cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
 513                                    status, core->pci_irqmask);
 514         return handled;
 515 }
 516 EXPORT_SYMBOL(cx88_core_irq);
 517 
 518 void cx88_wakeup(struct cx88_core *core,
 519                  struct cx88_dmaqueue *q, u32 count)
 520 {
 521         struct cx88_buffer *buf;
 522 
 523         buf = list_entry(q->active.next,
 524                          struct cx88_buffer, list);
 525         buf->vb.vb2_buf.timestamp = ktime_get_ns();
 526         buf->vb.field = core->field;
 527         buf->vb.sequence = q->count++;
 528         list_del(&buf->list);
 529         vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 530 }
 531 EXPORT_SYMBOL(cx88_wakeup);
 532 
 533 void cx88_shutdown(struct cx88_core *core)
 534 {
 535         /* disable RISC controller + IRQs */
 536         cx_write(MO_DEV_CNTRL2, 0);
 537 
 538         /* stop dma transfers */
 539         cx_write(MO_VID_DMACNTRL, 0x0);
 540         cx_write(MO_AUD_DMACNTRL, 0x0);
 541         cx_write(MO_TS_DMACNTRL, 0x0);
 542         cx_write(MO_VIP_DMACNTRL, 0x0);
 543         cx_write(MO_GPHST_DMACNTRL, 0x0);
 544 
 545         /* stop interrupts */
 546         cx_write(MO_PCI_INTMSK, 0x0);
 547         cx_write(MO_VID_INTMSK, 0x0);
 548         cx_write(MO_AUD_INTMSK, 0x0);
 549         cx_write(MO_TS_INTMSK, 0x0);
 550         cx_write(MO_VIP_INTMSK, 0x0);
 551         cx_write(MO_GPHST_INTMSK, 0x0);
 552 
 553         /* stop capturing */
 554         cx_write(VID_CAPTURE_CONTROL, 0);
 555 }
 556 EXPORT_SYMBOL(cx88_shutdown);
 557 
 558 int cx88_reset(struct cx88_core *core)
 559 {
 560         dprintk(1, "");
 561         cx88_shutdown(core);
 562 
 563         /* clear irq status */
 564         cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
 565         cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
 566         cx_write(MO_INT1_STAT,   0xFFFFFFFF); // Clear RISC int
 567 
 568         /* wait a bit */
 569         msleep(100);
 570 
 571         /* init sram */
 572         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21],
 573                                 720 * 4, 0);
 574         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
 575         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
 576         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
 577         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
 578         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
 579         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
 580                                 188 * 4, 0);
 581         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
 582 
 583         /* misc init ... */
 584         cx_write(MO_INPUT_FORMAT, ((1 << 13) |   // agc enable
 585                                    (1 << 12) |   // agc gain
 586                                    (1 << 11) |   // adaptibe agc
 587                                    (0 << 10) |   // chroma agc
 588                                    (0 <<  9) |   // ckillen
 589                                    (7)));
 590 
 591         /* setup image format */
 592         cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
 593 
 594         /* setup FIFO Thresholds */
 595         cx_write(MO_PDMA_STHRSH,   0x0807);
 596         cx_write(MO_PDMA_DTHRSH,   0x0807);
 597 
 598         /* fixes flashing of image */
 599         cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
 600         cx_write(MO_AGC_BACK_VBI,  0x00E00555);
 601 
 602         cx_write(MO_VID_INTSTAT,   0xFFFFFFFF); // Clear PIV int
 603         cx_write(MO_PCI_INTSTAT,   0xFFFFFFFF); // Clear PCI int
 604         cx_write(MO_INT1_STAT,     0xFFFFFFFF); // Clear RISC int
 605 
 606         /* Reset on-board parts */
 607         cx_write(MO_SRST_IO, 0);
 608         usleep_range(10000, 20000);
 609         cx_write(MO_SRST_IO, 1);
 610 
 611         return 0;
 612 }
 613 EXPORT_SYMBOL(cx88_reset);
 614 
 615 /* ------------------------------------------------------------------ */
 616 
 617 static inline unsigned int norm_swidth(v4l2_std_id norm)
 618 {
 619         return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
 620 }
 621 
 622 static inline unsigned int norm_hdelay(v4l2_std_id norm)
 623 {
 624         return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
 625 }
 626 
 627 static inline unsigned int norm_vdelay(v4l2_std_id norm)
 628 {
 629         return (norm & V4L2_STD_625_50) ? 0x24 : 0x18;
 630 }
 631 
 632 static inline unsigned int norm_fsc8(v4l2_std_id norm)
 633 {
 634         if (norm & V4L2_STD_PAL_M)
 635                 return 28604892;      // 3.575611 MHz
 636 
 637         if (norm & (V4L2_STD_PAL_Nc))
 638                 return 28656448;      // 3.582056 MHz
 639 
 640         if (norm & V4L2_STD_NTSC) // All NTSC/M and variants
 641                 return 28636360;      // 3.57954545 MHz +/- 10 Hz
 642 
 643         /*
 644          * SECAM have also different sub carrier for chroma,
 645          * but step_db and step_dr, at cx88_set_tvnorm already handles that.
 646          *
 647          * The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N
 648          */
 649 
 650         return 35468950;      // 4.43361875 MHz +/- 5 Hz
 651 }
 652 
 653 static inline unsigned int norm_htotal(v4l2_std_id norm)
 654 {
 655         unsigned int fsc4 = norm_fsc8(norm) / 2;
 656 
 657         /* returns 4*FSC / vtotal / frames per seconds */
 658         return (norm & V4L2_STD_625_50) ?
 659                                 ((fsc4 + 312) / 625 + 12) / 25 :
 660                                 ((fsc4 + 262) / 525 * 1001 + 15000) / 30000;
 661 }
 662 
 663 static inline unsigned int norm_vbipack(v4l2_std_id norm)
 664 {
 665         return (norm & V4L2_STD_625_50) ? 511 : 400;
 666 }
 667 
 668 int cx88_set_scale(struct cx88_core *core, unsigned int width,
 669                    unsigned int height, enum v4l2_field field)
 670 {
 671         unsigned int swidth  = norm_swidth(core->tvnorm);
 672         unsigned int sheight = norm_maxh(core->tvnorm);
 673         u32 value;
 674 
 675         dprintk(1, "set_scale: %dx%d [%s%s,%s]\n", width, height,
 676                 V4L2_FIELD_HAS_TOP(field)    ? "T" : "",
 677                 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
 678                 v4l2_norm_to_name(core->tvnorm));
 679         if (!V4L2_FIELD_HAS_BOTH(field))
 680                 height *= 2;
 681 
 682         // recalc H delay and scale registers
 683         value = (width * norm_hdelay(core->tvnorm)) / swidth;
 684         value &= 0x3fe;
 685         cx_write(MO_HDELAY_EVEN,  value);
 686         cx_write(MO_HDELAY_ODD,   value);
 687         dprintk(1, "set_scale: hdelay  0x%04x (width %d)\n", value, swidth);
 688 
 689         value = (swidth * 4096 / width) - 4096;
 690         cx_write(MO_HSCALE_EVEN,  value);
 691         cx_write(MO_HSCALE_ODD,   value);
 692         dprintk(1, "set_scale: hscale  0x%04x\n", value);
 693 
 694         cx_write(MO_HACTIVE_EVEN, width);
 695         cx_write(MO_HACTIVE_ODD,  width);
 696         dprintk(1, "set_scale: hactive 0x%04x\n", width);
 697 
 698         // recalc V scale Register (delay is constant)
 699         cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
 700         cx_write(MO_VDELAY_ODD,  norm_vdelay(core->tvnorm));
 701         dprintk(1, "set_scale: vdelay  0x%04x\n", norm_vdelay(core->tvnorm));
 702 
 703         value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
 704         cx_write(MO_VSCALE_EVEN,  value);
 705         cx_write(MO_VSCALE_ODD,   value);
 706         dprintk(1, "set_scale: vscale  0x%04x\n", value);
 707 
 708         cx_write(MO_VACTIVE_EVEN, sheight);
 709         cx_write(MO_VACTIVE_ODD,  sheight);
 710         dprintk(1, "set_scale: vactive 0x%04x\n", sheight);
 711 
 712         // setup filters
 713         value = 0;
 714         value |= (1 << 19);        // CFILT (default)
 715         if (core->tvnorm & V4L2_STD_SECAM) {
 716                 value |= (1 << 15);
 717                 value |= (1 << 16);
 718         }
 719         if (INPUT(core->input).type == CX88_VMUX_SVIDEO)
 720                 value |= (1 << 13) | (1 << 5);
 721         if (field == V4L2_FIELD_INTERLACED)
 722                 value |= (1 << 3); // VINT (interlaced vertical scaling)
 723         if (width < 385)
 724                 value |= (1 << 0); // 3-tap interpolation
 725         if (width < 193)
 726                 value |= (1 << 1); // 5-tap interpolation
 727         if (nocomb)
 728                 value |= (3 << 5); // disable comb filter
 729 
 730         cx_andor(MO_FILTER_EVEN,  0x7ffc7f, value); /* preserve PEAKEN, PSEL */
 731         cx_andor(MO_FILTER_ODD,   0x7ffc7f, value);
 732         dprintk(1, "set_scale: filter  0x%04x\n", value);
 733 
 734         return 0;
 735 }
 736 EXPORT_SYMBOL(cx88_set_scale);
 737 
 738 static const u32 xtal = 28636363;
 739 
 740 static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
 741 {
 742         static const u32 pre[] = { 0, 0, 0, 3, 2, 1 };
 743         u64 pll;
 744         u32 reg;
 745         int i;
 746 
 747         if (prescale < 2)
 748                 prescale = 2;
 749         if (prescale > 5)
 750                 prescale = 5;
 751 
 752         pll = ofreq * 8 * prescale * (u64)(1 << 20);
 753         do_div(pll, xtal);
 754         reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
 755         if (((reg >> 20) & 0x3f) < 14) {
 756                 pr_err("pll out of range\n");
 757                 return -1;
 758         }
 759 
 760         dprintk(1, "set_pll:    MO_PLL_REG       0x%08x [old=0x%08x,freq=%d]\n",
 761                 reg, cx_read(MO_PLL_REG), ofreq);
 762         cx_write(MO_PLL_REG, reg);
 763         for (i = 0; i < 100; i++) {
 764                 reg = cx_read(MO_DEVICE_STATUS);
 765                 if (reg & (1 << 2)) {
 766                         dprintk(1, "pll locked [pre=%d,ofreq=%d]\n",
 767                                 prescale, ofreq);
 768                         return 0;
 769                 }
 770                 dprintk(1, "pll not locked yet, waiting ...\n");
 771                 usleep_range(10000, 20000);
 772         }
 773         dprintk(1, "pll NOT locked [pre=%d,ofreq=%d]\n", prescale, ofreq);
 774         return -1;
 775 }
 776 
 777 int cx88_start_audio_dma(struct cx88_core *core)
 778 {
 779         /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
 780         int bpl = cx88_sram_channels[SRAM_CH25].fifo_size / 4;
 781 
 782         int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size / AUD_RDS_LINES;
 783 
 784         /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
 785         if (cx_read(MO_AUD_DMACNTRL) & 0x10)
 786                 return 0;
 787 
 788         /* setup fifo + format */
 789         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
 790         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
 791         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
 792                                 rds_bpl, 0);
 793 
 794         cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
 795         cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */
 796 
 797         /* enable Up, Down and Audio RDS fifo */
 798         cx_write(MO_AUD_DMACNTRL, 0x0007);
 799 
 800         return 0;
 801 }
 802 
 803 int cx88_stop_audio_dma(struct cx88_core *core)
 804 {
 805         /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
 806         if (cx_read(MO_AUD_DMACNTRL) & 0x10)
 807                 return 0;
 808 
 809         /* stop dma */
 810         cx_write(MO_AUD_DMACNTRL, 0x0000);
 811 
 812         return 0;
 813 }
 814 
 815 static int set_tvaudio(struct cx88_core *core)
 816 {
 817         v4l2_std_id norm = core->tvnorm;
 818 
 819         if (INPUT(core->input).type != CX88_VMUX_TELEVISION &&
 820             INPUT(core->input).type != CX88_VMUX_CABLE)
 821                 return 0;
 822 
 823         if (V4L2_STD_PAL_BG & norm) {
 824                 core->tvaudio = WW_BG;
 825 
 826         } else if (V4L2_STD_PAL_DK & norm) {
 827                 core->tvaudio = WW_DK;
 828 
 829         } else if (V4L2_STD_PAL_I & norm) {
 830                 core->tvaudio = WW_I;
 831 
 832         } else if (V4L2_STD_SECAM_L & norm) {
 833                 core->tvaudio = WW_L;
 834 
 835         } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) &
 836                    norm) {
 837                 core->tvaudio = WW_BG;
 838 
 839         } else if (V4L2_STD_SECAM_DK & norm) {
 840                 core->tvaudio = WW_DK;
 841 
 842         } else if ((V4L2_STD_NTSC_M & norm) ||
 843                    (V4L2_STD_PAL_M  & norm)) {
 844                 core->tvaudio = WW_BTSC;
 845 
 846         } else if (V4L2_STD_NTSC_M_JP & norm) {
 847                 core->tvaudio = WW_EIAJ;
 848 
 849         } else {
 850                 pr_info("tvaudio support needs work for this tv norm [%s], sorry\n",
 851                         v4l2_norm_to_name(core->tvnorm));
 852                 core->tvaudio = WW_NONE;
 853                 return 0;
 854         }
 855 
 856         cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
 857         cx88_set_tvaudio(core);
 858         /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
 859 
 860 /*
 861  * This should be needed only on cx88-alsa. It seems that some cx88 chips have
 862  * bugs and does require DMA enabled for it to work.
 863  */
 864         cx88_start_audio_dma(core);
 865         return 0;
 866 }
 867 
 868 int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
 869 {
 870         u32 fsc8;
 871         u32 adc_clock;
 872         u32 vdec_clock;
 873         u32 step_db, step_dr;
 874         u64 tmp64;
 875         u32 bdelay, agcdelay, htotal;
 876         u32 cxiformat, cxoformat;
 877 
 878         if (norm == core->tvnorm)
 879                 return 0;
 880         if (core->v4ldev && (vb2_is_busy(&core->v4ldev->vb2_vidq) ||
 881                              vb2_is_busy(&core->v4ldev->vb2_vbiq)))
 882                 return -EBUSY;
 883         if (core->dvbdev && vb2_is_busy(&core->dvbdev->vb2_mpegq))
 884                 return -EBUSY;
 885         core->tvnorm = norm;
 886         fsc8       = norm_fsc8(norm);
 887         adc_clock  = xtal;
 888         vdec_clock = fsc8;
 889         step_db    = fsc8;
 890         step_dr    = fsc8;
 891 
 892         if (norm & V4L2_STD_NTSC_M_JP) {
 893                 cxiformat = VideoFormatNTSCJapan;
 894                 cxoformat = 0x181f0008;
 895         } else if (norm & V4L2_STD_NTSC_443) {
 896                 cxiformat = VideoFormatNTSC443;
 897                 cxoformat = 0x181f0008;
 898         } else if (norm & V4L2_STD_PAL_M) {
 899                 cxiformat = VideoFormatPALM;
 900                 cxoformat = 0x1c1f0008;
 901         } else if (norm & V4L2_STD_PAL_N) {
 902                 cxiformat = VideoFormatPALN;
 903                 cxoformat = 0x1c1f0008;
 904         } else if (norm & V4L2_STD_PAL_Nc) {
 905                 cxiformat = VideoFormatPALNC;
 906                 cxoformat = 0x1c1f0008;
 907         } else if (norm & V4L2_STD_PAL_60) {
 908                 cxiformat = VideoFormatPAL60;
 909                 cxoformat = 0x181f0008;
 910         } else if (norm & V4L2_STD_NTSC) {
 911                 cxiformat = VideoFormatNTSC;
 912                 cxoformat = 0x181f0008;
 913         } else if (norm & V4L2_STD_SECAM) {
 914                 step_db = 4250000 * 8;
 915                 step_dr = 4406250 * 8;
 916 
 917                 cxiformat = VideoFormatSECAM;
 918                 cxoformat = 0x181f0008;
 919         } else { /* PAL */
 920                 cxiformat = VideoFormatPAL;
 921                 cxoformat = 0x181f0008;
 922         }
 923 
 924         dprintk(1, "set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
 925                 v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock,
 926                 step_db, step_dr);
 927         set_pll(core, 2, vdec_clock);
 928 
 929         dprintk(1, "set_tvnorm: MO_INPUT_FORMAT  0x%08x [old=0x%08x]\n",
 930                 cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
 931         /*
 932          * Chroma AGC must be disabled if SECAM is used, we enable it
 933          * by default on PAL and NTSC
 934          */
 935         cx_andor(MO_INPUT_FORMAT, 0x40f,
 936                  norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400);
 937 
 938         // FIXME: as-is from DScaler
 939         dprintk(1, "set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
 940                 cxoformat, cx_read(MO_OUTPUT_FORMAT));
 941         cx_write(MO_OUTPUT_FORMAT, cxoformat);
 942 
 943         // MO_SCONV_REG = adc clock / video dec clock * 2^17
 944         tmp64  = adc_clock * (u64)(1 << 17);
 945         do_div(tmp64, vdec_clock);
 946         dprintk(1, "set_tvnorm: MO_SCONV_REG     0x%08x [old=0x%08x]\n",
 947                 (u32)tmp64, cx_read(MO_SCONV_REG));
 948         cx_write(MO_SCONV_REG, (u32)tmp64);
 949 
 950         // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
 951         tmp64  = step_db * (u64)(1 << 22);
 952         do_div(tmp64, vdec_clock);
 953         dprintk(1, "set_tvnorm: MO_SUB_STEP      0x%08x [old=0x%08x]\n",
 954                 (u32)tmp64, cx_read(MO_SUB_STEP));
 955         cx_write(MO_SUB_STEP, (u32)tmp64);
 956 
 957         // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
 958         tmp64  = step_dr * (u64)(1 << 22);
 959         do_div(tmp64, vdec_clock);
 960         dprintk(1, "set_tvnorm: MO_SUB_STEP_DR   0x%08x [old=0x%08x]\n",
 961                 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
 962         cx_write(MO_SUB_STEP_DR, (u32)tmp64);
 963 
 964         // bdelay + agcdelay
 965         bdelay   = vdec_clock * 65 / 20000000 + 21;
 966         agcdelay = vdec_clock * 68 / 20000000 + 15;
 967         dprintk(1,
 968                 "set_tvnorm: MO_AGC_BURST     0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
 969                 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST),
 970                 bdelay, agcdelay);
 971         cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
 972 
 973         // htotal
 974         tmp64 = norm_htotal(norm) * (u64)vdec_clock;
 975         do_div(tmp64, fsc8);
 976         htotal = (u32)tmp64;
 977         dprintk(1,
 978                 "set_tvnorm: MO_HTOTAL        0x%08x [old=0x%08x,htotal=%d]\n",
 979                 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
 980         cx_andor(MO_HTOTAL, 0x07ff, htotal);
 981 
 982         // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
 983         // the effective vbi offset ~244 samples, the same as the Bt8x8
 984         cx_write(MO_VBI_PACKET, (10 << 11) | norm_vbipack(norm));
 985 
 986         // this is needed as well to set all tvnorm parameter
 987         cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
 988 
 989         // audio
 990         set_tvaudio(core);
 991 
 992         // tell i2c chips
 993         call_all(core, video, s_std, norm);
 994 
 995         /*
 996          * The chroma_agc control should be inaccessible
 997          * if the video format is SECAM
 998          */
 999         v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM);
1000 
1001         // done
1002         return 0;
1003 }
1004 EXPORT_SYMBOL(cx88_set_tvnorm);
1005 
1006 /* ------------------------------------------------------------------ */
1007 
1008 void cx88_vdev_init(struct cx88_core *core,
1009                     struct pci_dev *pci,
1010                     struct video_device *vfd,
1011                     const struct video_device *template_,
1012                     const char *type)
1013 {
1014         *vfd = *template_;
1015 
1016         /*
1017          * The dev pointer of v4l2_device is NULL, instead we set the
1018          * video_device dev_parent pointer to the correct PCI bus device.
1019          * This driver is a rare example where there is one v4l2_device,
1020          * but the video nodes have different parent (PCI) devices.
1021          */
1022         vfd->v4l2_dev = &core->v4l2_dev;
1023         vfd->dev_parent = &pci->dev;
1024         vfd->release = video_device_release_empty;
1025         vfd->lock = &core->lock;
1026         snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1027                  core->name, type, core->board.name);
1028 }
1029 EXPORT_SYMBOL(cx88_vdev_init);
1030 
1031 struct cx88_core *cx88_core_get(struct pci_dev *pci)
1032 {
1033         struct cx88_core *core;
1034 
1035         mutex_lock(&devlist);
1036         list_for_each_entry(core, &cx88_devlist, devlist) {
1037                 if (pci->bus->number != core->pci_bus)
1038                         continue;
1039                 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1040                         continue;
1041 
1042                 if (cx88_get_resources(core, pci) != 0) {
1043                         mutex_unlock(&devlist);
1044                         return NULL;
1045                 }
1046                 refcount_inc(&core->refcount);
1047                 mutex_unlock(&devlist);
1048                 return core;
1049         }
1050 
1051         core = cx88_core_create(pci, cx88_devcount);
1052         if (core) {
1053                 cx88_devcount++;
1054                 list_add_tail(&core->devlist, &cx88_devlist);
1055         }
1056 
1057         mutex_unlock(&devlist);
1058         return core;
1059 }
1060 EXPORT_SYMBOL(cx88_core_get);
1061 
1062 void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1063 {
1064         release_mem_region(pci_resource_start(pci, 0),
1065                            pci_resource_len(pci, 0));
1066 
1067         if (!refcount_dec_and_test(&core->refcount))
1068                 return;
1069 
1070         mutex_lock(&devlist);
1071         cx88_ir_fini(core);
1072         if (core->i2c_rc == 0) {
1073                 if (core->i2c_rtc)
1074                         i2c_unregister_device(core->i2c_rtc);
1075                 i2c_del_adapter(&core->i2c_adap);
1076         }
1077         list_del(&core->devlist);
1078         iounmap(core->lmmio);
1079         cx88_devcount--;
1080         mutex_unlock(&devlist);
1081         v4l2_ctrl_handler_free(&core->video_hdl);
1082         v4l2_ctrl_handler_free(&core->audio_hdl);
1083         v4l2_device_unregister(&core->v4l2_dev);
1084         kfree(core);
1085 }
1086 EXPORT_SYMBOL(cx88_core_put);

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