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