ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / media / video / cx88 / cx88-vbi.c
1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/init.h>
4 #include <linux/slab.h>
5
6 #include "cx88.h"
7
8 static unsigned int vbibufs = 4;
9 MODULE_PARM(vbibufs,"i");
10 MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
11
12 static unsigned int vbi_debug = 0;
13 MODULE_PARM(vbi_debug,"i");
14 MODULE_PARM_DESC(vbi_debug,"enable debug messages [video]");
15
16 #define dprintk(level,fmt, arg...)      if (vbi_debug >= level) \
17         printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg)
18
19 /* ------------------------------------------------------------------ */
20
21 void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f)
22 {
23         memset(&f->fmt.vbi,0,sizeof(f->fmt.vbi));
24
25         f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
26         f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
27         f->fmt.vbi.offset = 244;
28         f->fmt.vbi.count[0] = VBI_LINE_COUNT;
29         f->fmt.vbi.count[1] = VBI_LINE_COUNT;
30
31         switch (dev->tvnorm->id) {
32         case V4L2_STD_NTSC_M:
33         case V4L2_STD_NTSC_M_JP:
34                 f->fmt.vbi.sampling_rate = 28636363;
35                 f->fmt.vbi.start[0] = 10 -1;
36                 f->fmt.vbi.start[1] = 273 -1;
37                 break;
38         case V4L2_STD_PAL_BG:
39         case V4L2_STD_PAL_DK:
40         case V4L2_STD_PAL_I:
41         case V4L2_STD_SECAM:
42                 f->fmt.vbi.sampling_rate = 35468950;
43                 f->fmt.vbi.start[0] = 7 -1;
44                 f->fmt.vbi.start[1] = 319 -1;
45         }
46 }
47
48 int cx8800_start_vbi_dma(struct cx8800_dev    *dev,
49                          struct cx88_dmaqueue *q,
50                          struct cx88_buffer   *buf)
51 {
52         /* setup fifo + format */
53         cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH24],
54                                 buf->vb.width, buf->risc.dma);
55
56         cx_write(MO_VBOS_CONTROL, ( (1 << 18) |  // comb filter delay fixup
57                                     (1 << 15) |  // enable vbi capture
58                                     (1 << 11) ));
59
60         /* reset counter */
61         cx_write(MO_VBI_GPCNTRL,0x3);
62         q->count = 1;
63
64         /* enable irqs */
65         cx_set(MO_PCI_INTMSK, 0x00fc01);
66         cx_set(MO_VID_INTMSK, 0x0f0088);
67
68         /* enable capture */
69         cx_set(VID_CAPTURE_CONTROL,0x18);
70
71         /* start dma */
72         cx_set(MO_DEV_CNTRL2, (1<<5));
73         cx_set(MO_VID_DMACNTRL, 0x88);
74
75         return 0;
76 }
77
78 int cx8800_restart_vbi_queue(struct cx8800_dev    *dev,
79                              struct cx88_dmaqueue *q)
80 {
81         struct cx88_buffer *buf;
82         struct list_head *item;
83
84         if (list_empty(&q->active))
85                 return 0;
86
87         buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
88         dprintk(2,"restart_queue [%p/%d]: restart dma\n",
89                 buf, buf->vb.i);
90         cx8800_start_vbi_dma(dev, q, buf);
91         list_for_each(item,&q->active) {
92                 buf = list_entry(item, struct cx88_buffer, vb.queue);
93                 buf->count = q->count++;
94         }
95         mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
96         return 0;
97 }
98
99 void cx8800_vbi_timeout(unsigned long data)
100 {
101         struct cx8800_dev *dev = (struct cx8800_dev*)data;
102         struct cx88_dmaqueue *q = &dev->vbiq;
103         struct cx88_buffer *buf;
104         unsigned long flags;
105
106         cx88_sram_channel_dump(dev, &cx88_sram_channels[SRAM_CH24]);
107
108         cx_clear(MO_VID_DMACNTRL, 0x88);
109         cx_clear(VID_CAPTURE_CONTROL, 0x18);
110
111         spin_lock_irqsave(&dev->slock,flags);
112         while (!list_empty(&q->active)) {
113                 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
114                 list_del(&buf->vb.queue);
115                 buf->vb.state = STATE_ERROR;
116                 wake_up(&buf->vb.done);
117                 printk("%s: [%p/%d] timeout - dma=0x%08lx\n", dev->name,
118                        buf, buf->vb.i, (unsigned long)buf->risc.dma);
119         }
120         cx8800_restart_vbi_queue(dev,q);
121         spin_unlock_irqrestore(&dev->slock,flags);
122 }
123
124 /* ------------------------------------------------------------------ */
125
126 static int
127 vbi_setup(struct file *file, unsigned int *count, unsigned int *size)
128 {
129         *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
130         if (0 == *count)
131                 *count = vbibufs;
132         if (*count < 2)
133                 *count = 2;
134         if (*count > 32)
135                 *count = 32;
136         return 0;
137 }
138
139 static int
140 vbi_prepare(struct file *file, struct videobuf_buffer *vb,
141             enum v4l2_field field)
142 {
143         struct cx8800_fh   *fh  = file->private_data;
144         struct cx8800_dev  *dev = fh->dev;
145         struct cx88_buffer *buf = (struct cx88_buffer*)vb;
146         unsigned int size;
147         int rc;
148
149         size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
150         if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
151                 return -EINVAL;
152
153         if (STATE_NEEDS_INIT == buf->vb.state) {
154                 buf->vb.width  = VBI_LINE_LENGTH;
155                 buf->vb.height = VBI_LINE_COUNT;
156                 buf->vb.size   = size;
157                 buf->vb.field  = V4L2_FIELD_SEQ_TB;
158
159                 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
160                         goto fail;
161                 cx88_risc_buffer(dev->pci, &buf->risc,
162                                  buf->vb.dma.sglist,
163                                  0, buf->vb.width * buf->vb.height,
164                                  buf->vb.width, 0,
165                                  buf->vb.height);
166         }
167         buf->vb.state = STATE_PREPARED;
168         return 0;
169
170  fail:
171         cx88_free_buffer(dev->pci,buf);
172         return rc;
173 }
174
175 static void
176 vbi_queue(struct file *file, struct videobuf_buffer *vb)
177 {
178         struct cx88_buffer    *buf  = (struct cx88_buffer*)vb;
179         struct cx88_buffer    *prev;
180         struct cx8800_fh      *fh   = file->private_data;
181         struct cx8800_dev     *dev  = fh->dev;
182         struct cx88_dmaqueue  *q    = &dev->vbiq;
183
184         /* add jump to stopper */
185         buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | 0x10000);
186         buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
187
188         if (list_empty(&q->active)) {
189                 list_add_tail(&buf->vb.queue,&q->active);
190                 cx8800_start_vbi_dma(dev, q, buf);
191                 buf->vb.state = STATE_ACTIVE;
192                 buf->count    = q->count++;
193                 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
194                 dprintk(2,"[%p/%d] vbi_queue - first active\n",
195                         buf, buf->vb.i);
196
197         } else {
198                 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
199                 list_add_tail(&buf->vb.queue,&q->active);
200                 buf->vb.state = STATE_ACTIVE;
201                 buf->count    = q->count++;
202                 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
203                 dprintk(2,"[%p/%d] buffer_queue - append to active\n",
204                         buf, buf->vb.i);
205         }
206 }
207
208 static void vbi_release(struct file *file, struct videobuf_buffer *vb)
209 {
210         struct cx88_buffer *buf = (struct cx88_buffer*)vb;
211         struct cx8800_fh   *fh  = file->private_data;
212
213         cx88_free_buffer(fh->dev->pci,buf);
214 }
215
216 struct videobuf_queue_ops cx8800_vbi_qops = {
217         .buf_setup    = vbi_setup,
218         .buf_prepare  = vbi_prepare,
219         .buf_queue    = vbi_queue,
220         .buf_release  = vbi_release,
221 };
222
223 /* ------------------------------------------------------------------ */
224 /*
225  * Local variables:
226  * c-basic-offset: 8
227  * End:
228  */