V4L/DVB (4681): Cx88: fix analog capture notch filter
[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 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/init.h>
24#include <linux/list.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/kmod.h>
30#include <linux/sound.h>
31#include <linux/interrupt.h>
32#include <linux/pci.h>
33#include <linux/delay.h>
98f30ed0 34#include <linux/videodev2.h>
1e4baed3 35#include <linux/mutex.h>
1da177e4
LT
36
37#include "cx88.h"
5e453dc7 38#include <media/v4l2-common.h>
1da177e4
LT
39
40MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
41MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
42MODULE_LICENSE("GPL");
43
44/* ------------------------------------------------------------------ */
45
46static unsigned int core_debug = 0;
47module_param(core_debug,int,0644);
48MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
49
50static unsigned int latency = UNSET;
51module_param(latency,int,0444);
52MODULE_PARM_DESC(latency,"pci latency timer");
53
54static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
b45009b0 55static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
1da177e4
LT
56static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
57
58module_param_array(tuner, int, NULL, 0444);
b45009b0 59module_param_array(radio, int, NULL, 0444);
1da177e4
LT
60module_param_array(card, int, NULL, 0444);
61
62MODULE_PARM_DESC(tuner,"tuner type");
b45009b0 63MODULE_PARM_DESC(radio,"radio tuner type");
1da177e4
LT
64MODULE_PARM_DESC(card,"card type");
65
66static unsigned int nicam = 0;
67module_param(nicam,int,0644);
68MODULE_PARM_DESC(nicam,"tv audio is nicam");
69
70static unsigned int nocomb = 0;
71module_param(nocomb,int,0644);
72MODULE_PARM_DESC(nocomb,"disable comb filter");
73
74#define dprintk(level,fmt, arg...) if (core_debug >= level) \
75 printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
76
77static unsigned int cx88_devcount;
78static LIST_HEAD(cx88_devlist);
1e4baed3 79static DEFINE_MUTEX(devlist);
1da177e4 80
1da177e4
LT
81#define NO_SYNC_LINE (-1U)
82
83static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
84 unsigned int offset, u32 sync_line,
85 unsigned int bpl, unsigned int padding,
86 unsigned int lines)
87{
88 struct scatterlist *sg;
89 unsigned int line,todo;
90
91 /* sync instruction */
92 if (sync_line != NO_SYNC_LINE)
93 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
94
95 /* scan lines */
96 sg = sglist;
97 for (line = 0; line < lines; line++) {
98 while (offset && offset >= sg_dma_len(sg)) {
99 offset -= sg_dma_len(sg);
100 sg++;
101 }
102 if (bpl <= sg_dma_len(sg)-offset) {
103 /* fits into current chunk */
4ac97914
MCC
104 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
105 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
106 offset+=bpl;
1da177e4 107 } else {
d1009bd7 108 /* scanline needs to be split */
4ac97914
MCC
109 todo = bpl;
110 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
1da177e4 111 (sg_dma_len(sg)-offset));
4ac97914
MCC
112 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
113 todo -= (sg_dma_len(sg)-offset);
114 offset = 0;
115 sg++;
116 while (todo > sg_dma_len(sg)) {
f2421ca3 117 *(rp++)=cpu_to_le32(RISC_WRITE|
1da177e4 118 sg_dma_len(sg));
f2421ca3 119 *(rp++)=cpu_to_le32(sg_dma_address(sg));
1da177e4
LT
120 todo -= sg_dma_len(sg);
121 sg++;
122 }
4ac97914 123 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
1da177e4
LT
124 *(rp++)=cpu_to_le32(sg_dma_address(sg));
125 offset += todo;
126 }
127 offset += padding;
128 }
129
130 return rp;
131}
132
133int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
134 struct scatterlist *sglist,
135 unsigned int top_offset, unsigned int bottom_offset,
136 unsigned int bpl, unsigned int padding, unsigned int lines)
137{
138 u32 instructions,fields;
139 u32 *rp;
140 int rc;
141
142 fields = 0;
143 if (UNSET != top_offset)
144 fields++;
145 if (UNSET != bottom_offset)
146 fields++;
147
148 /* estimate risc mem: worst case is one write per page border +
bba3ad76
DS
149 one write per scan line + syncs + jump (all 2 dwords). Padding
150 can cause next bpl to start close to a page border. First DMA
151 region may be smaller than PAGE_SIZE */
152 instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
153 instructions += 2;
1da177e4
LT
154 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
155 return rc;
156
157 /* write risc instructions */
158 rp = risc->cpu;
159 if (UNSET != top_offset)
160 rp = cx88_risc_field(rp, sglist, top_offset, 0,
161 bpl, padding, lines);
162 if (UNSET != bottom_offset)
163 rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
164 bpl, padding, lines);
165
166 /* save pointer to jmp instruction address */
167 risc->jmp = rp;
4a287cfe 168 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
1da177e4
LT
169 return 0;
170}
171
172int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
173 struct scatterlist *sglist, unsigned int bpl,
174 unsigned int lines)
175{
176 u32 instructions;
177 u32 *rp;
178 int rc;
179
180 /* estimate risc mem: worst case is one write per page border +
bba3ad76
DS
181 one write per scan line + syncs + jump (all 2 dwords). Here
182 there is no padding and no sync. First DMA region may be smaller
183 than PAGE_SIZE */
184 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
185 instructions += 1;
1da177e4
LT
186 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
187 return rc;
188
189 /* write risc instructions */
190 rp = risc->cpu;
191 rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
192
193 /* save pointer to jmp instruction address */
194 risc->jmp = rp;
4a287cfe 195 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
1da177e4
LT
196 return 0;
197}
198
199int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
200 u32 reg, u32 mask, u32 value)
201{
202 u32 *rp;
203 int rc;
204
205 if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
206 return rc;
207
208 /* write risc instructions */
209 rp = risc->cpu;
210 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2 | RISC_IMM);
211 *(rp++) = cpu_to_le32(reg);
212 *(rp++) = cpu_to_le32(value);
213 *(rp++) = cpu_to_le32(mask);
214 *(rp++) = cpu_to_le32(RISC_JUMP);
215 *(rp++) = cpu_to_le32(risc->dma);
216 return 0;
217}
218
219void
c7b0ac05 220cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
1da177e4 221{
ae24601b 222 BUG_ON(in_interrupt());
1da177e4 223 videobuf_waiton(&buf->vb,0,0);
c7b0ac05 224 videobuf_dma_unmap(q, &buf->vb.dma);
1da177e4 225 videobuf_dma_free(&buf->vb.dma);
c7b0ac05 226 btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
1da177e4
LT
227 buf->vb.state = STATE_NEEDS_INIT;
228}
229
230/* ------------------------------------------------------------------ */
231/* our SRAM memory layout */
232
233/* we are going to put all thr risc programs into host memory, so we
234 * can use the whole SDRAM for the DMA fifos. To simplify things, we
235 * use a static memory layout. That surely will waste memory in case
236 * we don't use all DMA channels at the same time (which will be the
237 * case most of the time). But that still gives us enougth FIFO space
238 * to be able to deal with insane long pci latencies ...
239 *
240 * FIFO space allocations:
241 * channel 21 (y video) - 10.0k
242 * channel 22 (u video) - 2.0k
243 * channel 23 (v video) - 2.0k
244 * channel 24 (vbi) - 4.0k
b7f355d2 245 * channels 25+26 (audio) - 4.0k
1da177e4 246 * channel 28 (mpeg) - 4.0k
b7f355d2 247 * TOTAL = 29.0k
1da177e4
LT
248 *
249 * Every channel has 160 bytes control data (64 bytes instruction
250 * queue and 6 CDT entries), which is close to 2k total.
251 *
252 * Address layout:
253 * 0x0000 - 0x03ff CMDs / reserved
254 * 0x0400 - 0x0bff instruction queues + CDs
255 * 0x0c00 - FIFOs
256 */
257
258struct sram_channel cx88_sram_channels[] = {
259 [SRAM_CH21] = {
260 .name = "video y / packed",
261 .cmds_start = 0x180040,
262 .ctrl_start = 0x180400,
4ac97914 263 .cdt = 0x180400 + 64,
1da177e4
LT
264 .fifo_start = 0x180c00,
265 .fifo_size = 0x002800,
266 .ptr1_reg = MO_DMA21_PTR1,
267 .ptr2_reg = MO_DMA21_PTR2,
268 .cnt1_reg = MO_DMA21_CNT1,
269 .cnt2_reg = MO_DMA21_CNT2,
270 },
271 [SRAM_CH22] = {
272 .name = "video u",
273 .cmds_start = 0x180080,
274 .ctrl_start = 0x1804a0,
4ac97914 275 .cdt = 0x1804a0 + 64,
1da177e4
LT
276 .fifo_start = 0x183400,
277 .fifo_size = 0x000800,
278 .ptr1_reg = MO_DMA22_PTR1,
279 .ptr2_reg = MO_DMA22_PTR2,
280 .cnt1_reg = MO_DMA22_CNT1,
281 .cnt2_reg = MO_DMA22_CNT2,
282 },
283 [SRAM_CH23] = {
284 .name = "video v",
285 .cmds_start = 0x1800c0,
286 .ctrl_start = 0x180540,
4ac97914 287 .cdt = 0x180540 + 64,
1da177e4
LT
288 .fifo_start = 0x183c00,
289 .fifo_size = 0x000800,
290 .ptr1_reg = MO_DMA23_PTR1,
291 .ptr2_reg = MO_DMA23_PTR2,
292 .cnt1_reg = MO_DMA23_CNT1,
293 .cnt2_reg = MO_DMA23_CNT2,
294 },
295 [SRAM_CH24] = {
296 .name = "vbi",
297 .cmds_start = 0x180100,
298 .ctrl_start = 0x1805e0,
4ac97914 299 .cdt = 0x1805e0 + 64,
1da177e4
LT
300 .fifo_start = 0x184400,
301 .fifo_size = 0x001000,
302 .ptr1_reg = MO_DMA24_PTR1,
303 .ptr2_reg = MO_DMA24_PTR2,
304 .cnt1_reg = MO_DMA24_CNT1,
305 .cnt2_reg = MO_DMA24_CNT2,
306 },
307 [SRAM_CH25] = {
308 .name = "audio from",
309 .cmds_start = 0x180140,
310 .ctrl_start = 0x180680,
4ac97914 311 .cdt = 0x180680 + 64,
1da177e4 312 .fifo_start = 0x185400,
b7f355d2 313 .fifo_size = 0x001000,
1da177e4
LT
314 .ptr1_reg = MO_DMA25_PTR1,
315 .ptr2_reg = MO_DMA25_PTR2,
316 .cnt1_reg = MO_DMA25_CNT1,
317 .cnt2_reg = MO_DMA25_CNT2,
318 },
319 [SRAM_CH26] = {
320 .name = "audio to",
321 .cmds_start = 0x180180,
322 .ctrl_start = 0x180720,
4ac97914 323 .cdt = 0x180680 + 64, /* same as audio IN */
1da177e4 324 .fifo_start = 0x185400, /* same as audio IN */
b7f355d2 325 .fifo_size = 0x001000, /* same as audio IN */
1da177e4
LT
326 .ptr1_reg = MO_DMA26_PTR1,
327 .ptr2_reg = MO_DMA26_PTR2,
328 .cnt1_reg = MO_DMA26_CNT1,
329 .cnt2_reg = MO_DMA26_CNT2,
330 },
331 [SRAM_CH28] = {
332 .name = "mpeg",
333 .cmds_start = 0x180200,
334 .ctrl_start = 0x1807C0,
335 .cdt = 0x1807C0 + 64,
b7f355d2 336 .fifo_start = 0x186400,
1da177e4
LT
337 .fifo_size = 0x001000,
338 .ptr1_reg = MO_DMA28_PTR1,
339 .ptr2_reg = MO_DMA28_PTR2,
340 .cnt1_reg = MO_DMA28_CNT1,
341 .cnt2_reg = MO_DMA28_CNT2,
342 },
343};
344
345int cx88_sram_channel_setup(struct cx88_core *core,
346 struct sram_channel *ch,
347 unsigned int bpl, u32 risc)
348{
349 unsigned int i,lines;
350 u32 cdt;
351
352 bpl = (bpl + 7) & ~7; /* alignment */
353 cdt = ch->cdt;
354 lines = ch->fifo_size / bpl;
355 if (lines > 6)
356 lines = 6;
357 BUG_ON(lines < 2);
358
359 /* write CDT */
360 for (i = 0; i < lines; i++)
361 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
362
363 /* write CMDS */
364 cx_write(ch->cmds_start + 0, risc);
365 cx_write(ch->cmds_start + 4, cdt);
366 cx_write(ch->cmds_start + 8, (lines*16) >> 3);
367 cx_write(ch->cmds_start + 12, ch->ctrl_start);
368 cx_write(ch->cmds_start + 16, 64 >> 2);
369 for (i = 20; i < 64; i += 4)
370 cx_write(ch->cmds_start + i, 0);
371
372 /* fill registers */
373 cx_write(ch->ptr1_reg, ch->fifo_start);
374 cx_write(ch->ptr2_reg, cdt);
375 cx_write(ch->cnt1_reg, (bpl >> 3) -1);
376 cx_write(ch->cnt2_reg, (lines*16) >> 3);
377
378 dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
379 return 0;
380}
381
382/* ------------------------------------------------------------------ */
383/* debug helper code */
384
f9e7a020 385static int cx88_risc_decode(u32 risc)
1da177e4
LT
386{
387 static char *instr[16] = {
388 [ RISC_SYNC >> 28 ] = "sync",
389 [ RISC_WRITE >> 28 ] = "write",
390 [ RISC_WRITEC >> 28 ] = "writec",
391 [ RISC_READ >> 28 ] = "read",
392 [ RISC_READC >> 28 ] = "readc",
393 [ RISC_JUMP >> 28 ] = "jump",
394 [ RISC_SKIP >> 28 ] = "skip",
395 [ RISC_WRITERM >> 28 ] = "writerm",
396 [ RISC_WRITECM >> 28 ] = "writecm",
397 [ RISC_WRITECR >> 28 ] = "writecr",
398 };
399 static int incr[16] = {
400 [ RISC_WRITE >> 28 ] = 2,
401 [ RISC_JUMP >> 28 ] = 2,
402 [ RISC_WRITERM >> 28 ] = 3,
403 [ RISC_WRITECM >> 28 ] = 3,
404 [ RISC_WRITECR >> 28 ] = 4,
405 };
406 static char *bits[] = {
407 "12", "13", "14", "resync",
408 "cnt0", "cnt1", "18", "19",
409 "20", "21", "22", "23",
410 "irq1", "irq2", "eol", "sol",
411 };
412 int i;
413
414 printk("0x%08x [ %s", risc,
415 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
416 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
417 if (risc & (1 << (i + 12)))
418 printk(" %s",bits[i]);
419 printk(" count=%d ]\n", risc & 0xfff);
420 return incr[risc >> 28] ? incr[risc >> 28] : 1;
421}
422
1da177e4
LT
423
424void cx88_sram_channel_dump(struct cx88_core *core,
425 struct sram_channel *ch)
426{
427 static char *name[] = {
428 "initial risc",
429 "cdt base",
430 "cdt size",
431 "iq base",
432 "iq size",
433 "risc pc",
434 "iq wr ptr",
435 "iq rd ptr",
436 "cdt current",
437 "pci target",
438 "line / byte",
439 };
440 u32 risc;
441 unsigned int i,j,n;
442
443 printk("%s: %s - dma channel status dump\n",
444 core->name,ch->name);
445 for (i = 0; i < ARRAY_SIZE(name); i++)
446 printk("%s: cmds: %-12s: 0x%08x\n",
447 core->name,name[i],
448 cx_read(ch->cmds_start + 4*i));
449 for (i = 0; i < 4; i++) {
450 risc = cx_read(ch->cmds_start + 4 * (i+11));
451 printk("%s: risc%d: ", core->name, i);
452 cx88_risc_decode(risc);
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,
487 u32 bits, u32 mask)
488{
489 unsigned int i;
490
491 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
492 for (i = 0; i < 32; i++) {
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
512 if (status & (1<<18)) {
513 cx88_ir_irq(core);
514 handled++;
515 }
516 if (!handled)
517 cx88_print_irqbits(core->name, "irq pci",
518 cx88_pci_irqs, status,
519 core->pci_irqmask);
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);
542 buf->vb.state = STATE_DONE;
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)
552 printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
553}
554
555void cx88_shutdown(struct cx88_core *core)
556{
557 /* disable RISC controller + IRQs */
558 cx_write(MO_DEV_CNTRL2, 0);
559
560 /* stop dma transfers */
561 cx_write(MO_VID_DMACNTRL, 0x0);
562 cx_write(MO_AUD_DMACNTRL, 0x0);
563 cx_write(MO_TS_DMACNTRL, 0x0);
564 cx_write(MO_VIP_DMACNTRL, 0x0);
565 cx_write(MO_GPHST_DMACNTRL, 0x0);
566
567 /* stop interrupts */
568 cx_write(MO_PCI_INTMSK, 0x0);
569 cx_write(MO_VID_INTMSK, 0x0);
570 cx_write(MO_AUD_INTMSK, 0x0);
571 cx_write(MO_TS_INTMSK, 0x0);
572 cx_write(MO_VIP_INTMSK, 0x0);
573 cx_write(MO_GPHST_INTMSK, 0x0);
574
575 /* stop capturing */
576 cx_write(VID_CAPTURE_CONTROL, 0);
577}
578
579int cx88_reset(struct cx88_core *core)
580{
581 dprintk(1,"%s\n",__FUNCTION__);
582 cx88_shutdown(core);
583
584 /* clear irq status */
585 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
586 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
587 cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
588
589 /* wait a bit */
590 msleep(100);
591
592 /* init sram */
593 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);
594 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
595 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
596 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
597 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
598 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
599 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
600
601 /* misc init ... */
602 cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable
603 (1 << 12) | // agc gain
604 (1 << 11) | // adaptibe agc
605 (0 << 10) | // chroma agc
606 (0 << 9) | // ckillen
607 (7)));
608
609 /* setup image format */
610 cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
611
612 /* setup FIFO Threshholds */
613 cx_write(MO_PDMA_STHRSH, 0x0807);
614 cx_write(MO_PDMA_DTHRSH, 0x0807);
615
616 /* fixes flashing of image */
617 cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
618 cx_write(MO_AGC_BACK_VBI, 0x00E00555);
619
620 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
621 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
622 cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
623
624 /* Reset on-board parts */
625 cx_write(MO_SRST_IO, 0);
626 msleep(10);
627 cx_write(MO_SRST_IO, 1);
628
629 return 0;
630}
631
632/* ------------------------------------------------------------------ */
633
634static unsigned int inline norm_swidth(struct cx88_tvnorm *norm)
635{
636 return (norm->id & V4L2_STD_625_50) ? 922 : 754;
637}
638
639static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm)
640{
641 return (norm->id & V4L2_STD_625_50) ? 186 : 135;
642}
643
644static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
645{
646 return (norm->id & V4L2_STD_625_50) ? 0x24 : 0x18;
647}
648
649static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
650{
651 static const unsigned int ntsc = 28636360;
652 static const unsigned int pal = 35468950;
59dcd948
MCC
653 static const unsigned int palm = 28604892;
654
655 if (norm->id & V4L2_STD_PAL_M)
656 return palm;
1da177e4
LT
657
658 return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
659}
660
661static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
662{
4f43ac0c 663 return HLNotchFilter4xFsc;
1da177e4
LT
664}
665
666static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
667{
59dcd948
MCC
668 /* Should always be Line Draw Time / (4*FSC) */
669
670 if (norm->id & V4L2_STD_PAL_M)
671 return 909;
672
1da177e4
LT
673 return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
674}
675
676static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
677{
419ac5d4 678 return (norm->id & V4L2_STD_625_50) ? 511 : 400;
1da177e4
LT
679}
680
681int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
682 enum v4l2_field field)
683{
684 unsigned int swidth = norm_swidth(core->tvnorm);
685 unsigned int sheight = norm_maxh(core->tvnorm);
686 u32 value;
687
688 dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
689 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
690 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
691 core->tvnorm->name);
692 if (!V4L2_FIELD_HAS_BOTH(field))
693 height *= 2;
694
695 // recalc H delay and scale registers
696 value = (width * norm_hdelay(core->tvnorm)) / swidth;
697 value &= 0x3fe;
698 cx_write(MO_HDELAY_EVEN, value);
699 cx_write(MO_HDELAY_ODD, value);
700 dprintk(1,"set_scale: hdelay 0x%04x\n", value);
701
702 value = (swidth * 4096 / width) - 4096;
703 cx_write(MO_HSCALE_EVEN, value);
704 cx_write(MO_HSCALE_ODD, value);
705 dprintk(1,"set_scale: hscale 0x%04x\n", value);
706
707 cx_write(MO_HACTIVE_EVEN, width);
708 cx_write(MO_HACTIVE_ODD, width);
709 dprintk(1,"set_scale: hactive 0x%04x\n", width);
710
711 // recalc V scale Register (delay is constant)
712 cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
713 cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
714 dprintk(1,"set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
715
716 value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
717 cx_write(MO_VSCALE_EVEN, value);
718 cx_write(MO_VSCALE_ODD, value);
719 dprintk(1,"set_scale: vscale 0x%04x\n", value);
720
721 cx_write(MO_VACTIVE_EVEN, sheight);
722 cx_write(MO_VACTIVE_ODD, sheight);
723 dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
724
725 // setup filters
726 value = 0;
727 value |= (1 << 19); // CFILT (default)
728 if (core->tvnorm->id & V4L2_STD_SECAM) {
729 value |= (1 << 15);
730 value |= (1 << 16);
731 }
732 if (INPUT(core->input)->type == CX88_VMUX_SVIDEO)
733 value |= (1 << 13) | (1 << 5);
734 if (V4L2_FIELD_INTERLACED == field)
735 value |= (1 << 3); // VINT (interlaced vertical scaling)
736 if (width < 385)
737 value |= (1 << 0); // 3-tap interpolation
738 if (width < 193)
739 value |= (1 << 1); // 5-tap interpolation
740 if (nocomb)
741 value |= (3 << 5); // disable comb filter
742
743 cx_write(MO_FILTER_EVEN, value);
744 cx_write(MO_FILTER_ODD, value);
745 dprintk(1,"set_scale: filter 0x%04x\n", value);
746
747 return 0;
748}
749
750static const u32 xtal = 28636363;
751
752static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
753{
754 static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
755 u64 pll;
756 u32 reg;
757 int i;
758
759 if (prescale < 2)
760 prescale = 2;
761 if (prescale > 5)
762 prescale = 5;
763
764 pll = ofreq * 8 * prescale * (u64)(1 << 20);
765 do_div(pll,xtal);
766 reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
767 if (((reg >> 20) & 0x3f) < 14) {
768 printk("%s/0: pll out of range\n",core->name);
769 return -1;
770 }
771
772 dprintk(1,"set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
773 reg, cx_read(MO_PLL_REG), ofreq);
774 cx_write(MO_PLL_REG, reg);
775 for (i = 0; i < 100; i++) {
776 reg = cx_read(MO_DEVICE_STATUS);
777 if (reg & (1<<2)) {
778 dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
779 prescale,ofreq);
780 return 0;
781 }
782 dprintk(1,"pll not locked yet, waiting ...\n");
783 msleep(10);
784 }
785 dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
786 return -1;
787}
788
6f502b8a
MCC
789int cx88_start_audio_dma(struct cx88_core *core)
790{
17801f5f
MR
791 /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
792 int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
e738e35d
RC
793
794 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
795 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
796 return 0;
797
6f502b8a 798 /* setup fifo + format */
17801f5f
MR
799 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
800 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
6f502b8a 801
17801f5f
MR
802 cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
803 cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
6f502b8a
MCC
804
805 /* start dma */
806 cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
e738e35d 807
6f502b8a
MCC
808 return 0;
809}
810
811int cx88_stop_audio_dma(struct cx88_core *core)
812{
e738e35d
RC
813 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
814 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
815 return 0;
816
6f502b8a
MCC
817 /* stop dma */
818 cx_write(MO_AUD_DMACNTRL, 0x0000);
819
820 return 0;
821}
822
1da177e4
LT
823static int set_tvaudio(struct cx88_core *core)
824{
825 struct cx88_tvnorm *norm = core->tvnorm;
826
827 if (CX88_VMUX_TELEVISION != INPUT(core->input)->type)
828 return 0;
829
830 if (V4L2_STD_PAL_BG & norm->id) {
b1706b91 831 core->tvaudio = WW_BG;
1da177e4
LT
832
833 } else if (V4L2_STD_PAL_DK & norm->id) {
b1706b91 834 core->tvaudio = WW_DK;
1da177e4
LT
835
836 } else if (V4L2_STD_PAL_I & norm->id) {
b1706b91 837 core->tvaudio = WW_I;
1da177e4
LT
838
839 } else if (V4L2_STD_SECAM_L & norm->id) {
b1706b91 840 core->tvaudio = WW_L;
1da177e4
LT
841
842 } else if (V4L2_STD_SECAM_DK & norm->id) {
b1706b91 843 core->tvaudio = WW_DK;
1da177e4
LT
844
845 } else if ((V4L2_STD_NTSC_M & norm->id) ||
846 (V4L2_STD_PAL_M & norm->id)) {
847 core->tvaudio = WW_BTSC;
848
849 } else if (V4L2_STD_NTSC_M_JP & norm->id) {
850 core->tvaudio = WW_EIAJ;
851
852 } else {
853 printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
854 core->name, norm->name);
855 core->tvaudio = 0;
856 return 0;
857 }
858
859 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
860 cx88_set_tvaudio(core);
e52e98a7 861 /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
1da177e4 862
6f502b8a
MCC
863/*
864 This should be needed only on cx88-alsa. It seems that some cx88 chips have
865 bugs and does require DMA enabled for it to work.
866 */
867 cx88_start_audio_dma(core);
1da177e4
LT
868 return 0;
869}
870
6f502b8a
MCC
871
872
1da177e4
LT
873int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
874{
875 u32 fsc8;
876 u32 adc_clock;
877 u32 vdec_clock;
878 u32 step_db,step_dr;
879 u64 tmp64;
880 u32 bdelay,agcdelay,htotal;
881
882 core->tvnorm = norm;
883 fsc8 = norm_fsc8(norm);
884 adc_clock = xtal;
885 vdec_clock = fsc8;
886 step_db = fsc8;
887 step_dr = fsc8;
888
889 if (norm->id & V4L2_STD_SECAM) {
890 step_db = 4250000 * 8;
891 step_dr = 4406250 * 8;
892 }
893
894 dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
895 norm->name, fsc8, adc_clock, vdec_clock, step_db, step_dr);
896 set_pll(core,2,vdec_clock);
897
898 dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
899 norm->cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
900 cx_andor(MO_INPUT_FORMAT, 0xf, norm->cxiformat);
901
1da177e4
LT
902 // FIXME: as-is from DScaler
903 dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
904 norm->cxoformat, cx_read(MO_OUTPUT_FORMAT));
905 cx_write(MO_OUTPUT_FORMAT, norm->cxoformat);
1da177e4
LT
906
907 // MO_SCONV_REG = adc clock / video dec clock * 2^17
908 tmp64 = adc_clock * (u64)(1 << 17);
909 do_div(tmp64, vdec_clock);
910 dprintk(1,"set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
911 (u32)tmp64, cx_read(MO_SCONV_REG));
912 cx_write(MO_SCONV_REG, (u32)tmp64);
913
914 // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
915 tmp64 = step_db * (u64)(1 << 22);
916 do_div(tmp64, vdec_clock);
917 dprintk(1,"set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
918 (u32)tmp64, cx_read(MO_SUB_STEP));
919 cx_write(MO_SUB_STEP, (u32)tmp64);
920
921 // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
922 tmp64 = step_dr * (u64)(1 << 22);
923 do_div(tmp64, vdec_clock);
924 dprintk(1,"set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
925 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
926 cx_write(MO_SUB_STEP_DR, (u32)tmp64);
927
928 // bdelay + agcdelay
929 bdelay = vdec_clock * 65 / 20000000 + 21;
930 agcdelay = vdec_clock * 68 / 20000000 + 15;
931 dprintk(1,"set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
932 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
933 cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
934
935 // htotal
936 tmp64 = norm_htotal(norm) * (u64)vdec_clock;
937 do_div(tmp64, fsc8);
938 htotal = (u32)tmp64 | (norm_notchfilter(norm) << 11);
939 dprintk(1,"set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
940 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
941 cx_write(MO_HTOTAL, htotal);
942
3eb73170
TP
943 // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
944 // the effective vbi offset ~244 samples, the same as the Bt8x8
945 cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
1da177e4
LT
946
947 // this is needed as well to set all tvnorm parameter
948 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
949
950 // audio
951 set_tvaudio(core);
952
953 // tell i2c chips
1da177e4 954 cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
1da177e4
LT
955
956 // done
957 return 0;
958}
959
960/* ------------------------------------------------------------------ */
961
962static int cx88_pci_quirks(char *name, struct pci_dev *pci)
963{
964 unsigned int lat = UNSET;
965 u8 ctrl = 0;
966 u8 value;
967
968 /* check pci quirks */
969 if (pci_pci_problems & PCIPCI_TRITON) {
970 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
971 name);
972 ctrl |= CX88X_EN_TBFX;
973 }
974 if (pci_pci_problems & PCIPCI_NATOMA) {
975 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
976 name);
977 ctrl |= CX88X_EN_TBFX;
978 }
979 if (pci_pci_problems & PCIPCI_VIAETBF) {
980 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
981 name);
982 ctrl |= CX88X_EN_TBFX;
983 }
984 if (pci_pci_problems & PCIPCI_VSFX) {
985 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
986 name);
987 ctrl |= CX88X_EN_VSFX;
988 }
989#ifdef PCIPCI_ALIMAGIK
990 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
991 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
992 name);
993 lat = 0x0A;
994 }
995#endif
996
997 /* check insmod options */
998 if (UNSET != latency)
999 lat = latency;
1000
1001 /* apply stuff */
1002 if (ctrl) {
1003 pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
1004 value |= ctrl;
1005 pci_write_config_byte(pci, CX88X_DEVCTRL, value);
1006 }
1007 if (UNSET != lat) {
1008 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
1009 name, latency);
1010 pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
1011 }
1012 return 0;
1013}
1014
1015/* ------------------------------------------------------------------ */
1016
1017struct video_device *cx88_vdev_init(struct cx88_core *core,
1018 struct pci_dev *pci,
1019 struct video_device *template,
1020 char *type)
1021{
1022 struct video_device *vfd;
1023
1024 vfd = video_device_alloc();
1025 if (NULL == vfd)
1026 return NULL;
1027 *vfd = *template;
1028 vfd->minor = -1;
1029 vfd->dev = &pci->dev;
1030 vfd->release = video_device_release;
1031 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1032 core->name, type, cx88_boards[core->board].name);
1033 return vfd;
1034}
1035
1036static int get_ressources(struct cx88_core *core, struct pci_dev *pci)
1037{
1038 if (request_mem_region(pci_resource_start(pci,0),
1039 pci_resource_len(pci,0),
1040 core->name))
1041 return 0;
228aef63
GKH
1042 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
1043 core->name,(unsigned long long)pci_resource_start(pci,0));
1da177e4
LT
1044 return -EBUSY;
1045}
1046
1047struct cx88_core* cx88_core_get(struct pci_dev *pci)
1048{
1049 struct cx88_core *core;
1050 struct list_head *item;
1051 int i;
1052
1e4baed3 1053 mutex_lock(&devlist);
1da177e4
LT
1054 list_for_each(item,&cx88_devlist) {
1055 core = list_entry(item, struct cx88_core, devlist);
1056 if (pci->bus->number != core->pci_bus)
1057 continue;
1058 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1059 continue;
1060
1061 if (0 != get_ressources(core,pci))
1062 goto fail_unlock;
1063 atomic_inc(&core->refcount);
1e4baed3 1064 mutex_unlock(&devlist);
1da177e4
LT
1065 return core;
1066 }
7408187d 1067 core = kzalloc(sizeof(*core),GFP_KERNEL);
1da177e4
LT
1068 if (NULL == core)
1069 goto fail_unlock;
1070
1da177e4
LT
1071 atomic_inc(&core->refcount);
1072 core->pci_bus = pci->bus->number;
1073 core->pci_slot = PCI_SLOT(pci->devfn);
1074 core->pci_irqmask = 0x00fc00;
3593cab5 1075 mutex_init(&core->lock);
1da177e4
LT
1076
1077 core->nr = cx88_devcount++;
1078 sprintf(core->name,"cx88[%d]",core->nr);
1079 if (0 != get_ressources(core,pci)) {
e52e98a7
MCC
1080 printk(KERN_ERR "CORE %s No more PCI ressources for "
1081 "subsystem: %04x:%04x, board: %s\n",
1082 core->name,pci->subsystem_vendor,
1083 pci->subsystem_device,
1084 cx88_boards[core->board].name);
1085
1da177e4
LT
1086 cx88_devcount--;
1087 goto fail_free;
1088 }
1089 list_add_tail(&core->devlist,&cx88_devlist);
1090
1091 /* PCI stuff */
1092 cx88_pci_quirks(core->name, pci);
1093 core->lmmio = ioremap(pci_resource_start(pci,0),
1094 pci_resource_len(pci,0));
1095 core->bmmio = (u8 __iomem *)core->lmmio;
1096
1097 /* board config */
1098 core->board = UNSET;
1099 if (card[core->nr] < cx88_bcount)
1100 core->board = card[core->nr];
1101 for (i = 0; UNSET == core->board && i < cx88_idcount; i++)
1102 if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
1103 pci->subsystem_device == cx88_subids[i].subdevice)
1104 core->board = cx88_subids[i].card;
1105 if (UNSET == core->board) {
1106 core->board = CX88_BOARD_UNKNOWN;
1107 cx88_card_list(core,pci);
1108 }
e52e98a7
MCC
1109 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1110 core->name,pci->subsystem_vendor,
1111 pci->subsystem_device,cx88_boards[core->board].name,
1112 core->board, card[core->nr] == core->board ?
1113 "insmod option" : "autodetected");
1da177e4
LT
1114
1115 core->tuner_type = tuner[core->nr];
b45009b0 1116 core->radio_type = radio[core->nr];
1da177e4
LT
1117 if (UNSET == core->tuner_type)
1118 core->tuner_type = cx88_boards[core->board].tuner_type;
b45009b0
MCC
1119 if (UNSET == core->radio_type)
1120 core->radio_type = cx88_boards[core->board].radio_type;
1121 if (!core->tuner_addr)
1122 core->tuner_addr = cx88_boards[core->board].tuner_addr;
1123 if (!core->radio_addr)
1124 core->radio_addr = cx88_boards[core->board].radio_addr;
1125
4ac97914 1126 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
b45009b0
MCC
1127 core->tuner_type, core->tuner_addr<<1,
1128 core->radio_type, core->radio_addr<<1);
1129
1da177e4
LT
1130 core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
1131
1132 /* init hardware */
1133 cx88_reset(core);
aa481a65 1134 cx88_card_setup_pre_i2c(core);
1da177e4 1135 cx88_i2c_init(core,pci);
87f07831 1136 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
1da177e4
LT
1137 cx88_card_setup(core);
1138 cx88_ir_init(core,pci);
1139
1e4baed3 1140 mutex_unlock(&devlist);
1da177e4
LT
1141 return core;
1142
1143fail_free:
1144 kfree(core);
1145fail_unlock:
1e4baed3 1146 mutex_unlock(&devlist);
1da177e4
LT
1147 return NULL;
1148}
1149
1150void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1151{
1152 release_mem_region(pci_resource_start(pci,0),
1153 pci_resource_len(pci,0));
1154
1155 if (!atomic_dec_and_test(&core->refcount))
1156 return;
1157
1e4baed3 1158 mutex_lock(&devlist);
1da177e4
LT
1159 cx88_ir_fini(core);
1160 if (0 == core->i2c_rc)
1161 i2c_bit_del_bus(&core->i2c_adap);
1162 list_del(&core->devlist);
1163 iounmap(core->lmmio);
1164 cx88_devcount--;
1e4baed3 1165 mutex_unlock(&devlist);
1da177e4
LT
1166 kfree(core);
1167}
1168
1169/* ------------------------------------------------------------------ */
1170
1da177e4
LT
1171EXPORT_SYMBOL(cx88_print_irqbits);
1172
1173EXPORT_SYMBOL(cx88_core_irq);
1174EXPORT_SYMBOL(cx88_wakeup);
1175EXPORT_SYMBOL(cx88_reset);
1176EXPORT_SYMBOL(cx88_shutdown);
1177
1178EXPORT_SYMBOL(cx88_risc_buffer);
1179EXPORT_SYMBOL(cx88_risc_databuffer);
1180EXPORT_SYMBOL(cx88_risc_stopper);
1181EXPORT_SYMBOL(cx88_free_buffer);
1182
1183EXPORT_SYMBOL(cx88_sram_channels);
1184EXPORT_SYMBOL(cx88_sram_channel_setup);
1185EXPORT_SYMBOL(cx88_sram_channel_dump);
1186
1187EXPORT_SYMBOL(cx88_set_tvnorm);
1188EXPORT_SYMBOL(cx88_set_scale);
1189
1190EXPORT_SYMBOL(cx88_vdev_init);
1191EXPORT_SYMBOL(cx88_core_get);
1192EXPORT_SYMBOL(cx88_core_put);
1193
1194/*
1195 * Local variables:
1196 * c-basic-offset: 8
1197 * End:
e52e98a7 1198 * 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 1199 */
This page took 0.340688 seconds and 5 git commands to generate.