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
static int memory = 32;
6
 
7
MODULE_PARM(memory,"i");
8
MODULE_PARM_DESC(memory, "maximum memory usage for capture buffers (default: 32Mb)");
9
 
10
/* format descriptions for capture and preview */
11
static struct saa7146_format formats[] = {
12
        {
13
                .name           = "RGB-8 (3-3-2)",
14
                .pixelformat    = V4L2_PIX_FMT_RGB332,
15
                .trans          = RGB08_COMPOSED,
16
                .depth          = 8,
17
                .flags          = 0,
18
        }, {
19
                .name           = "RGB-16 (5/B-6/G-5/R)",
20
                .pixelformat    = V4L2_PIX_FMT_RGB565,
21
                .trans          = RGB16_COMPOSED,
22
                .depth          = 16,
23
                .flags          = 0,
24
        }, {
25
                .name           = "RGB-24 (B-G-R)",
26
                .pixelformat    = V4L2_PIX_FMT_BGR24,
27
                .trans          = RGB24_COMPOSED,
28
                .depth          = 24,
29
                .flags          = 0,
30
        }, {
31
                .name           = "RGB-32 (B-G-R)",
32
                .pixelformat    = V4L2_PIX_FMT_BGR32,
33
                .trans          = RGB32_COMPOSED,
34
                .depth          = 32,
35
                .flags          = 0,
36
        }, {
37
                .name           = "Greyscale-8",
38
                .pixelformat    = V4L2_PIX_FMT_GREY,
39
                .trans          = Y8,
40
                .depth          = 8,
41
                .flags          = 0,
42
        }, {
43
                .name           = "YUV 4:2:2 planar (Y-Cb-Cr)",
44
                .pixelformat    = V4L2_PIX_FMT_YUV422P,
45
                .trans          = YUV422_DECOMPOSED,
46
                .depth          = 16,
47
                .flags          = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
48
        }, {
49
                .name           = "YVU 4:2:0 planar (Y-Cb-Cr)",
50
                .pixelformat    = V4L2_PIX_FMT_YVU420,
51
                .trans          = YUV420_DECOMPOSED,
52
                .depth          = 12,
53
                .flags          = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
54
        }, {
55
                .name           = "YUV 4:2:0 planar (Y-Cb-Cr)",
56
                .pixelformat    = V4L2_PIX_FMT_YUV420,
57
                .trans          = YUV420_DECOMPOSED,
58
                .depth          = 12,
59
                .flags          = FORMAT_IS_PLANAR,
60
        }, {
61
                .name           = "YUV 4:2:2 (U-Y-V-Y)",
62
                .pixelformat    = V4L2_PIX_FMT_UYVY,
63
                .trans          = YUV422_COMPOSED,
64
                .depth          = 16,
65
                .flags          = 0,
66
        }
67
};
68
 
69
/* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps.
70
   due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped
71
   (like V4L2_PIX_FMT_YUYV) ... 8-( */
72
 
73
static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
74
 
75
struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
76
{
77
        int i, j = NUM_FORMATS;
78
 
79
        for (i = 0; i < j; i++) {
80
                if (formats[i].pixelformat == fourcc) {
81
                        return formats+i;
82
                }
83
        }
84
 
85
        DEB_D(("unknown pixelformat:'%4.4s'\n",(char *)&fourcc));
86
        return NULL;
87
}
88
 
89
static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
90
{
91
        struct saa7146_dev *dev = fh->dev;
92
        DEB_EE(("dev:%p, fh:%p\n",dev,fh));
93
 
94
        switch (f->type) {
95
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
96
                f->fmt.pix = fh->video_fmt;
97
                return 0;
98
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
99
                f->fmt.win = fh->ov.win;
100
                return 0;
101
        case V4L2_BUF_TYPE_VBI_CAPTURE:
102
        {
103
                f->fmt.vbi = fh->vbi_fmt;
104
                return 0;
105
        }
106
        default:
107
                DEB_D(("invalid format type '%d'.\n",f->type));
108
                return -EINVAL;
109
        }
110
}
111
 
112
static int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
113
{
114
        struct saa7146_vv *vv = dev->vv_data;
115
        enum v4l2_field field;
116
        int maxw, maxh;
117
 
118
        DEB_EE(("dev:%p\n",dev));
119
 
120
        if (NULL == vv->ov_fb.base) {
121
                DEB_D(("no fb base set.\n"));
122
                return -EINVAL;
123
        }
124
        if (NULL == vv->ov_fmt) {
125
                DEB_D(("no fb fmt set.\n"));
126
                return -EINVAL;
127
        }
128
        if (win->w.width < 48 || win->w.height <  32) {
129
                DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height));
130
                return -EINVAL;
131
        }
132
        if (win->clipcount > 16) {
133
                DEB_D(("clipcount too big.\n"));
134
                return -EINVAL;
135
        }
136
 
137
        field = win->field;
138
        maxw  = vv->standard->h_max_out;
139
        maxh  = vv->standard->v_max_out;
140
 
141
        if (V4L2_FIELD_ANY == field) {
142
                field = (win->w.height > maxh/2)
143
                        ? V4L2_FIELD_INTERLACED
144
                        : V4L2_FIELD_TOP;
145
                }
146
        switch (field) {
147
        case V4L2_FIELD_TOP:
148
        case V4L2_FIELD_BOTTOM:
149
        case V4L2_FIELD_ALTERNATE:
150
                maxh = maxh / 2;
151
                break;
152
        case V4L2_FIELD_INTERLACED:
153
                break;
154
        default: {
155
                DEB_D(("no known field mode '%d'.\n",field));
156
                return -EINVAL;
157
        }
158
        }
159
 
160
        win->field = field;
161
        if (win->w.width > maxw)
162
                win->w.width = maxw;
163
        if (win->w.height > maxh)
164
                win->w.height = maxh;
165
 
166
        return 0;
167
}
168
 
169
static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
170
{
171
        struct saa7146_dev *dev = fh->dev;
172
        struct saa7146_vv *vv = dev->vv_data;
173
        int err;
174
 
175
        switch (f->type) {
176
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
177
        {
178
                struct saa7146_format *fmt;
179
                enum v4l2_field field;
180
                int maxw, maxh;
181
                int calc_bpl;
182
 
183
                DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
184
 
185
                fmt = format_by_fourcc(dev,f->fmt.pix.pixelformat);
186
                if (NULL == fmt) {
187
                        return -EINVAL;
188
                }
189
 
190
                field = f->fmt.pix.field;
191
                maxw  = vv->standard->h_max_out;
192
                maxh  = vv->standard->v_max_out;
193
 
194
                if (V4L2_FIELD_ANY == field) {
195
                        field = (f->fmt.pix.height > maxh/2)
196
                                ? V4L2_FIELD_INTERLACED
197
                                : V4L2_FIELD_BOTTOM;
198
                }
199
                switch (field) {
200
                case V4L2_FIELD_ALTERNATE: {
201
                        vv->last_field = V4L2_FIELD_TOP;
202
                        maxh = maxh / 2;
203
                        break;
204
                }
205
                case V4L2_FIELD_TOP:
206
                case V4L2_FIELD_BOTTOM:
207
                        vv->last_field = V4L2_FIELD_INTERLACED;
208
                        maxh = maxh / 2;
209
                        break;
210
                case V4L2_FIELD_INTERLACED:
211
                        vv->last_field = V4L2_FIELD_INTERLACED;
212
                        break;
213
                default: {
214
                        DEB_D(("no known field mode '%d'.\n",field));
215
                        return -EINVAL;
216
                }
217
                }
218
 
219
                f->fmt.pix.field = field;
220
                if (f->fmt.pix.width > maxw)
221
                        f->fmt.pix.width = maxw;
222
                if (f->fmt.pix.height > maxh)
223
                        f->fmt.pix.height = maxh;
224
 
225
                calc_bpl = (f->fmt.pix.width * fmt->depth)/8;
226
 
227
                if (f->fmt.pix.bytesperline < calc_bpl)
228
                        f->fmt.pix.bytesperline = calc_bpl;
229
 
230
                if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */
231
                        f->fmt.pix.bytesperline = calc_bpl;
232
 
233
                f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
234
                DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage));
235
 
236
                return 0;
237
        }
238
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
239
                DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
240
                err = try_win(dev,&f->fmt.win);
241
                if (0 != err) {
242
                        return err;
243
                }
244
                return 0;
245
        default:
246
                DEB_EE(("unknown format type '%d'\n",f->type));
247
                return -EINVAL;
248
        }
249
}
250
 
251
int saa7146_start_preview(struct saa7146_fh *fh)
252
{
253
        struct saa7146_dev *dev = fh->dev;
254
        struct saa7146_vv *vv = dev->vv_data;
255
        int ret = 0, err = 0;
256
 
257
        DEB_EE(("dev:%p, fh:%p\n",dev,fh));
258
 
259
        /* check if we have overlay informations */
260
        if( NULL == fh->ov.fh ) {
261
                DEB_D(("no overlay data available. try S_FMT first.\n"));
262
                return -EAGAIN;
263
        }
264
 
265
        /* check if overlay is running */
266
        if( 0 != vv->ov_data ) {
267
                if( fh != vv->ov_data->fh ) {
268
                        DEB_D(("overlay is running in another open.\n"));
269
                        return -EAGAIN;
270
                }
271
                DEB_D(("overlay is already active.\n"));
272
                return 0;
273
        }
274
 
275
        if( 0 != vv->streaming ) {
276
                DEB_D(("streaming capture is active.\n"));
277
                return -EBUSY;
278
        }      
279
 
280
        err = try_win(dev,&fh->ov.win);
281
        if (0 != err) {
282
                return err;
283
        }
284
 
285
        vv->ov_data = &fh->ov;
286
 
287
        DEB_D(("%dx%d+%d+%d %s field=%s\n",
288
                fh->ov.win.w.width,fh->ov.win.w.height,
289
                fh->ov.win.w.left,fh->ov.win.w.top,
290
                vv->ov_fmt->name,v4l2_field_names[fh->ov.win.field]));
291
 
292
        if (0 != (ret = saa7146_enable_overlay(fh))) {
293
                vv->ov_data = NULL;
294
                DEB_D(("enabling overlay failed: %d\n",ret));
295
                return ret;
296
        }
297
 
298
        return 0;
299
}
300
 
301
int saa7146_stop_preview(struct saa7146_fh *fh)
302
{
303
        struct saa7146_dev *dev = fh->dev;
304
        struct saa7146_vv *vv = dev->vv_data;
305
 
306
        DEB_EE(("dev:%p, fh:%p\n",dev,fh));
307
 
308
        /* check if overlay is running */
309
        if( 0 == vv->ov_data ) {
310
                DEB_D(("overlay is not active.\n"));
311
                return 0;
312
        }
313
 
314
        if( fh != vv->ov_data->fh ) {
315
                DEB_D(("overlay is active, but for another open.\n"));
316
                return 0;
317
        }
318
 
319
        vv->ov_data = NULL;
320
        saa7146_disable_overlay(fh);
321
 
322
        return 0;
323
}
324
 
325
static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
326
{
327
        struct saa7146_dev *dev = fh->dev;
328
        struct saa7146_vv *vv = dev->vv_data;
329
 
330
        unsigned long flags;
331
        int err;
332
 
333
        switch (f->type) {
334
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
335
                DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
336
                if( fh == vv->streaming ) {
337
                        DEB_EE(("streaming capture is active"));
338
                        return -EAGAIN;
339
                }
340
                err = try_fmt(fh,f);
341
                if (0 != err)
342
                        return err;
343
                fh->video_fmt = f->fmt.pix;
344
                DEB_EE(("set to pixelformat '%4.4s'\n",(char *)&fh->video_fmt.pixelformat));
345
                return 0;
346
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
347
                DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
348
                err = try_win(dev,&f->fmt.win);
349
                if (0 != err)
350
                        return err;
773 giacomo 351
                //down(&dev->lock);
425 giacomo 352
                fh->ov.win    = f->fmt.win;
353
                fh->ov.nclips = f->fmt.win.clipcount;
354
                if (fh->ov.nclips > 16)
355
                        fh->ov.nclips = 16;
356
                if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
773 giacomo 357
                        //up(&dev->lock);
425 giacomo 358
                        return -EFAULT;
359
                }
360
 
361
                /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
362
                fh->ov.fh = fh;
363
 
364
                /* check if we have an active overlay */
365
                if( vv->ov_data != NULL ) {
366
                        if( fh == vv->ov_data->fh) {
367
                                spin_lock_irqsave(&dev->slock,flags);
368
                                saa7146_stop_preview(fh);
369
                                saa7146_start_preview(fh);
370
                                spin_unlock_irqrestore(&dev->slock,flags);
371
                        }
372
                }
773 giacomo 373
                //up(&dev->lock);
425 giacomo 374
                return 0;
375
        default:
376
                DEB_D(("unknown format type '%d'\n",f->type));
377
                return -EINVAL;
378
        }
379
}
380
 
381
/********************************************************************************/
382
/* device controls */
383
 
384
static struct v4l2_queryctrl controls[] = {
385
        {
386
                id:            V4L2_CID_BRIGHTNESS,
387
                name:          "Brightness",
388
                minimum:       0,
389
                maximum:       255,
390
                step:          1,
391
                default_value: 128,
392
                type:          V4L2_CTRL_TYPE_INTEGER,
393
        },{
394
                id:            V4L2_CID_CONTRAST,
395
                name:          "Contrast",
396
                minimum:       0,
397
                maximum:       127,
398
                step:          1,
399
                default_value: 64,
400
                type:          V4L2_CTRL_TYPE_INTEGER,
401
        },{
402
                id:            V4L2_CID_SATURATION,
403
                name:          "Saturation",
404
                minimum:       0,
405
                maximum:       127,
406
                step:          1,
407
                default_value: 64,
408
                type:          V4L2_CTRL_TYPE_INTEGER,
409
        },{
410
                id:            V4L2_CID_VFLIP,
411
                name:          "Vertical flip",
412
                minimum:       0,
413
                maximum:       1,
414
                type:          V4L2_CTRL_TYPE_BOOLEAN,
415
        },{
416
                id:            V4L2_CID_HFLIP,
417
                name:          "Horizontal flip",
418
                minimum:       0,
419
                maximum:       1,
420
                type:          V4L2_CTRL_TYPE_BOOLEAN,
421
        },
422
};
423
static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl);
424
 
425
#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 0)
426
 
427
static struct v4l2_queryctrl* ctrl_by_id(int id)
428
{
429
        int i;
430
 
431
        for (i = 0; i < NUM_CONTROLS; i++)
432
                if (controls[i].id == id)
433
                        return controls+i;
434
        return NULL;
435
}
436
 
437
static int get_control(struct saa7146_fh *fh, struct v4l2_control *c)
438
{
439
        struct saa7146_dev *dev = fh->dev;
440
        struct saa7146_vv *vv = dev->vv_data;
441
 
442
        const struct v4l2_queryctrl* ctrl;
443
        u32 value = 0;
444
 
445
        ctrl = ctrl_by_id(c->id);
446
        if (NULL == ctrl)
447
                return -EINVAL;
448
        switch (c->id) {
449
        case V4L2_CID_BRIGHTNESS:
450
                value = saa7146_read(dev, BCS_CTRL);
451
                c->value = 0xff & (value >> 24);
452
                DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value));
453
                break;
454
        case V4L2_CID_CONTRAST:
455
                value = saa7146_read(dev, BCS_CTRL);
456
                c->value = 0x7f & (value >> 16);
457
                DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value));
458
                break;
459
        case V4L2_CID_SATURATION:
460
                value = saa7146_read(dev, BCS_CTRL);
461
                c->value = 0x7f & (value >> 0);
462
                DEB_D(("V4L2_CID_SATURATION: %d\n",c->value));
463
                break;
464
        case V4L2_CID_VFLIP:
465
                c->value = vv->vflip;
466
                DEB_D(("V4L2_CID_VFLIP: %d\n",c->value));
467
                break;
468
        case V4L2_CID_HFLIP:
469
                c->value = vv->hflip;
470
                DEB_D(("V4L2_CID_HFLIP: %d\n",c->value));
471
                break;
472
        default:
473
                return -EINVAL;
474
        }
475
 
476
        return 0;
477
}
478
 
479
static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
480
{
481
        struct saa7146_dev *dev = fh->dev;
482
        struct saa7146_vv *vv = dev->vv_data;
483
 
484
        const struct v4l2_queryctrl* ctrl;
485
        unsigned long flags;
486
        int restart_overlay = 0;
487
 
488
        ctrl = ctrl_by_id(c->id);
489
        if (NULL == ctrl) {
490
                DEB_D(("unknown control %d\n",c->id));
491
                return -EINVAL;
492
        }
493
 
494
        switch (ctrl->type) {
495
        case V4L2_CTRL_TYPE_BOOLEAN:
496
        case V4L2_CTRL_TYPE_MENU:
497
        case V4L2_CTRL_TYPE_INTEGER:
498
                if (c->value < ctrl->minimum)
499
                        c->value = ctrl->minimum;
500
                if (c->value > ctrl->maximum)
501
                        c->value = ctrl->maximum;
502
                break;
503
        default:
504
                /* nothing */;
505
        };
506
 
507
        switch (c->id) {
508
        case V4L2_CID_BRIGHTNESS: {
509
                u32 value = saa7146_read(dev, BCS_CTRL);
510
                value &= 0x00ffffff;
511
                value |= (c->value << 24);
512
                saa7146_write(dev, BCS_CTRL, value);
513
                saa7146_write(dev, MC2, MASK_22 | MASK_06 );
514
                break;
515
        }
516
        case V4L2_CID_CONTRAST: {
517
                u32 value = saa7146_read(dev, BCS_CTRL);
518
                value &= 0xff00ffff;
519
                value |= (c->value << 16);
520
                saa7146_write(dev, BCS_CTRL, value);
521
                saa7146_write(dev, MC2, MASK_22 | MASK_06 );
522
                break;
523
        }
524
        case V4L2_CID_SATURATION: {
525
                u32 value = saa7146_read(dev, BCS_CTRL);
526
                value &= 0xffffff00;
527
                value |= (c->value << 0);
528
                saa7146_write(dev, BCS_CTRL, value);
529
                saa7146_write(dev, MC2, MASK_22 | MASK_06 );
530
                break;
531
        }
532
        case V4L2_CID_HFLIP:
533
                /* fixme: we can supfhrt changing VFLIP and HFLIP here... */
534
                if( 0 != vv->streaming ) {
535
                        DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
536
                        return -EINVAL;
537
                }
538
                vv->hflip = c->value;
539
                restart_overlay = 1;
540
                break;
541
        case V4L2_CID_VFLIP:
542
                if( 0 != vv->streaming ) {
543
                        DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
544
                        return -EINVAL;
545
                }
546
                vv->vflip = c->value;
547
                restart_overlay = 1;
548
                break;
549
        default: {
550
                return -EINVAL;
551
        }
552
        }
553
        if( 0 != restart_overlay ) {
554
                if( 0 != vv->ov_data ) {
555
                        if( fh == vv->ov_data->fh ) {
556
                                spin_lock_irqsave(&dev->slock,flags);
557
                                saa7146_stop_preview(fh);
558
                                saa7146_start_preview(fh);
559
                                spin_unlock_irqrestore(&dev->slock,flags);
560
                        }
561
                }
562
        }
563
        return 0;
564
}
565
 
566
/********************************************************************************/
567
/* common pagetable functions */
568
 
569
static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
570
{
571
        struct pci_dev *pci = dev->pci;
572
        struct scatterlist *list = buf->vb.dma.sglist;
573
        int length = buf->vb.dma.sglen;
574
        struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
575
 
576
        DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
577
 
578
        if( 0 != IS_PLANAR(sfmt->trans)) {
579
                struct saa7146_pgtable *pt1 = &buf->pt[0];
580
                struct saa7146_pgtable *pt2 = &buf->pt[1];
581
                struct saa7146_pgtable *pt3 = &buf->pt[2];
582
                u32  *ptr1, *ptr2, *ptr3;
583
                u32 fill;
584
 
585
                int size = buf->fmt->width*buf->fmt->height;
586
                int i,p,m1,m2,m3,o1,o2;
587
 
588
                switch( sfmt->depth ) {
589
                        case 12: {
590
                                /* create some offsets inside the page table */
591
                                m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
592
                                m2 = ((size+(size/4)+PAGE_SIZE)/PAGE_SIZE)-1;
593
                                m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
594
                                o1 = size%PAGE_SIZE;
595
                                o2 = (size+(size/4))%PAGE_SIZE;
596
                                DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
597
                                break;
598
                        }
599
                        case 16: {
600
                                /* create some offsets inside the page table */
601
                                m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
602
                                m2 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
603
                                m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1;
604
                                o1 = size%PAGE_SIZE;
605
                                o2 = (size+(size/2))%PAGE_SIZE;
606
                                DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
607
                                break;
608
                        }
609
                        default: {
610
                                return -1;
611
                        }
612
                }
613
 
614
                ptr1 = pt1->cpu;
615
                ptr2 = pt2->cpu;
616
                ptr3 = pt3->cpu;
617
 
618
                /* walk all pages, copy all page addresses to ptr1 */
619
                for (i = 0; i < length; i++, list++) {
620
                        for (p = 0; p * 4096 < list->length; p++, ptr1++) {
621
                                *ptr1 = sg_dma_address(list) - list->offset;
622
                        }
623
                }
624
/*
625
                ptr1 = pt1->cpu;
626
                for(j=0;j<40;j++) {
627
                        printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
628
                }
629
*/             
630
 
631
                /* if we have a user buffer, the first page may not be
632
                   aligned to a page boundary. */
633
                pt1->offset = buf->vb.dma.sglist->offset;
634
                pt2->offset = pt1->offset+o1;
635
                pt3->offset = pt1->offset+o2;
636
 
637
                /* create video-dma2 page table */
638
                ptr1 = pt1->cpu;
639
                for(i = m1; i <= m2 ; i++, ptr2++) {
640
                        *ptr2 = ptr1[i];
641
                }
642
                fill = *(ptr2-1);
643
                for(;i<1024;i++,ptr2++) {
644
                        *ptr2 = fill;
645
                }
646
                /* create video-dma3 page table */
647
                ptr1 = pt1->cpu;
648
                for(i = m2; i <= m3; i++,ptr3++) {
649
                        *ptr3 = ptr1[i];
650
                }
651
                fill = *(ptr3-1);
652
                for(;i<1024;i++,ptr3++) {
653
                        *ptr3 = fill;
654
                }
655
                /* finally: finish up video-dma1 page table */         
656
                ptr1 = pt1->cpu+m1;
657
                fill = pt1->cpu[m1];
658
                for(i=m1;i<1024;i++,ptr1++) {
659
                        *ptr1 = fill;
660
                }
661
/*
662
                ptr1 = pt1->cpu;
663
                ptr2 = pt2->cpu;
664
                ptr3 = pt3->cpu;
665
                for(j=0;j<40;j++) {
666
                        printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
667
                }
668
                for(j=0;j<40;j++) {
669
                        printk("ptr2 %d: 0x%08x\n",j,ptr2[j]);
670
                }
671
                for(j=0;j<40;j++) {
672
                        printk("ptr3 %d: 0x%08x\n",j,ptr3[j]);
673
                }
674
*/                             
675
        } else {
676
                struct saa7146_pgtable *pt = &buf->pt[0];
677
                return saa7146_pgtable_build_single(pci, pt, list, length);
678
        }
679
 
680
        return 0;
681
}
682
 
683
 
684
/********************************************************************************/
685
/* file operations */
686
 
687
static int video_begin(struct saa7146_fh *fh)
688
{
689
        struct saa7146_dev *dev = fh->dev;
690
        struct saa7146_vv *vv = dev->vv_data;
691
        struct saa7146_format *fmt = NULL;
692
        unsigned long flags;
693
        unsigned int resource;
694
        int ret = 0;
695
 
696
        DEB_EE(("dev:%p, fh:%p\n",dev,fh));
697
 
698
        if( fh == vv->streaming ) {
699
                DEB_S(("already capturing.\n"));
700
                return -EBUSY;
701
        }
702
        if( vv->streaming != 0 ) {
703
                DEB_S(("already capturing, but in another open.\n"));
704
                return -EBUSY;
705
        }
706
 
707
        fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
708
        /* we need to have a valid format set here */
709
        BUG_ON(NULL == fmt);
710
 
711
        if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
712
                resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
713
        } else {
714
                resource = RESOURCE_DMA1_HPS;
715
        }
716
 
717
        ret = saa7146_res_get(fh, resource);
718
        if (0 == ret) {
719
                DEB_S(("cannot get capture resource %d\n",resource));
720
                return -EBUSY;
721
        }
722
 
723
        spin_lock_irqsave(&dev->slock,flags);
724
 
725
        /* clear out beginning of streaming bit (rps register 0)*/
726
        saa7146_write(dev, MC2, MASK_27 );
727
 
728
        /* enable rps0 irqs */
729
        IER_ENABLE(dev, MASK_27);
730
 
731
        vv->streaming = fh;
732
        spin_unlock_irqrestore(&dev->slock,flags);
733
        return 0;
734
}
735
 
736
static int video_end(struct saa7146_fh *fh, struct file *file)
737
{
738
        struct saa7146_dev *dev = fh->dev;
739
        struct saa7146_vv *vv = dev->vv_data;
740
        struct saa7146_format *fmt = NULL;
741
        unsigned long flags;
742
        unsigned int resource;
743
        u32 dmas = 0;
744
        DEB_EE(("dev:%p, fh:%p\n",dev,fh));
745
 
746
        if( vv->streaming != fh ) {
747
                DEB_S(("not capturing.\n"));
748
                return -EINVAL;
749
        }
750
 
751
        fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
752
        /* we need to have a valid format set here */
753
        BUG_ON(NULL == fmt);
754
 
755
        if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
756
                resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
757
                dmas = 0x00700000;
758
        } else {
759
                resource = RESOURCE_DMA1_HPS;
760
                dmas = 0x00100000;
761
        }
762
        saa7146_res_free(fh, resource);
763
 
764
        spin_lock_irqsave(&dev->slock,flags);
765
 
766
        /* disable rps0  */
767
        saa7146_write(dev, MC1, MASK_28);
768
 
769
        /* disable rps0 irqs */
770
        IER_DISABLE(dev, MASK_27);
771
 
772
        /* shut down all used video dma transfers */
773
        saa7146_write(dev, MC1, dmas);
774
 
775
        vv->streaming = NULL;
776
 
777
        spin_unlock_irqrestore(&dev->slock, flags);
778
 
779
        return 0;
780
}
781
 
782
/*
783
 * This function is _not_ called directly, but from
784
 * video_generic_ioctl (and maybe others).  userspace
785
 * copying is done already, arg is a kernel pointer.
786
 */
787
 
788
int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
789
{
790
        struct saa7146_fh *fh  = file->private_data;
791
        struct saa7146_dev *dev = fh->dev;
792
        struct saa7146_vv *vv = dev->vv_data;
793
 
794
        unsigned long flags;
795
        int err = 0, result = 0, ee = 0;
796
 
797
        struct saa7146_use_ops *ops;
798
        struct videobuf_queue *q;
799
 
800
        /* check if extension handles the command */
801
        for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) {
802
                if( cmd == dev->ext_vv_data->ioctls[ee].cmd )
803
                        break;
804
        }
805
 
806
        if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
807
                DEB_D(("extension handles ioctl exclusive.\n"));
808
                result = dev->ext_vv_data->ioctl(fh, cmd, arg);
809
                return result;
810
        }
811
        if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
812
                DEB_D(("extension handles ioctl before.\n"));
813
                result = dev->ext_vv_data->ioctl(fh, cmd, arg);
814
                if( -EAGAIN != result ) {
815
                        return result;
816
                }
817
        }
818
 
819
        /* fixme: add handle "after" case (is it still needed?) */
820
 
821
        switch (fh->type) {
822
        case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
823
                ops = &saa7146_video_uops;
824
                q = &fh->video_q;
825
                break;
826
                }
827
        case V4L2_BUF_TYPE_VBI_CAPTURE: {
828
                ops = &saa7146_vbi_uops;
829
                q = &fh->vbi_q;
830
                break;
831
                }
832
        default:
833
                BUG();
834
                return 0;
835
        }
836
 
837
        switch (cmd) {
838
        case VIDIOC_QUERYCAP:
839
        {
840
                struct v4l2_capability *cap = arg;
841
                memset(cap,0,sizeof(*cap));
842
 
843
                DEB_EE(("VIDIOC_QUERYCAP\n"));
844
 
845
                strcpy(cap->driver, "saa7146 v4l2");
846
                strlcpy(cap->card, dev->ext->name, sizeof(cap->card));
773 giacomo 847
                sprintf26(cap->bus_info,"PCI:%s",dev->pci->slot_name);
425 giacomo 848
                cap->version = SAA7146_VERSION_CODE;
849
                cap->capabilities =
850
                        V4L2_CAP_VIDEO_CAPTURE |
851
                        V4L2_CAP_VIDEO_OVERLAY |
852
                        V4L2_CAP_READWRITE |
853
                        V4L2_CAP_STREAMING;
854
                cap->capabilities |= dev->ext_vv_data->capabilities;
855
                return 0;
856
        }
857
        case VIDIOC_G_FBUF:
858
        {
859
                struct v4l2_framebuffer *fb = arg;
860
 
861
                DEB_EE(("VIDIOC_G_FBUF\n"));
862
 
863
                *fb = vv->ov_fb;
864
                fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
865
                return 0;
866
        }
867
        case VIDIOC_S_FBUF:
868
        {
869
                struct v4l2_framebuffer *fb = arg;
870
                struct saa7146_format *fmt;
871
                struct saa7146_fh *ov_fh = NULL;
872
                int restart_overlay = 0;
873
 
874
                DEB_EE(("VIDIOC_S_FBUF\n"));
875
/*
876
                if(!capable(CAP_SYS_ADMIN)) { // && !capable(CAP_SYS_RAWIO)) {
877
                        DEB_D(("VIDIOC_S_FBUF: not CAP_SYS_ADMIN or CAP_SYS_RAWIO.\n"));
878
                        return -EPERM;
879
                }
880
*/
881
 
882
                /* check args */
883
                fmt = format_by_fourcc(dev,fb->fmt.pixelformat);
884
                if (NULL == fmt) {
885
                        return -EINVAL;
886
                }
887
 
888
                /* planar formats are not allowed for overlay video, clipping and video dma would clash */
889
                if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
890
                        DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat));
891
                }
892
 
773 giacomo 893
                //down(&dev->lock);
425 giacomo 894
                if( vv->ov_data != NULL ) {
895
                        ov_fh = vv->ov_data->fh;
896
                        saa7146_stop_preview(ov_fh);
897
                        restart_overlay = 1;
898
                }
899
 
900
                /* ok, accept it */
901
                vv->ov_fb = *fb;
902
                vv->ov_fmt = fmt;
903
                if (0 == vv->ov_fb.fmt.bytesperline)
904
                        vv->ov_fb.fmt.bytesperline =
905
                                vv->ov_fb.fmt.width*fmt->depth/8;
906
 
907
                if( 0 != restart_overlay ) {
908
                        saa7146_start_preview(ov_fh);
909
                }
910
 
773 giacomo 911
                //up(&dev->lock);
425 giacomo 912
 
913
                return 0;
914
        }
915
        case VIDIOC_ENUM_FMT:
916
        {
917
                struct v4l2_fmtdesc *f = arg;
918
                int index;
919
 
920
                switch (f->type) {
921
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
922
                case V4L2_BUF_TYPE_VIDEO_OVERLAY: {
923
                        index = f->index;
924
                        if (index < 0 || index >= NUM_FORMATS) {
925
                                return -EINVAL;
926
                        }
927
                        memset(f,0,sizeof(*f));
928
                        f->index = index;
929
                        strlcpy(f->description,formats[index].name,sizeof(f->description));
930
                        f->pixelformat = formats[index].pixelformat;
931
                        break;
932
                }
933
                default:
934
                        return -EINVAL;
935
                }
936
 
937
                DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index));
938
                return 0;
939
        }
940
        case VIDIOC_QUERYCTRL:
941
        {
942
                const struct v4l2_queryctrl *ctrl;
943
                struct v4l2_queryctrl *c = arg;
944
 
945
                if ((c->id <  V4L2_CID_BASE ||
946
                     c->id >= V4L2_CID_LASTP1) &&
947
                    (c->id <  V4L2_CID_PRIVATE_BASE ||
948
                     c->id >= V4L2_CID_PRIVATE_LASTP1))
949
                        return -EINVAL;
950
 
951
                ctrl = ctrl_by_id(c->id);
952
                if( NULL == ctrl ) {
953
                        return -EINVAL;
954
/*
955
                        c->flags = V4L2_CTRL_FLAG_DISABLED;    
956
                        return 0;
957
*/
958
                }
959
 
960
                DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id));
961
                *c = *ctrl;
962
                return 0;
963
        }
964
        case VIDIOC_G_CTRL: {
965
                DEB_EE(("VIDIOC_G_CTRL\n"));
966
                return get_control(fh,arg);
967
        }
968
        case VIDIOC_S_CTRL:
969
/* FIXME: remove when videodev2.h update is in kernel */
970
#ifdef VIDIOC_S_CTRL_OLD
971
        case VIDIOC_S_CTRL_OLD:
972
#endif
973
        {
974
                DEB_EE(("VIDIOC_S_CTRL\n"));
773 giacomo 975
                //down(&dev->lock);
425 giacomo 976
                err = set_control(fh,arg);
773 giacomo 977
                //up(&dev->lock);
425 giacomo 978
                return err;
979
        }
980
        case VIDIOC_G_PARM:
981
        {
982
                struct v4l2_streamparm *parm = arg;
983
                if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) {
984
                        return -EINVAL;
985
                }
986
                memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm));
987
                parm->parm.capture.readbuffers = 1;
988
                // fixme: only for PAL!
989
                parm->parm.capture.timeperframe.numerator = 1;
990
                parm->parm.capture.timeperframe.denominator = 25;
991
                return 0;
992
        }
993
        case VIDIOC_G_FMT:
994
        {
995
                struct v4l2_format *f = arg;
996
                DEB_EE(("VIDIOC_G_FMT\n"));
997
                return g_fmt(fh,f);
998
        }
999
        case VIDIOC_S_FMT:
1000
        {
1001
                struct v4l2_format *f = arg;
1002
                DEB_EE(("VIDIOC_S_FMT\n"));
1003
                return s_fmt(fh,f);
1004
        }
1005
        case VIDIOC_TRY_FMT:
1006
        {
1007
                struct v4l2_format *f = arg;
1008
                DEB_EE(("VIDIOC_TRY_FMT\n"));
1009
                return try_fmt(fh,f);
1010
        }
1011
        case VIDIOC_G_STD:
1012
        {
1013
                v4l2_std_id *id = arg;
1014
                DEB_EE(("VIDIOC_G_STD\n"));
1015
                *id = vv->standard->id;
1016
                return 0;
1017
        }
1018
        /* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
1019
           PAL / NTSC / SECAM. if your hardware does not (or does more)
1020
           -- override this function in your extension */
1021
        case VIDIOC_ENUMSTD:
1022
        {
1023
                struct v4l2_standard *e = arg;
1024
                if (e->index < 0 )
1025
                        return -EINVAL;
1026
                if( e->index < dev->ext_vv_data->num_stds ) {
1027
                        DEB_EE(("VIDIOC_ENUMSTD: index:%d\n",e->index));
1028
                        v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name);
1029
                        return 0;
1030
                }
1031
                return -EINVAL;
1032
        }
1033
        case VIDIOC_S_STD:
1034
        {
1035
                v4l2_std_id *id = arg;
1036
                int i;
1037
 
1038
                int restart_overlay = 0;
1039
                int found = 0;
1040
 
1041
                struct saa7146_fh *ov_fh = NULL;
1042
 
1043
                DEB_EE(("VIDIOC_S_STD\n"));
1044
 
1045
                if( 0 != vv->streaming ) {
1046
                        return -EBUSY;
1047
                }
1048
 
1049
                DEB_D(("before getting lock...\n"));
773 giacomo 1050
                //down(&dev->lock);
425 giacomo 1051
                DEB_D(("got lock\n"));
1052
 
1053
                if( vv->ov_data != NULL ) {
1054
                        ov_fh = vv->ov_data->fh;
1055
                        saa7146_stop_preview(ov_fh);
1056
                        restart_overlay = 1;
1057
                }
1058
 
1059
                for(i = 0; i < dev->ext_vv_data->num_stds; i++)
1060
                        if (*id & dev->ext_vv_data->stds[i].id)
1061
                                break;
1062
                if (i != dev->ext_vv_data->num_stds) {
1063
                        vv->standard = &dev->ext_vv_data->stds[i];
1064
                        if( NULL != dev->ext_vv_data->std_callback )
1065
                                dev->ext_vv_data->std_callback(dev, vv->standard);
1066
                        found = 1;
1067
                }
1068
 
1069
                if( 0 != restart_overlay ) {
1070
                        saa7146_start_preview(ov_fh);
1071
                }
773 giacomo 1072
                //up(&dev->lock);
425 giacomo 1073
 
1074
                if( 0 == found ) {
1075
                        DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
1076
                        return -EINVAL;
1077
                }
1078
 
1079
                DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name));
1080
                return 0;
1081
        }
1082
        case VIDIOC_OVERLAY:
1083
/* FIXME: remove when videodev2.h update is in kernel */
1084
#ifdef VIDIOC_OVERLAY_OLD
1085
        case VIDIOC_OVERLAY_OLD:
1086
#endif
1087
        {
1088
                int on = *(int *)arg;
1089
                int err = 0;
1090
 
1091
                if( NULL == vv->ov_fmt && on != 0 ) {
1092
                        DEB_D(("VIDIOC_OVERLAY: no framebuffer informations. call S_FBUF first!\n"));
1093
                        return -EAGAIN;
1094
                }
1095
 
1096
                DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
1097
                if( 0 != on ) {
1098
                        if( vv->ov_data != NULL ) {
1099
                                if( fh != vv->ov_data->fh) {
1100
                                        DEB_D(("overlay already active in another open\n"));
1101
                                        return -EAGAIN;
1102
                                }
1103
                        }
1104
 
1105
                        if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
1106
                                DEB_D(("cannot get overlay resources\n"));
1107
                                return -EBUSY;
1108
                        }
1109
 
1110
                        spin_lock_irqsave(&dev->slock,flags);
1111
                        err = saa7146_start_preview(fh);
1112
                        spin_unlock_irqrestore(&dev->slock,flags);
1113
                        return err;
1114
                }
1115
 
1116
                if( vv->ov_data != NULL ) {
1117
                        if( fh != vv->ov_data->fh) {
1118
                                DEB_D(("overlay is active, but in another open\n"));
1119
                                return -EAGAIN;
1120
                        }
1121
                }
1122
                spin_lock_irqsave(&dev->slock,flags);
1123
                err = saa7146_stop_preview(fh);
1124
                spin_unlock_irqrestore(&dev->slock,flags);
1125
                /* free resources */
1126
                saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
1127
                return err;
1128
        }
1129
        case VIDIOC_REQBUFS: {
1130
                struct v4l2_requestbuffers *req = arg;
1131
                DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type));
1132
                return videobuf_reqbufs(file,q,req);
1133
        }
1134
        case VIDIOC_QUERYBUF: {
1135
                struct v4l2_buffer *buf = arg;
1136
                DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset));
1137
                return videobuf_querybuf(q,buf);
1138
        }
1139
        case VIDIOC_QBUF: {
1140
                struct v4l2_buffer *buf = arg;
1141
                int ret = 0;
1142
                ret = videobuf_qbuf(file,q,buf);
1143
                DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index));
1144
                return ret;
1145
        }
1146
        case VIDIOC_DQBUF: {
1147
                struct v4l2_buffer *buf = arg;
1148
                int ret = 0;
1149
                ret = videobuf_dqbuf(file,q,buf);
1150
                DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index));
1151
                return ret;
1152
        }
1153
        case VIDIOC_STREAMON: {
1154
                int *type = arg;
1155
                DEB_D(("VIDIOC_STREAMON, type:%d\n",*type));
1156
 
1157
                if( fh == vv->streaming ) {
1158
                        DEB_D(("already capturing.\n"));
1159
                        return 0;
1160
                }
1161
 
1162
                err = video_begin(fh);
1163
                if( 0 != err) {
1164
                        return err;
1165
                }
1166
                err = videobuf_streamon(file,q);
1167
                return err;
1168
        }
1169
        case VIDIOC_STREAMOFF: {
1170
                int *type = arg;
1171
 
1172
                DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type));
1173
 
1174
                if( fh != vv->streaming ) {
1175
                        DEB_D(("this open is not capturing.\n"));
1176
                        return -EINVAL;
1177
                }
1178
 
1179
                err = videobuf_streamoff(file,q);
1180
                video_end(fh, file);
1181
                return err;
1182
        }
1183
        case VIDIOCGMBUF:
1184
        {
1185
                struct video_mbuf *mbuf = arg;
1186
                struct videobuf_queue *q;
1187
                int i;
1188
 
1189
                /* fixme: number of capture buffers and sizes for v4l apps */
1190
                int gbuffers = 2;
1191
                int gbufsize = 768*576*4;
1192
 
1193
                DEB_D(("VIDIOCGMBUF \n"));
1194
 
1195
                q = &fh->video_q;
773 giacomo 1196
                //down(&q->lock);
425 giacomo 1197
                err = videobuf_mmap_setup(file,q,gbuffers,gbufsize,
1198
                                          V4L2_MEMORY_MMAP);
1199
                if (err < 0) {
773 giacomo 1200
                        //up(&q->lock);
425 giacomo 1201
                        return err;
1202
                }
1203
                memset(mbuf,0,sizeof(*mbuf));
1204
                mbuf->frames = gbuffers;
1205
                mbuf->size   = gbuffers * gbufsize;
1206
                for (i = 0; i < gbuffers; i++)
1207
                        mbuf->offsets[i] = i * gbufsize;
773 giacomo 1208
                //up(&q->lock);
425 giacomo 1209
                return 0;
1210
        }
1211
        default:
1212
                return v4l_compat_translate_ioctl(inode,file,cmd,arg,
1213
                                                  saa7146_video_do_ioctl);
1214
        }
1215
        return 0;
1216
}
1217
 
1218
/*********************************************************************************/
1219
/* buffer handling functions                                                  */
1220
 
1221
static int buffer_activate (struct saa7146_dev *dev,
1222
                     struct saa7146_buf *buf,
1223
                     struct saa7146_buf *next)
1224
{
1225
        struct saa7146_vv *vv = dev->vv_data;
1226
 
1227
        buf->vb.state = STATE_ACTIVE;
1228
        saa7146_set_capture(dev,buf,next);
1229
 
1230
        mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT);
1231
        return 0;
1232
}
1233
 
1234
static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, enum v4l2_field field)
1235
{
1236
        struct saa7146_fh *fh = file->private_data;
1237
        struct saa7146_dev *dev = fh->dev;
1238
        struct saa7146_vv *vv = dev->vv_data;
1239
        struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1240
        int size,err = 0;
1241
 
1242
        DEB_CAP(("vbuf:%p\n",vb));
1243
 
1244
        /* sanity checks */
1245
        if (fh->video_fmt.width  < 48 ||
1246
            fh->video_fmt.height < 32 ||
1247
            fh->video_fmt.width  > vv->standard->h_max_out ||
1248
            fh->video_fmt.height > vv->standard->v_max_out) {
1249
                DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height));
1250
                return -EINVAL;
1251
        }
1252
 
1253
        size = fh->video_fmt.sizeimage;
1254
        if (0 != buf->vb.baddr && buf->vb.bsize < size) {
1255
                DEB_D(("size mismatch.\n"));
1256
                return -EINVAL;
1257
        }
1258
 
1259
        DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
1260
                fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
1261
        if (buf->vb.width  != fh->video_fmt.width  ||
1262
            buf->vb.bytesperline != fh->video_fmt.bytesperline ||
1263
            buf->vb.height != fh->video_fmt.height ||
1264
            buf->vb.size   != size ||
1265
            buf->vb.field  != field      ||
1266
            buf->vb.field  != fh->video_fmt.field  ||
1267
            buf->fmt       != &fh->video_fmt) {
1268
                saa7146_dma_free(dev,buf);
1269
        }
1270
 
1271
        if (STATE_NEEDS_INIT == buf->vb.state) {
1272
                struct saa7146_format *sfmt;
1273
 
1274
                buf->vb.bytesperline  = fh->video_fmt.bytesperline;
1275
                buf->vb.width  = fh->video_fmt.width;
1276
                buf->vb.height = fh->video_fmt.height;
1277
                buf->vb.size   = size;
1278
                buf->vb.field  = field;
1279
                buf->fmt       = &fh->video_fmt;
1280
                buf->vb.field  = fh->video_fmt.field;
1281
 
1282
                sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
1283
 
1284
                if( 0 != IS_PLANAR(sfmt->trans)) {
1285
                        saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1286
                        saa7146_pgtable_free(dev->pci, &buf->pt[1]);
1287
                        saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1288
 
1289
                        saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1290
                        saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
1291
                        saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
1292
                } else {
1293
                        saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1294
                        saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1295
                }
1296
 
1297
                err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
1298
                if (err)
1299
                        goto oops;
1300
                err = saa7146_pgtable_build(dev,buf);
1301
                if (err)
1302
                        goto oops;
1303
        }
1304
        buf->vb.state = STATE_PREPARED;
1305
        buf->activate = buffer_activate;
1306
 
1307
        return 0;
1308
 
1309
 oops:
1310
        DEB_D(("error out.\n"));
1311
        saa7146_dma_free(dev,buf);
1312
 
1313
        return err;
1314
}
1315
 
1316
static int buffer_setup(struct file *file, unsigned int *count, unsigned int *size)
1317
{
1318
        struct saa7146_fh *fh = file->private_data;
1319
 
1320
        if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
1321
                *count = MAX_SAA7146_CAPTURE_BUFFERS;
1322
 
1323
        *size = fh->video_fmt.sizeimage;
1324
 
1325
        /* check if we exceed the "memory" parameter */
1326
        if( (*count * *size) > (memory*1048576) ) {
1327
                *count = (memory*1048576) / *size;
1328
        }
1329
 
1330
        DEB_CAP(("%d buffers, %d bytes each.\n",*count,*size));
1331
 
1332
        return 0;
1333
}
1334
 
1335
static void buffer_queue(struct file *file, struct videobuf_buffer *vb)
1336
{
1337
        struct saa7146_fh *fh = file->private_data;
1338
        struct saa7146_dev *dev = fh->dev;
1339
        struct saa7146_vv *vv = dev->vv_data;
1340
        struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1341
 
1342
        DEB_CAP(("vbuf:%p\n",vb));
1343
        saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
1344
}
1345
 
1346
 
1347
static void buffer_release(struct file *file, struct videobuf_buffer *vb)
1348
{
1349
        struct saa7146_fh *fh = file->private_data;
1350
        struct saa7146_dev *dev = fh->dev;
1351
        struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1352
 
1353
        DEB_CAP(("vbuf:%p\n",vb));
1354
        saa7146_dma_free(dev,buf);
1355
}
1356
 
1357
static struct videobuf_queue_ops video_qops = {
1358
        .buf_setup    = buffer_setup,
1359
        .buf_prepare  = buffer_prepare,
1360
        .buf_queue    = buffer_queue,
1361
        .buf_release  = buffer_release,
1362
};
1363
 
1364
/********************************************************************************/
1365
/* file operations */
1366
 
1367
static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1368
{
1369
        INIT_LIST_HEAD(&vv->video_q.queue);
1370
 
1371
        init_timer(&vv->video_q.timeout);
1372
        vv->video_q.timeout.function = saa7146_buffer_timeout;
1373
        vv->video_q.timeout.data     = (unsigned long)(&vv->video_q);
1374
        vv->video_q.dev              = dev;
1375
 
1376
        /* set some default values */
1377
        vv->standard = &dev->ext_vv_data->stds[0];
1378
 
1379
        /* FIXME: what's this? */
1380
        vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
1381
        vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
1382
}
1383
 
1384
 
1385
static int video_open(struct saa7146_dev *dev, struct file *file)
1386
{
1387
        struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
1388
        struct saa7146_format *sfmt;
1389
 
1390
        fh->video_fmt.width = 384;
1391
        fh->video_fmt.height = 288;
1392
        fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
1393
        fh->video_fmt.bytesperline = 0;
1394
        fh->video_fmt.field = V4L2_FIELD_ANY;
1395
        sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
1396
        fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
1397
 
1398
        videobuf_queue_init(&fh->video_q, &video_qops,
1399
                            dev->pci, &dev->slock,
1400
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
1401
                            V4L2_FIELD_INTERLACED,
1402
                            sizeof(struct saa7146_buf));
1403
 
1404
        init_MUTEX(&fh->video_q.lock);
1405
 
1406
        return 0;
1407
}
1408
 
1409
 
1410
static void video_close(struct saa7146_dev *dev, struct file *file)
1411
{
1412
        struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
1413
        struct saa7146_vv *vv = dev->vv_data;
1414
        unsigned long flags;
1415
 
1416
        if( 0 != vv->ov_data ) {
1417
                if( fh == vv->ov_data->fh ) {
1418
                        spin_lock_irqsave(&dev->slock,flags);
1419
                        saa7146_stop_preview(fh);
1420
                        spin_unlock_irqrestore(&dev->slock,flags);
1421
                }
1422
        }
1423
 
1424
        if( fh == vv->streaming ) {
1425
                video_end(fh, file);           
1426
        }
1427
}
1428
 
1429
 
1430
static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
1431
{
1432
        struct saa7146_vv *vv = dev->vv_data;
1433
        struct saa7146_dmaqueue *q = &vv->video_q;
1434
 
1435
        spin_lock(&dev->slock);
1436
        DEB_CAP(("called.\n"));
1437
 
1438
        /* only finish the buffer if we have one... */
1439
        if( NULL != q->curr ) {
1440
                saa7146_buffer_finish(dev,q,STATE_DONE);
1441
        }
1442
        saa7146_buffer_next(dev,q,0);
1443
 
1444
        spin_unlock(&dev->slock);
1445
}
1446
 
1447
static ssize_t video_read(struct file *file, char *data, size_t count, loff_t *ppos)
1448
{
1449
        struct saa7146_fh *fh = file->private_data;
1450
        struct saa7146_dev *dev = fh->dev;
1451
        struct saa7146_vv *vv = dev->vv_data;
1452
        ssize_t ret = 0;
1453
 
1454
        int restart_overlay = 0;
1455
        struct saa7146_fh *ov_fh = NULL;
1456
 
1457
        DEB_EE(("called.\n"));
1458
 
1459
        /* fixme: should we allow read() captures while streaming capture? */
1460
        if( 0 != vv->streaming ) {
1461
                DEB_S(("already capturing.\n"));
1462
                return -EBUSY;
1463
        }
1464
 
1465
        /* stop any active overlay */
1466
        if( vv->ov_data != NULL ) {
1467
                ov_fh = vv->ov_data->fh;
1468
                saa7146_stop_preview(ov_fh);
1469
                saa7146_res_free(ov_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
1470
                restart_overlay = 1;
1471
        }
1472
 
1473
        ret = video_begin(fh);
1474
        if( 0 != ret) {
1475
                goto out;
1476
        }
1477
 
1478
        ret = videobuf_read_one(file,&fh->video_q , data, count, ppos);
1479
        video_end(fh, file);
1480
 
1481
out:
1482
        /* restart overlay if it was active before */
1483
        if( 0 != restart_overlay ) {
1484
                if (0 == saa7146_res_get(ov_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
1485
                        DEB_D(("cannot get overlay resources again!\n"));
1486
                        BUG();
1487
                }
1488
                saa7146_start_preview(ov_fh);
1489
        }
1490
 
1491
        return ret;
1492
}
1493
 
1494
struct saa7146_use_ops saa7146_video_uops = {
1495
        .init = video_init,
1496
        .open = video_open,
1497
        .release = video_close,
1498
        .irq_done = video_irq_done,
1499
        .read = video_read,
1500
};