Root/drivers/media/common/saa7146_vbi.c

1#include <media/saa7146_vv.h>
2
3static int vbi_pixel_to_capture = 720 * 2;
4
5static int vbi_workaround(struct saa7146_dev *dev)
6{
7    struct saa7146_vv *vv = dev->vv_data;
8
9    u32 *cpu;
10    dma_addr_t dma_addr;
11
12    int count = 0;
13    int i;
14
15    DECLARE_WAITQUEUE(wait, current);
16
17    DEB_VBI("dev:%p\n", dev);
18
19    /* once again, a bug in the saa7146: the brs acquisition
20       is buggy and especially the BXO-counter does not work
21       as specified. there is this workaround, but please
22       don't let me explain it. ;-) */
23
24    cpu = pci_alloc_consistent(dev->pci, 4096, &dma_addr);
25    if (NULL == cpu)
26        return -ENOMEM;
27
28    /* setup some basic programming, just for the workaround */
29    saa7146_write(dev, BASE_EVEN3, dma_addr);
30    saa7146_write(dev, BASE_ODD3, dma_addr+vbi_pixel_to_capture);
31    saa7146_write(dev, PROT_ADDR3, dma_addr+4096);
32    saa7146_write(dev, PITCH3, vbi_pixel_to_capture);
33    saa7146_write(dev, BASE_PAGE3, 0x0);
34    saa7146_write(dev, NUM_LINE_BYTE3, (2<<16)|((vbi_pixel_to_capture)<<0));
35    saa7146_write(dev, MC2, MASK_04|MASK_20);
36
37    /* load brs-control register */
38    WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
39    /* BXO = 1h, BRS to outbound */
40    WRITE_RPS1(0xc000008c);
41    /* wait for vbi_a or vbi_b*/
42    if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
43        DEB_D("...using port b\n");
44        WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_E_FID_B);
45        WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_O_FID_B);
46/*
47        WRITE_RPS1(CMD_PAUSE | MASK_09);
48*/
49    } else {
50        DEB_D("...using port a\n");
51        WRITE_RPS1(CMD_PAUSE | MASK_10);
52    }
53    /* upload brs */
54    WRITE_RPS1(CMD_UPLOAD | MASK_08);
55    /* load brs-control register */
56    WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
57    /* BYO = 1, BXO = NQBIL (=1728 for PAL, for NTSC this is 858*2) - NumByte3 (=1440) = 288 */
58    WRITE_RPS1(((1728-(vbi_pixel_to_capture)) << 7) | MASK_19);
59    /* wait for brs_done */
60    WRITE_RPS1(CMD_PAUSE | MASK_08);
61    /* upload brs */
62    WRITE_RPS1(CMD_UPLOAD | MASK_08);
63    /* load video-dma3 NumLines3 and NumBytes3 */
64    WRITE_RPS1(CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4));
65    /* dev->vbi_count*2 lines, 720 pixel (= 1440 Bytes) */
66    WRITE_RPS1((2 << 16) | (vbi_pixel_to_capture));
67    /* load brs-control register */
68    WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
69    /* Set BRS right: note: this is an experimental value for BXO (=> PAL!) */
70    WRITE_RPS1((540 << 7) | (5 << 19)); // 5 == vbi_start
71    /* wait for brs_done */
72    WRITE_RPS1(CMD_PAUSE | MASK_08);
73    /* upload brs and video-dma3*/
74    WRITE_RPS1(CMD_UPLOAD | MASK_08 | MASK_04);
75    /* load mc2 register: enable dma3 */
76    WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC1/4));
77    WRITE_RPS1(MASK_20 | MASK_04);
78    /* generate interrupt */
79    WRITE_RPS1(CMD_INTERRUPT);
80    /* stop rps1 */
81    WRITE_RPS1(CMD_STOP);
82
83    /* we have to do the workaround twice to be sure that
84       everything is ok */
85    for(i = 0; i < 2; i++) {
86
87        /* indicate to the irq handler that we do the workaround */
88        saa7146_write(dev, MC2, MASK_31|MASK_15);
89
90        saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0));
91        saa7146_write(dev, MC2, MASK_04|MASK_20);
92
93        /* enable rps1 irqs */
94        SAA7146_IER_ENABLE(dev,MASK_28);
95
96        /* prepare to wait to be woken up by the irq-handler */
97        add_wait_queue(&vv->vbi_wq, &wait);
98        current->state = TASK_INTERRUPTIBLE;
99
100        /* start rps1 to enable workaround */
101        saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
102        saa7146_write(dev, MC1, (MASK_13 | MASK_29));
103
104        schedule();
105
106        DEB_VBI("brs bug workaround %d/1\n", i);
107
108        remove_wait_queue(&vv->vbi_wq, &wait);
109        current->state = TASK_RUNNING;
110
111        /* disable rps1 irqs */
112        SAA7146_IER_DISABLE(dev,MASK_28);
113
114        /* stop video-dma3 */
115        saa7146_write(dev, MC1, MASK_20);
116
117        if(signal_pending(current)) {
118
119            DEB_VBI("aborted (rps:0x%08x)\n",
120                saa7146_read(dev, RPS_ADDR1));
121
122            /* stop rps1 for sure */
123            saa7146_write(dev, MC1, MASK_29);
124
125            pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
126            return -EINTR;
127        }
128    }
129
130    pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
131    return 0;
132}
133
134static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
135{
136    struct saa7146_vv *vv = dev->vv_data;
137
138    struct saa7146_video_dma vdma3;
139
140    int count = 0;
141    unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
142    unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
143
144/*
145    vdma3.base_even = 0xc8000000+2560*70;
146    vdma3.base_odd = 0xc8000000;
147    vdma3.prot_addr = 0xc8000000+2560*164;
148    vdma3.pitch = 2560;
149    vdma3.base_page = 0;
150    vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above!
151*/
152    vdma3.base_even = buf->pt[2].offset;
153    vdma3.base_odd = buf->pt[2].offset + 16 * vbi_pixel_to_capture;
154    vdma3.prot_addr = buf->pt[2].offset + 16 * 2 * vbi_pixel_to_capture;
155    vdma3.pitch = vbi_pixel_to_capture;
156    vdma3.base_page = buf->pt[2].dma | ME1;
157    vdma3.num_line_byte = (16 << 16) | vbi_pixel_to_capture;
158
159    saa7146_write_out_dma(dev, 3, &vdma3);
160
161    /* write beginning of rps-program */
162    count = 0;
163
164    /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */
165
166    /* we don't wait here for the first field anymore. this is different from the video
167       capture and might cause that the first buffer is only half filled (with only
168       one field). but since this is some sort of streaming data, this is not that negative.
169       but by doing this, we can use the whole engine from videobuf-dma-sg.c... */
170
171/*
172    WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
173    WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait);
174*/
175    /* set bit 1 */
176    WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4));
177    WRITE_RPS1(MASK_28 | MASK_12);
178
179    /* turn on video-dma3 */
180    WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4));
181    WRITE_RPS1(MASK_04 | MASK_20); /* => mask */
182    WRITE_RPS1(MASK_04 | MASK_20); /* => values */
183
184    /* wait for o_fid_a/b / e_fid_a/b toggle */
185    WRITE_RPS1(CMD_PAUSE | o_wait);
186    WRITE_RPS1(CMD_PAUSE | e_wait);
187
188    /* generate interrupt */
189    WRITE_RPS1(CMD_INTERRUPT);
190
191    /* stop */
192    WRITE_RPS1(CMD_STOP);
193
194    /* enable rps1 irqs */
195    SAA7146_IER_ENABLE(dev, MASK_28);
196
197    /* write the address of the rps-program */
198    saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
199
200    /* turn on rps */
201    saa7146_write(dev, MC1, (MASK_13 | MASK_29));
202}
203
204static int buffer_activate(struct saa7146_dev *dev,
205               struct saa7146_buf *buf,
206               struct saa7146_buf *next)
207{
208    struct saa7146_vv *vv = dev->vv_data;
209    buf->vb.state = VIDEOBUF_ACTIVE;
210
211    DEB_VBI("dev:%p, buf:%p, next:%p\n", dev, buf, next);
212    saa7146_set_vbi_capture(dev,buf,next);
213
214    mod_timer(&vv->vbi_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
215    return 0;
216}
217
218static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
219{
220    struct file *file = q->priv_data;
221    struct saa7146_fh *fh = file->private_data;
222    struct saa7146_dev *dev = fh->dev;
223    struct saa7146_buf *buf = (struct saa7146_buf *)vb;
224
225    int err = 0;
226    int lines, llength, size;
227
228    lines = 16 * 2 ; /* 2 fields */
229    llength = vbi_pixel_to_capture;
230    size = lines * llength;
231
232    DEB_VBI("vb:%p\n", vb);
233
234    if (0 != buf->vb.baddr && buf->vb.bsize < size) {
235        DEB_VBI("size mismatch\n");
236        return -EINVAL;
237    }
238
239    if (buf->vb.size != size)
240        saa7146_dma_free(dev,q,buf);
241
242    if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
243        struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
244
245        buf->vb.width = llength;
246        buf->vb.height = lines;
247        buf->vb.size = size;
248        buf->vb.field = field; // FIXME: check this
249
250        saa7146_pgtable_free(dev->pci, &buf->pt[2]);
251        saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
252
253        err = videobuf_iolock(q,&buf->vb, NULL);
254        if (err)
255            goto oops;
256        err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
257                         dma->sglist, dma->sglen);
258        if (0 != err)
259            return err;
260    }
261    buf->vb.state = VIDEOBUF_PREPARED;
262    buf->activate = buffer_activate;
263
264    return 0;
265
266 oops:
267    DEB_VBI("error out\n");
268    saa7146_dma_free(dev,q,buf);
269
270    return err;
271}
272
273static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
274{
275    int llength,lines;
276
277    lines = 16 * 2 ; /* 2 fields */
278    llength = vbi_pixel_to_capture;
279
280    *size = lines * llength;
281    *count = 2;
282
283    DEB_VBI("count:%d, size:%d\n", *count, *size);
284
285    return 0;
286}
287
288static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
289{
290    struct file *file = q->priv_data;
291    struct saa7146_fh *fh = file->private_data;
292    struct saa7146_dev *dev = fh->dev;
293    struct saa7146_vv *vv = dev->vv_data;
294    struct saa7146_buf *buf = (struct saa7146_buf *)vb;
295
296    DEB_VBI("vb:%p\n", vb);
297    saa7146_buffer_queue(dev, &vv->vbi_dmaq, buf);
298}
299
300static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
301{
302    struct file *file = q->priv_data;
303    struct saa7146_fh *fh = file->private_data;
304    struct saa7146_dev *dev = fh->dev;
305    struct saa7146_buf *buf = (struct saa7146_buf *)vb;
306
307    DEB_VBI("vb:%p\n", vb);
308    saa7146_dma_free(dev,q,buf);
309}
310
311static struct videobuf_queue_ops vbi_qops = {
312    .buf_setup = buffer_setup,
313    .buf_prepare = buffer_prepare,
314    .buf_queue = buffer_queue,
315    .buf_release = buffer_release,
316};
317
318/* ------------------------------------------------------------------ */
319
320static void vbi_stop(struct saa7146_fh *fh, struct file *file)
321{
322    struct saa7146_dev *dev = fh->dev;
323    struct saa7146_vv *vv = dev->vv_data;
324    unsigned long flags;
325    DEB_VBI("dev:%p, fh:%p\n", dev, fh);
326
327    spin_lock_irqsave(&dev->slock,flags);
328
329    /* disable rps1 */
330    saa7146_write(dev, MC1, MASK_29);
331
332    /* disable rps1 irqs */
333    SAA7146_IER_DISABLE(dev, MASK_28);
334
335    /* shut down dma 3 transfers */
336    saa7146_write(dev, MC1, MASK_20);
337
338    if (vv->vbi_dmaq.curr)
339        saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
340
341    videobuf_queue_cancel(&fh->vbi_q);
342
343    vv->vbi_streaming = NULL;
344
345    del_timer(&vv->vbi_dmaq.timeout);
346    del_timer(&vv->vbi_read_timeout);
347
348    spin_unlock_irqrestore(&dev->slock, flags);
349}
350
351static void vbi_read_timeout(unsigned long data)
352{
353    struct file *file = (struct file*)data;
354    struct saa7146_fh *fh = file->private_data;
355    struct saa7146_dev *dev = fh->dev;
356
357    DEB_VBI("dev:%p, fh:%p\n", dev, fh);
358
359    vbi_stop(fh, file);
360}
361
362static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
363{
364    DEB_VBI("dev:%p\n", dev);
365
366    INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
367
368    init_timer(&vv->vbi_dmaq.timeout);
369    vv->vbi_dmaq.timeout.function = saa7146_buffer_timeout;
370    vv->vbi_dmaq.timeout.data = (unsigned long)(&vv->vbi_dmaq);
371    vv->vbi_dmaq.dev = dev;
372
373    init_waitqueue_head(&vv->vbi_wq);
374}
375
376static int vbi_open(struct saa7146_dev *dev, struct file *file)
377{
378    struct saa7146_fh *fh = file->private_data;
379    struct saa7146_vv *vv = fh->dev->vv_data;
380
381    u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
382    int ret = 0;
383
384    DEB_VBI("dev:%p, fh:%p\n", dev, fh);
385
386    ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
387    if (0 == ret) {
388        DEB_S("cannot get vbi RESOURCE_DMA3_BRS resource\n");
389        return -EBUSY;
390    }
391
392    /* adjust arbitrition control for video dma 3 */
393    arbtr_ctrl &= ~0x1f0000;
394    arbtr_ctrl |= 0x1d0000;
395    saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
396    saa7146_write(dev, MC2, (MASK_04|MASK_20));
397
398    videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
399                &dev->pci->dev, &dev->slock,
400                V4L2_BUF_TYPE_VBI_CAPTURE,
401                V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
402                sizeof(struct saa7146_buf),
403                file, &dev->v4l2_lock);
404
405    vv->vbi_read_timeout.function = vbi_read_timeout;
406    vv->vbi_read_timeout.data = (unsigned long)file;
407
408    /* initialize the brs */
409    if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
410        saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
411    } else {
412        saa7146_write(dev, BRS_CTRL, 0x00000001);
413
414        if (0 != (ret = vbi_workaround(dev))) {
415            DEB_VBI("vbi workaround failed!\n");
416            /* return ret;*/
417        }
418    }
419
420    /* upload brs register */
421    saa7146_write(dev, MC2, (MASK_08|MASK_24));
422    return 0;
423}
424
425static void vbi_close(struct saa7146_dev *dev, struct file *file)
426{
427    struct saa7146_fh *fh = file->private_data;
428    struct saa7146_vv *vv = dev->vv_data;
429    DEB_VBI("dev:%p, fh:%p\n", dev, fh);
430
431    if( fh == vv->vbi_streaming ) {
432        vbi_stop(fh, file);
433    }
434    saa7146_res_free(fh, RESOURCE_DMA3_BRS);
435}
436
437static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
438{
439    struct saa7146_vv *vv = dev->vv_data;
440    spin_lock(&dev->slock);
441
442    if (vv->vbi_dmaq.curr) {
443        DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_dmaq.curr);
444        /* this must be += 2, one count for each field */
445        vv->vbi_fieldcount+=2;
446        vv->vbi_dmaq.curr->vb.field_count = vv->vbi_fieldcount;
447        saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
448    } else {
449        DEB_VBI("dev:%p\n", dev);
450    }
451    saa7146_buffer_next(dev, &vv->vbi_dmaq, 1);
452
453    spin_unlock(&dev->slock);
454}
455
456static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
457{
458    struct saa7146_fh *fh = file->private_data;
459    struct saa7146_dev *dev = fh->dev;
460    struct saa7146_vv *vv = dev->vv_data;
461    ssize_t ret = 0;
462
463    DEB_VBI("dev:%p, fh:%p\n", dev, fh);
464
465    if( NULL == vv->vbi_streaming ) {
466        // fixme: check if dma3 is available
467        // fixme: activate vbi engine here if necessary. (really?)
468        vv->vbi_streaming = fh;
469    }
470
471    if( fh != vv->vbi_streaming ) {
472        DEB_VBI("open %p is already using vbi capture\n",
473            vv->vbi_streaming);
474        return -EBUSY;
475    }
476
477    mod_timer(&vv->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
478    ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
479                   file->f_flags & O_NONBLOCK);
480/*
481    printk("BASE_ODD3: 0x%08x\n", saa7146_read(dev, BASE_ODD3));
482    printk("BASE_EVEN3: 0x%08x\n", saa7146_read(dev, BASE_EVEN3));
483    printk("PROT_ADDR3: 0x%08x\n", saa7146_read(dev, PROT_ADDR3));
484    printk("PITCH3: 0x%08x\n", saa7146_read(dev, PITCH3));
485    printk("BASE_PAGE3: 0x%08x\n", saa7146_read(dev, BASE_PAGE3));
486    printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
487    printk("BRS_CTRL: 0x%08x\n", saa7146_read(dev, BRS_CTRL));
488*/
489    return ret;
490}
491
492struct saa7146_use_ops saa7146_vbi_uops = {
493    .init = vbi_init,
494    .open = vbi_open,
495    .release = vbi_close,
496    .irq_done = vbi_irq_done,
497    .read = vbi_read,
498};
499

Archive Download this file



interactive