Merge ../linus
[deliverable/linux.git] / drivers / media / video / cx88 / cx88-core.c
1 /*
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>
34 #include <linux/videodev2.h>
35 #include <linux/mutex.h>
36
37 #include "cx88.h"
38 #include <media/v4l2-common.h>
39
40 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
41 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
42 MODULE_LICENSE("GPL");
43
44 /* ------------------------------------------------------------------ */
45
46 static unsigned int core_debug = 0;
47 module_param(core_debug,int,0644);
48 MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
49
50 static unsigned int latency = UNSET;
51 module_param(latency,int,0444);
52 MODULE_PARM_DESC(latency,"pci latency timer");
53
54 static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
55 static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
56 static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
57
58 module_param_array(tuner, int, NULL, 0444);
59 module_param_array(radio, int, NULL, 0444);
60 module_param_array(card, int, NULL, 0444);
61
62 MODULE_PARM_DESC(tuner,"tuner type");
63 MODULE_PARM_DESC(radio,"radio tuner type");
64 MODULE_PARM_DESC(card,"card type");
65
66 static unsigned int nicam = 0;
67 module_param(nicam,int,0644);
68 MODULE_PARM_DESC(nicam,"tv audio is nicam");
69
70 static unsigned int nocomb = 0;
71 module_param(nocomb,int,0644);
72 MODULE_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
77 static unsigned int cx88_devcount;
78 static LIST_HEAD(cx88_devlist);
79 static DEFINE_MUTEX(devlist);
80
81 #define NO_SYNC_LINE (-1U)
82
83 static 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 */
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;
107 } else {
108 /* scanline needs to be split */
109 todo = bpl;
110 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
111 (sg_dma_len(sg)-offset));
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)) {
117 *(rp++)=cpu_to_le32(RISC_WRITE|
118 sg_dma_len(sg));
119 *(rp++)=cpu_to_le32(sg_dma_address(sg));
120 todo -= sg_dma_len(sg);
121 sg++;
122 }
123 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
124 *(rp++)=cpu_to_le32(sg_dma_address(sg));
125 offset += todo;
126 }
127 offset += padding;
128 }
129
130 return rp;
131 }
132
133 int 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 +
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;
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;
168 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
169 return 0;
170 }
171
172 int 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 +
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;
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;
195 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
196 return 0;
197 }
198
199 int 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
219 void
220 cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
221 {
222 BUG_ON(in_interrupt());
223 videobuf_waiton(&buf->vb,0,0);
224 videobuf_dma_unmap(q, &buf->vb.dma);
225 videobuf_dma_free(&buf->vb.dma);
226 btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
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
245 * channels 25+26 (audio) - 4.0k
246 * channel 28 (mpeg) - 4.0k
247 * TOTAL = 29.0k
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
258 struct sram_channel cx88_sram_channels[] = {
259 [SRAM_CH21] = {
260 .name = "video y / packed",
261 .cmds_start = 0x180040,
262 .ctrl_start = 0x180400,
263 .cdt = 0x180400 + 64,
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,
275 .cdt = 0x1804a0 + 64,
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,
287 .cdt = 0x180540 + 64,
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,
299 .cdt = 0x1805e0 + 64,
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,
311 .cdt = 0x180680 + 64,
312 .fifo_start = 0x185400,
313 .fifo_size = 0x001000,
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,
323 .cdt = 0x180680 + 64, /* same as audio IN */
324 .fifo_start = 0x185400, /* same as audio IN */
325 .fifo_size = 0x001000, /* same as audio IN */
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,
336 .fifo_start = 0x186400,
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
345 int 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
385 static int cx88_risc_decode(u32 risc)
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
423
424 void 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
479 static char *cx88_pci_irqs[32] = {
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 };
485
486 void 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
508 int 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
523 void 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);
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;
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
555 void 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
579 int 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
634 static unsigned int inline norm_swidth(struct cx88_tvnorm *norm)
635 {
636 return (norm->id & V4L2_STD_625_50) ? 922 : 754;
637 }
638
639 static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm)
640 {
641 return (norm->id & V4L2_STD_625_50) ? 186 : 135;
642 }
643
644 static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
645 {
646 return (norm->id & V4L2_STD_625_50) ? 0x24 : 0x18;
647 }
648
649 static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
650 {
651 static const unsigned int ntsc = 28636360;
652 static const unsigned int pal = 35468950;
653 static const unsigned int palm = 28604892;
654
655 if (norm->id & V4L2_STD_PAL_M)
656 return palm;
657
658 return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
659 }
660
661 static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
662 {
663 /* Should always be Line Draw Time / (4*FSC) */
664
665 if (norm->id & V4L2_STD_PAL_M)
666 return 909;
667
668 return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
669 }
670
671 static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
672 {
673 return (norm->id & V4L2_STD_625_50) ? 511 : 400;
674 }
675
676 int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
677 enum v4l2_field field)
678 {
679 unsigned int swidth = norm_swidth(core->tvnorm);
680 unsigned int sheight = norm_maxh(core->tvnorm);
681 u32 value;
682
683 dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
684 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
685 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
686 core->tvnorm->name);
687 if (!V4L2_FIELD_HAS_BOTH(field))
688 height *= 2;
689
690 // recalc H delay and scale registers
691 value = (width * norm_hdelay(core->tvnorm)) / swidth;
692 value &= 0x3fe;
693 cx_write(MO_HDELAY_EVEN, value);
694 cx_write(MO_HDELAY_ODD, value);
695 dprintk(1,"set_scale: hdelay 0x%04x\n", value);
696
697 value = (swidth * 4096 / width) - 4096;
698 cx_write(MO_HSCALE_EVEN, value);
699 cx_write(MO_HSCALE_ODD, value);
700 dprintk(1,"set_scale: hscale 0x%04x\n", value);
701
702 cx_write(MO_HACTIVE_EVEN, width);
703 cx_write(MO_HACTIVE_ODD, width);
704 dprintk(1,"set_scale: hactive 0x%04x\n", width);
705
706 // recalc V scale Register (delay is constant)
707 cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
708 cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
709 dprintk(1,"set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
710
711 value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
712 cx_write(MO_VSCALE_EVEN, value);
713 cx_write(MO_VSCALE_ODD, value);
714 dprintk(1,"set_scale: vscale 0x%04x\n", value);
715
716 cx_write(MO_VACTIVE_EVEN, sheight);
717 cx_write(MO_VACTIVE_ODD, sheight);
718 dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
719
720 // setup filters
721 value = 0;
722 value |= (1 << 19); // CFILT (default)
723 if (core->tvnorm->id & V4L2_STD_SECAM) {
724 value |= (1 << 15);
725 value |= (1 << 16);
726 }
727 if (INPUT(core->input)->type == CX88_VMUX_SVIDEO)
728 value |= (1 << 13) | (1 << 5);
729 if (V4L2_FIELD_INTERLACED == field)
730 value |= (1 << 3); // VINT (interlaced vertical scaling)
731 if (width < 385)
732 value |= (1 << 0); // 3-tap interpolation
733 if (width < 193)
734 value |= (1 << 1); // 5-tap interpolation
735 if (nocomb)
736 value |= (3 << 5); // disable comb filter
737
738 cx_write(MO_FILTER_EVEN, value);
739 cx_write(MO_FILTER_ODD, value);
740 dprintk(1,"set_scale: filter 0x%04x\n", value);
741
742 return 0;
743 }
744
745 static const u32 xtal = 28636363;
746
747 static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
748 {
749 static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
750 u64 pll;
751 u32 reg;
752 int i;
753
754 if (prescale < 2)
755 prescale = 2;
756 if (prescale > 5)
757 prescale = 5;
758
759 pll = ofreq * 8 * prescale * (u64)(1 << 20);
760 do_div(pll,xtal);
761 reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
762 if (((reg >> 20) & 0x3f) < 14) {
763 printk("%s/0: pll out of range\n",core->name);
764 return -1;
765 }
766
767 dprintk(1,"set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
768 reg, cx_read(MO_PLL_REG), ofreq);
769 cx_write(MO_PLL_REG, reg);
770 for (i = 0; i < 100; i++) {
771 reg = cx_read(MO_DEVICE_STATUS);
772 if (reg & (1<<2)) {
773 dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
774 prescale,ofreq);
775 return 0;
776 }
777 dprintk(1,"pll not locked yet, waiting ...\n");
778 msleep(10);
779 }
780 dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
781 return -1;
782 }
783
784 int cx88_start_audio_dma(struct cx88_core *core)
785 {
786 /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
787 int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
788
789 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
790 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
791 return 0;
792
793 /* setup fifo + format */
794 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
795 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
796
797 cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
798 cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
799
800 /* start dma */
801 cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
802
803 return 0;
804 }
805
806 int cx88_stop_audio_dma(struct cx88_core *core)
807 {
808 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
809 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
810 return 0;
811
812 /* stop dma */
813 cx_write(MO_AUD_DMACNTRL, 0x0000);
814
815 return 0;
816 }
817
818 static int set_tvaudio(struct cx88_core *core)
819 {
820 struct cx88_tvnorm *norm = core->tvnorm;
821
822 if (CX88_VMUX_TELEVISION != INPUT(core->input)->type)
823 return 0;
824
825 if (V4L2_STD_PAL_BG & norm->id) {
826 core->tvaudio = WW_BG;
827
828 } else if (V4L2_STD_PAL_DK & norm->id) {
829 core->tvaudio = WW_DK;
830
831 } else if (V4L2_STD_PAL_I & norm->id) {
832 core->tvaudio = WW_I;
833
834 } else if (V4L2_STD_SECAM_L & norm->id) {
835 core->tvaudio = WW_L;
836
837 } else if (V4L2_STD_SECAM_DK & norm->id) {
838 core->tvaudio = WW_DK;
839
840 } else if ((V4L2_STD_NTSC_M & norm->id) ||
841 (V4L2_STD_PAL_M & norm->id)) {
842 core->tvaudio = WW_BTSC;
843
844 } else if (V4L2_STD_NTSC_M_JP & norm->id) {
845 core->tvaudio = WW_EIAJ;
846
847 } else {
848 printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
849 core->name, norm->name);
850 core->tvaudio = 0;
851 return 0;
852 }
853
854 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
855 cx88_set_tvaudio(core);
856 /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
857
858 /*
859 This should be needed only on cx88-alsa. It seems that some cx88 chips have
860 bugs and does require DMA enabled for it to work.
861 */
862 cx88_start_audio_dma(core);
863 return 0;
864 }
865
866
867
868 int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
869 {
870 u32 fsc8;
871 u32 adc_clock;
872 u32 vdec_clock;
873 u32 step_db,step_dr;
874 u64 tmp64;
875 u32 bdelay,agcdelay,htotal;
876
877 core->tvnorm = norm;
878 fsc8 = norm_fsc8(norm);
879 adc_clock = xtal;
880 vdec_clock = fsc8;
881 step_db = fsc8;
882 step_dr = fsc8;
883
884 if (norm->id & V4L2_STD_SECAM) {
885 step_db = 4250000 * 8;
886 step_dr = 4406250 * 8;
887 }
888
889 dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
890 norm->name, fsc8, adc_clock, vdec_clock, step_db, step_dr);
891 set_pll(core,2,vdec_clock);
892
893 dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
894 norm->cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
895 cx_andor(MO_INPUT_FORMAT, 0xf, norm->cxiformat);
896
897 // FIXME: as-is from DScaler
898 dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
899 norm->cxoformat, cx_read(MO_OUTPUT_FORMAT));
900 cx_write(MO_OUTPUT_FORMAT, norm->cxoformat);
901
902 // MO_SCONV_REG = adc clock / video dec clock * 2^17
903 tmp64 = adc_clock * (u64)(1 << 17);
904 do_div(tmp64, vdec_clock);
905 dprintk(1,"set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
906 (u32)tmp64, cx_read(MO_SCONV_REG));
907 cx_write(MO_SCONV_REG, (u32)tmp64);
908
909 // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
910 tmp64 = step_db * (u64)(1 << 22);
911 do_div(tmp64, vdec_clock);
912 dprintk(1,"set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
913 (u32)tmp64, cx_read(MO_SUB_STEP));
914 cx_write(MO_SUB_STEP, (u32)tmp64);
915
916 // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
917 tmp64 = step_dr * (u64)(1 << 22);
918 do_div(tmp64, vdec_clock);
919 dprintk(1,"set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
920 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
921 cx_write(MO_SUB_STEP_DR, (u32)tmp64);
922
923 // bdelay + agcdelay
924 bdelay = vdec_clock * 65 / 20000000 + 21;
925 agcdelay = vdec_clock * 68 / 20000000 + 15;
926 dprintk(1,"set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
927 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
928 cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
929
930 // htotal
931 tmp64 = norm_htotal(norm) * (u64)vdec_clock;
932 do_div(tmp64, fsc8);
933 htotal = (u32)tmp64 | (HLNotchFilter4xFsc << 11);
934 dprintk(1,"set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
935 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
936 cx_write(MO_HTOTAL, htotal);
937
938 // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
939 // the effective vbi offset ~244 samples, the same as the Bt8x8
940 cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
941
942 // this is needed as well to set all tvnorm parameter
943 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
944
945 // audio
946 set_tvaudio(core);
947
948 // tell i2c chips
949 cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
950
951 // done
952 return 0;
953 }
954
955 /* ------------------------------------------------------------------ */
956
957 static int cx88_pci_quirks(char *name, struct pci_dev *pci)
958 {
959 unsigned int lat = UNSET;
960 u8 ctrl = 0;
961 u8 value;
962
963 /* check pci quirks */
964 if (pci_pci_problems & PCIPCI_TRITON) {
965 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
966 name);
967 ctrl |= CX88X_EN_TBFX;
968 }
969 if (pci_pci_problems & PCIPCI_NATOMA) {
970 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
971 name);
972 ctrl |= CX88X_EN_TBFX;
973 }
974 if (pci_pci_problems & PCIPCI_VIAETBF) {
975 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
976 name);
977 ctrl |= CX88X_EN_TBFX;
978 }
979 if (pci_pci_problems & PCIPCI_VSFX) {
980 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
981 name);
982 ctrl |= CX88X_EN_VSFX;
983 }
984 #ifdef PCIPCI_ALIMAGIK
985 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
986 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
987 name);
988 lat = 0x0A;
989 }
990 #endif
991
992 /* check insmod options */
993 if (UNSET != latency)
994 lat = latency;
995
996 /* apply stuff */
997 if (ctrl) {
998 pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
999 value |= ctrl;
1000 pci_write_config_byte(pci, CX88X_DEVCTRL, value);
1001 }
1002 if (UNSET != lat) {
1003 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
1004 name, latency);
1005 pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
1006 }
1007 return 0;
1008 }
1009
1010 /* ------------------------------------------------------------------ */
1011
1012 struct video_device *cx88_vdev_init(struct cx88_core *core,
1013 struct pci_dev *pci,
1014 struct video_device *template,
1015 char *type)
1016 {
1017 struct video_device *vfd;
1018
1019 vfd = video_device_alloc();
1020 if (NULL == vfd)
1021 return NULL;
1022 *vfd = *template;
1023 vfd->minor = -1;
1024 vfd->dev = &pci->dev;
1025 vfd->release = video_device_release;
1026 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1027 core->name, type, cx88_boards[core->board].name);
1028 return vfd;
1029 }
1030
1031 static int get_ressources(struct cx88_core *core, struct pci_dev *pci)
1032 {
1033 if (request_mem_region(pci_resource_start(pci,0),
1034 pci_resource_len(pci,0),
1035 core->name))
1036 return 0;
1037 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
1038 core->name,(unsigned long long)pci_resource_start(pci,0));
1039 return -EBUSY;
1040 }
1041
1042 struct cx88_core* cx88_core_get(struct pci_dev *pci)
1043 {
1044 struct cx88_core *core;
1045 struct list_head *item;
1046 int i;
1047
1048 mutex_lock(&devlist);
1049 list_for_each(item,&cx88_devlist) {
1050 core = list_entry(item, struct cx88_core, devlist);
1051 if (pci->bus->number != core->pci_bus)
1052 continue;
1053 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1054 continue;
1055
1056 if (0 != get_ressources(core,pci))
1057 goto fail_unlock;
1058 atomic_inc(&core->refcount);
1059 mutex_unlock(&devlist);
1060 return core;
1061 }
1062 core = kzalloc(sizeof(*core),GFP_KERNEL);
1063 if (NULL == core)
1064 goto fail_unlock;
1065
1066 atomic_inc(&core->refcount);
1067 core->pci_bus = pci->bus->number;
1068 core->pci_slot = PCI_SLOT(pci->devfn);
1069 core->pci_irqmask = 0x00fc00;
1070 mutex_init(&core->lock);
1071
1072 core->nr = cx88_devcount++;
1073 sprintf(core->name,"cx88[%d]",core->nr);
1074 if (0 != get_ressources(core,pci)) {
1075 printk(KERN_ERR "CORE %s No more PCI ressources for "
1076 "subsystem: %04x:%04x, board: %s\n",
1077 core->name,pci->subsystem_vendor,
1078 pci->subsystem_device,
1079 cx88_boards[core->board].name);
1080
1081 cx88_devcount--;
1082 goto fail_free;
1083 }
1084 list_add_tail(&core->devlist,&cx88_devlist);
1085
1086 /* PCI stuff */
1087 cx88_pci_quirks(core->name, pci);
1088 core->lmmio = ioremap(pci_resource_start(pci,0),
1089 pci_resource_len(pci,0));
1090 core->bmmio = (u8 __iomem *)core->lmmio;
1091
1092 /* board config */
1093 core->board = UNSET;
1094 if (card[core->nr] < cx88_bcount)
1095 core->board = card[core->nr];
1096 for (i = 0; UNSET == core->board && i < cx88_idcount; i++)
1097 if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
1098 pci->subsystem_device == cx88_subids[i].subdevice)
1099 core->board = cx88_subids[i].card;
1100 if (UNSET == core->board) {
1101 core->board = CX88_BOARD_UNKNOWN;
1102 cx88_card_list(core,pci);
1103 }
1104 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1105 core->name,pci->subsystem_vendor,
1106 pci->subsystem_device,cx88_boards[core->board].name,
1107 core->board, card[core->nr] == core->board ?
1108 "insmod option" : "autodetected");
1109
1110 core->tuner_type = tuner[core->nr];
1111 core->radio_type = radio[core->nr];
1112 if (UNSET == core->tuner_type)
1113 core->tuner_type = cx88_boards[core->board].tuner_type;
1114 if (UNSET == core->radio_type)
1115 core->radio_type = cx88_boards[core->board].radio_type;
1116 if (!core->tuner_addr)
1117 core->tuner_addr = cx88_boards[core->board].tuner_addr;
1118 if (!core->radio_addr)
1119 core->radio_addr = cx88_boards[core->board].radio_addr;
1120
1121 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
1122 core->tuner_type, core->tuner_addr<<1,
1123 core->radio_type, core->radio_addr<<1);
1124
1125 core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
1126
1127 /* init hardware */
1128 cx88_reset(core);
1129 cx88_card_setup_pre_i2c(core);
1130 cx88_i2c_init(core,pci);
1131 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
1132 cx88_card_setup(core);
1133 cx88_ir_init(core,pci);
1134
1135 mutex_unlock(&devlist);
1136 return core;
1137
1138 fail_free:
1139 kfree(core);
1140 fail_unlock:
1141 mutex_unlock(&devlist);
1142 return NULL;
1143 }
1144
1145 void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1146 {
1147 release_mem_region(pci_resource_start(pci,0),
1148 pci_resource_len(pci,0));
1149
1150 if (!atomic_dec_and_test(&core->refcount))
1151 return;
1152
1153 mutex_lock(&devlist);
1154 cx88_ir_fini(core);
1155 if (0 == core->i2c_rc)
1156 i2c_del_adapter(&core->i2c_adap);
1157 list_del(&core->devlist);
1158 iounmap(core->lmmio);
1159 cx88_devcount--;
1160 mutex_unlock(&devlist);
1161 kfree(core);
1162 }
1163
1164 /* ------------------------------------------------------------------ */
1165
1166 EXPORT_SYMBOL(cx88_print_irqbits);
1167
1168 EXPORT_SYMBOL(cx88_core_irq);
1169 EXPORT_SYMBOL(cx88_wakeup);
1170 EXPORT_SYMBOL(cx88_reset);
1171 EXPORT_SYMBOL(cx88_shutdown);
1172
1173 EXPORT_SYMBOL(cx88_risc_buffer);
1174 EXPORT_SYMBOL(cx88_risc_databuffer);
1175 EXPORT_SYMBOL(cx88_risc_stopper);
1176 EXPORT_SYMBOL(cx88_free_buffer);
1177
1178 EXPORT_SYMBOL(cx88_sram_channels);
1179 EXPORT_SYMBOL(cx88_sram_channel_setup);
1180 EXPORT_SYMBOL(cx88_sram_channel_dump);
1181
1182 EXPORT_SYMBOL(cx88_set_tvnorm);
1183 EXPORT_SYMBOL(cx88_set_scale);
1184
1185 EXPORT_SYMBOL(cx88_vdev_init);
1186 EXPORT_SYMBOL(cx88_core_get);
1187 EXPORT_SYMBOL(cx88_core_put);
1188
1189 /*
1190 * Local variables:
1191 * c-basic-offset: 8
1192 * End:
1193 * 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
1194 */
This page took 0.058854 seconds and 6 git commands to generate.