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