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