Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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