Subversion Repositories shark

Rev

Rev 425 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
773 giacomo 1
#include <linuxcomp.h>
2
 
425 giacomo 3
#include <media/saa7146_vv.h>
4
 
5
#define BOARD_CAN_DO_VBI(dev)   (dev->revision != 0 && dev->vv_data->vbi_minor != -1) 
6
 
7
/****************************************************************************/
8
/* resource management functions, shamelessly stolen from saa7134 driver */
9
 
10
int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
11
{
12
        struct saa7146_dev *dev = fh->dev;
13
        struct saa7146_vv *vv = dev->vv_data;
14
 
15
        if (fh->resources & bit)
16
                /* have it already allocated */
17
                return 1;
18
 
19
        /* is it free? */
20
        DEB_D(("getting lock...\n"));
773 giacomo 21
        //down(&dev->lock);
425 giacomo 22
        DEB_D(("got lock\n"));
23
        if (vv->resources & bit) {
24
                DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
25
                /* no, someone else uses it */
773 giacomo 26
                //up(&dev->lock);
425 giacomo 27
                return 0;
28
        }
29
        /* it's free, grab it */
30
        fh->resources  |= bit;
31
        vv->resources |= bit;
32
        DEB_D(("res: get %d\n",bit));
773 giacomo 33
        //up(&dev->lock);
425 giacomo 34
        return 1;
35
}
36
 
37
int saa7146_res_check(struct saa7146_fh *fh, unsigned int bit)
38
{
39
        return (fh->resources & bit);
40
}
41
 
42
int saa7146_res_locked(struct saa7146_dev *dev, unsigned int bit)
43
{
44
        struct saa7146_vv *vv = dev->vv_data;
45
        return (vv->resources & bit);
46
}
47
 
48
void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
49
{
50
        struct saa7146_dev *dev = fh->dev;
51
        struct saa7146_vv *vv = dev->vv_data;
52
 
53
        if ((fh->resources & bits) != bits)
54
                BUG();
55
 
56
        DEB_D(("getting lock...\n"));
773 giacomo 57
        //down(&dev->lock);
425 giacomo 58
        DEB_D(("got lock\n"));
59
        fh->resources  &= ~bits;
60
        vv->resources &= ~bits;
61
        DEB_D(("res: put %d\n",bits));
773 giacomo 62
        //up(&dev->lock);
425 giacomo 63
}
64
 
65
 
66
/********************************************************************************/
67
/* common dma functions */
68
 
69
void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf)
70
{
71
        DEB_EE(("dev:%p, buf:%p\n",dev,buf));
72
 
73
        if (in_interrupt())
74
                BUG();
75
 
76
        videobuf_waiton(&buf->vb,0,0);
77
        videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
78
        videobuf_dma_free(&buf->vb.dma);
79
        buf->vb.state = STATE_NEEDS_INIT;
80
}
81
 
82
 
83
/********************************************************************************/
84
/* common buffer functions */
85
 
86
int saa7146_buffer_queue(struct saa7146_dev *dev,
87
                         struct saa7146_dmaqueue *q,
88
                         struct saa7146_buf *buf)
89
{
90
#if DEBUG_SPINLOCKS
91
        BUG_ON(!spin_is_locked(&dev->slock));
92
#endif
93
        DEB_EE(("dev:%p, dmaq:%p, buf:%p\n", dev, q, buf));
94
 
95
        if( NULL == q ) {
96
                ERR(("internal error: fatal NULL pointer for q.\n"));
97
                return 0;
98
        }
99
 
100
        if (NULL == q->curr) {
101
                q->curr = buf;
102
                DEB_D(("immediately activating buffer %p\n", buf));
103
                buf->activate(dev,buf,NULL);
104
        } else {
105
                list_add_tail(&buf->vb.queue,&q->queue);
106
                buf->vb.state = STATE_QUEUED;
107
                DEB_D(("adding buffer %p to queue. (active buffer present)\n", buf));
108
        }
109
        return 0;
110
}
111
 
112
void saa7146_buffer_finish(struct saa7146_dev *dev,
113
                           struct saa7146_dmaqueue *q,
114
                           int state)
115
{
116
#if DEBUG_SPINLOCKS
117
        BUG_ON(!spin_is_locked(&dev->slock));
118
#endif
119
        if( NULL == q->curr ) {
120
                ERR(("internal error: fatal NULL pointer for q->curr.\n"));
121
                return;
122
        }
123
 
124
        DEB_EE(("dev:%p, dmaq:%p, state:%d\n", dev, q, state));
125
        DEB_EE(("q->curr:%p\n",q->curr));
126
 
127
        /* finish current buffer */
128
        if (NULL == q->curr) {
129
                DEB_D(("aiii. no current buffer\n"));
130
                return;
131
        }
132
 
133
        q->curr->vb.state = state;
773 giacomo 134
        //do_gettimeofday(&q->curr->vb.ts);
135
        //wake_up(&q->curr->vb.done);
425 giacomo 136
 
137
        q->curr = NULL;
138
}
139
 
140
void saa7146_buffer_next(struct saa7146_dev *dev,
141
                         struct saa7146_dmaqueue *q, int vbi)
142
{
143
        struct saa7146_buf *buf,*next = NULL;
144
 
145
        if( NULL == q ) {
146
                ERR(("internal error: fatal NULL pointer for q.\n"));
147
                return;
148
        }
149
 
150
        DEB_INT(("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi));
151
 
152
#if DEBUG_SPINLOCKS
153
        BUG_ON(!spin_is_locked(&dev->slock));
154
#endif
155
        if (!list_empty(&q->queue)) {
156
                /* activate next one from queue */
157
                buf = list_entry(q->queue.next,struct saa7146_buf,vb.queue);
158
                list_del(&buf->vb.queue);
159
                if (!list_empty(&q->queue))
160
                        next = list_entry(q->queue.next,struct saa7146_buf, vb.queue);
161
                q->curr = buf;
162
                DEB_INT(("next buffer: buf:%p, prev:%p, next:%p\n", buf, q->queue.prev,q->queue.next));
163
                buf->activate(dev,buf,next);
164
        } else {
165
                DEB_INT(("no next buffer. stopping.\n"));
166
                if( 0 != vbi ) {
167
                        /* turn off video-dma3 */
168
                        saa7146_write(dev,MC1, MASK_20);
169
                } else {
170
                        /* nothing to do -- just prevent next video-dma1 transfer
171
                           by lowering the protection address */
172
 
173
                        // fixme: fix this for vflip != 0
174
 
175
                        saa7146_write(dev, PROT_ADDR1, 0);
176
                        saa7146_write(dev, MC2, (MASK_02|MASK_18));            
177
 
178
                        /* write the address of the rps-program */
179
                        saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
180
                        /* turn on rps */
181
                        saa7146_write(dev, MC1, (MASK_12 | MASK_28));
182
 
183
/*
184
                        printk("vdma%d.base_even:     0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
185
                        printk("vdma%d.base_odd:      0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
186
                        printk("vdma%d.prot_addr:     0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
187
                        printk("vdma%d.base_page:     0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
188
                        printk("vdma%d.pitch:         0x%08x\n", 1,saa7146_read(dev,PITCH1));
189
                        printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
190
*/
191
                }
192
                del_timer(&q->timeout);
193
        }
194
}
195
 
196
void saa7146_buffer_timeout(unsigned long data)
197
{
198
        struct saa7146_dmaqueue *q = (struct saa7146_dmaqueue*)data;
199
        struct saa7146_dev *dev = q->dev;
200
        unsigned long flags;
201
 
202
        DEB_EE(("dev:%p, dmaq:%p\n", dev, q));
203
 
204
        spin_lock_irqsave(&dev->slock,flags);
205
        if (q->curr) {
206
                DEB_D(("timeout on %p\n", q->curr));
207
                saa7146_buffer_finish(dev,q,STATE_ERROR);
208
        }
209
 
210
        /* we don't restart the transfer here like other drivers do. when
211
           a streaming capture is disabled, the timeout function will be
212
           called for the current buffer. if we activate the next buffer now,
213
           we mess up our capture logic. if a timeout occurs on another buffer,
214
           then something is seriously broken before, so no need to buffer the
215
           next capture IMHO... */
216
/*
217
        saa7146_buffer_next(dev,q);
218
*/
219
        spin_unlock_irqrestore(&dev->slock,flags);
220
}
221
 
222
/********************************************************************************/
223
/* file operations */
224
 
225
static int fops_open(struct inode *inode, struct file *file)
226
{
227
        unsigned int minor = iminor(inode);
228
        struct saa7146_dev *h = NULL, *dev = NULL;
229
        struct list_head *list;
230
        struct saa7146_fh *fh = NULL;
231
        int result = 0;
232
 
233
        enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
234
 
235
        DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor));
236
 
773 giacomo 237
        //if (down_interruptible(&saa7146_devices_lock))
238
        //      return -ERESTARTSYS;
425 giacomo 239
 
240
        list_for_each(list,&saa7146_devices) {
241
                h = list_entry(list, struct saa7146_dev, item);
242
                if( NULL == h->vv_data ) {
243
                        DEB_D(("device %p has not registered video devices.\n",h));
244
                        continue;
245
                }
246
                DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor));
247
 
248
                if (h->vv_data->video_minor == minor) {
249
                        dev = h;
250
                }
251
                if (h->vv_data->vbi_minor == minor) {
252
                        type = V4L2_BUF_TYPE_VBI_CAPTURE;
253
                        dev = h;
254
                }
255
        }
256
        if (NULL == dev) {
257
                DEB_S(("no such video device.\n"));
258
                result = -ENODEV;
259
                goto out;
260
        }
261
 
262
        DEB_D(("using: %p\n",dev));
263
 
264
        /* check if an extension is registered */
265
        if( NULL == dev->ext ) {
266
                DEB_S(("no extension registered for this device.\n"));
267
                result = -ENODEV;
268
                goto out;
269
        }
270
 
271
        /* allocate per open data */
272
        fh = kmalloc(sizeof(*fh),GFP_KERNEL);
273
        if (NULL == fh) {
274
                DEB_S(("cannot allocate memory for per open data.\n"));
275
                result = -ENOMEM;
276
                goto out;
277
        }
278
        memset(fh,0,sizeof(*fh));
279
 
280
        file->private_data = fh;
281
        fh->dev = dev;
282
        fh->type = type;
283
 
284
        if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
285
                DEB_S(("initializing vbi...\n"));
286
                result = saa7146_vbi_uops.open(dev,file);
287
        } else {
288
                DEB_S(("initializing video...\n"));
289
                result = saa7146_video_uops.open(dev,file);
290
        }
291
 
292
        if (0 != result) {
293
                goto out;
294
        }
295
 
296
        if( 0 == try_module_get(dev->ext->module)) {
297
                result = -EINVAL;
298
                goto out;
299
        }
300
 
301
        result = 0;
302
out:
303
        if( fh != 0 && result != 0 ) {
304
                kfree(fh);
305
                file->private_data = NULL;
306
        }
773 giacomo 307
        //up(&saa7146_devices_lock);
425 giacomo 308
        return result;
309
}
310
 
311
static int fops_release(struct inode *inode, struct file *file)
312
{
313
        struct saa7146_fh  *fh  = file->private_data;
314
        struct saa7146_dev *dev = fh->dev;
315
 
316
        DEB_EE(("inode:%p, file:%p\n",inode,file));
317
 
773 giacomo 318
        //if (down_interruptible(&saa7146_devices_lock))
319
        //      return -ERESTARTSYS;
425 giacomo 320
 
321
        if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
322
                saa7146_vbi_uops.release(dev,file);
323
        } else {
324
                saa7146_video_uops.release(dev,file);
325
        }
326
 
327
        module_put(dev->ext->module);
328
        file->private_data = NULL;
329
        kfree(fh);
330
 
773 giacomo 331
        //up(&saa7146_devices_lock);
425 giacomo 332
 
333
        return 0;
334
}
335
 
336
int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
337
static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
338
{
339
/*
340
        DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg));
341
*/
342
        return video_usercopy(inode, file, cmd, arg, saa7146_video_do_ioctl);
343
}
344
 
345
static int fops_mmap(struct file *file, struct vm_area_struct * vma)
346
{
347
        struct saa7146_fh *fh = file->private_data;
348
        struct videobuf_queue *q;
349
 
350
        switch (fh->type) {
351
        case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
352
                DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",file, vma));
353
                q = &fh->video_q;
354
                break;
355
                }
356
        case V4L2_BUF_TYPE_VBI_CAPTURE: {
357
                DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",file, vma));
358
                q = &fh->vbi_q;
359
                break;
360
                }
361
        default:
362
                BUG();
363
                return 0;
364
        }
365
        return videobuf_mmap_mapper(vma,q);
366
}
367
 
368
static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
369
{
370
        struct saa7146_fh *fh = file->private_data;
371
        struct videobuf_buffer *buf = NULL;
372
        struct videobuf_queue *q;
373
 
374
        DEB_EE(("file:%p, poll:%p\n",file, wait));
375
 
376
        if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
377
                if( 0 == fh->vbi_q.streaming )
378
                        return videobuf_poll_stream(file, &fh->vbi_q, wait);
379
                q = &fh->vbi_q;
380
        } else {
381
                DEB_D(("using video queue.\n"));
382
                q = &fh->video_q;
383
        }
384
 
385
        if (!list_empty(&q->stream))
386
                buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
387
 
388
        if (!buf) {
389
                DEB_D(("buf == NULL!\n"));
390
                return POLLERR;
391
        }
392
 
393
        poll_wait(file, &buf->done, wait);
394
        if (buf->state == STATE_DONE || buf->state == STATE_ERROR) {
395
                DEB_D(("poll succeeded!\n"));
396
                return POLLIN|POLLRDNORM;
397
        }
398
 
399
        DEB_D(("nothing to poll for, buf->state:%d\n",buf->state));
400
        return 0;
401
}
402
 
403
static ssize_t fops_read(struct file *file, char *data, size_t count, loff_t *ppos)
404
{
405
        struct saa7146_fh *fh = file->private_data;
406
 
407
        switch (fh->type) {
408
        case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
409
//              DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count));
410
                return saa7146_video_uops.read(file,data,count,ppos);
411
                }
412
        case V4L2_BUF_TYPE_VBI_CAPTURE: {
413
//              DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count));
414
                return saa7146_vbi_uops.read(file,data,count,ppos);
415
                }
416
                break;
417
        default:
418
                BUG();
419
                return 0;
420
        }
421
}
422
 
423
static struct file_operations video_fops =
424
{
425
        .owner          = THIS_MODULE,
426
        .open           = fops_open,
427
        .release        = fops_release,
428
        .read           = fops_read,
429
        .poll           = fops_poll,
430
        .mmap           = fops_mmap,
431
        .ioctl          = fops_ioctl,
432
        .llseek         = no_llseek,
433
};
434
 
435
void vv_callback(struct saa7146_dev *dev, unsigned long status)
436
{
437
        u32 isr = status;
438
 
439
        DEB_INT(("dev:%p, isr:0x%08x\n",dev,(u32)status));
440
 
441
        if (0 != (isr & (MASK_27))) {
442
                DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
443
                saa7146_video_uops.irq_done(dev,isr);
444
        }
445
 
446
        if (0 != (isr & (MASK_28))) {
447
                u32 mc2 = saa7146_read(dev, MC2);
448
                if( 0 != (mc2 & MASK_15)) {
449
                        DEB_INT(("irq: RPS1 vbi workaround (0x%08x).\n",isr));
773 giacomo 450
                        //wake_up(&dev->vv_data->vbi_wq);
425 giacomo 451
                        saa7146_write(dev,MC2, MASK_31);
452
                        return;
453
                }
454
                DEB_INT(("irq: RPS1 (0x%08x).\n",isr));
455
                saa7146_vbi_uops.irq_done(dev,isr);
456
        }
457
}
458
 
459
static struct video_device device_template =
460
{
461
        .hardware       = VID_HARDWARE_SAA7146,
462
        .fops           = &video_fops,
463
        .minor          = -1,
464
};
465
 
466
int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
467
{
468
        struct saa7146_vv *vv = kmalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
469
        if( NULL == vv ) {
470
                ERR(("out of memory. aborting.\n"));
471
                return -1;
472
        }
473
        memset(vv, 0x0, sizeof(*vv));
474
 
475
        DEB_EE(("dev:%p\n",dev));
476
 
477
        /* set default values for video parts of the saa7146 */
478
        saa7146_write(dev, BCS_CTRL, 0x80400040);
479
 
480
        /* enable video-port pins */
481
        saa7146_write(dev, MC1, (MASK_10 | MASK_26));
482
 
483
        /* save per-device extension data (one extension can
484
           handle different devices that might need different
485
           configuration data) */
486
        dev->ext_vv_data = ext_vv;
487
 
488
        vv->video_minor = -1;
489
        vv->vbi_minor = -1;
490
 
491
        vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);    
492
        if( NULL == vv->d_clipping.cpu_addr ) {
493
                ERR(("out of memory. aborting.\n"));
494
                kfree(vv);
495
                return -1;
496
        }
497
        memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
498
 
499
        saa7146_video_uops.init(dev,vv);
500
        saa7146_vbi_uops.init(dev,vv);
501
 
502
        dev->vv_data = vv;
503
        dev->vv_callback = &vv_callback;
504
 
505
        return 0;
506
}
507
 
508
int saa7146_vv_release(struct saa7146_dev* dev)
509
{
510
        struct saa7146_vv *vv = dev->vv_data;
511
 
512
        DEB_EE(("dev:%p\n",dev));
513
 
514
        pci_free_consistent(dev->pci, SAA7146_RPS_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
515
        kfree(vv);
516
        dev->vv_data = NULL;
517
        dev->vv_callback = NULL;
518
 
519
        return 0;
520
}
521
 
522
int saa7146_register_device(struct video_device *vid, struct saa7146_dev* dev, char *name, int type)
523
{
524
        struct saa7146_vv *vv = dev->vv_data;
525
 
526
        DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));
527
 
528
        *vid = device_template;
529
        strlcpy(vid->name, name, sizeof(vid->name));
530
        vid->priv = dev;
531
 
532
        // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
533
        if (video_register_device(vid,type,-1) < 0) {
534
                ERR(("cannot register v4l2 device. skipping.\n"));
535
                return -1;
536
        }
537
 
538
        if( VFL_TYPE_GRABBER == type ) {
539
                vv->video_minor = vid->minor;
540
                INFO(("%s: registered device video%d [v4l2]\n", dev->name,vid->minor & 0x1f));
541
        } else {
542
                vv->vbi_minor = vid->minor;
543
                INFO(("%s: registered device vbi%d [v4l2]\n", dev->name,vid->minor & 0x1f));
544
        }
545
 
546
        return 0;
547
}
548
 
549
int saa7146_unregister_device(struct video_device *vid, struct saa7146_dev* dev)
550
{
551
        struct saa7146_vv *vv = dev->vv_data;
552
 
553
        DEB_EE(("dev:%p\n",dev));
554
 
555
        if( VFL_TYPE_GRABBER == vid->type ) {
556
                vv->video_minor = -1;
557
        } else {
558
                vv->vbi_minor = -1;
559
        }
560
        video_unregister_device(vid);
561
 
562
        return 0;
563
}
564
 
565
static int __init saa7146_vv_init_module(void)
566
{
567
        return 0;
568
}
569
 
570
 
571
static void __exit saa7146_vv_cleanup_module(void)
572
{
573
}
574
 
575
module_init(saa7146_vv_init_module);
576
module_exit(saa7146_vv_cleanup_module);
577
 
578
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
579
MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware");
580
MODULE_LICENSE("GPL");