OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [media/] [video/] [v4l1-compat.c] - Blame information for rev 78

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *
3
 *      Video for Linux Two
4
 *      Backward Compatibility Layer
5
 *
6
 *      Support subroutines for providing V4L2 drivers with backward
7
 *      compatibility with applications using the old API.
8
 *
9
 *      This program is free software; you can redistribute it and/or
10
 *      modify it under the terms of the GNU General Public License
11
 *      as published by the Free Software Foundation; either version
12
 *      2 of the License, or (at your option) any later version.
13
 *
14
 * Author:      Bill Dirks <bill@thedirks.org>
15
 *              et al.
16
 *
17
 */
18
 
19
 
20
#include <linux/init.h>
21
#include <linux/module.h>
22
#include <linux/types.h>
23
#include <linux/kernel.h>
24
#include <linux/sched.h>
25
#include <linux/mm.h>
26
#include <linux/fs.h>
27
#include <linux/file.h>
28
#include <linux/string.h>
29
#include <linux/errno.h>
30
#include <linux/slab.h>
31
#include <linux/videodev.h>
32
#include <media/v4l2-common.h>
33
 
34
#include <asm/uaccess.h>
35
#include <asm/system.h>
36
#include <asm/pgtable.h>
37
 
38
#ifdef CONFIG_KMOD
39
#include <linux/kmod.h>
40
#endif
41
 
42
static unsigned int debug  = 0;
43
module_param(debug, int, 0644);
44
MODULE_PARM_DESC(debug,"enable debug messages");
45
MODULE_AUTHOR("Bill Dirks");
46
MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
47
MODULE_LICENSE("GPL");
48
 
49
#define dprintk(fmt, arg...)    if (debug) \
50
        printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg)
51
 
52
/*
53
 *      I O C T L   T R A N S L A T I O N
54
 *
55
 *      From here on down is the code for translating the numerous
56
 *      ioctl commands from the old API to the new API.
57
 */
58
 
59
static int
60
get_v4l_control(struct inode            *inode,
61
                struct file             *file,
62
                int                     cid,
63
                v4l2_kioctl             drv)
64
{
65
        struct v4l2_queryctrl   qctrl2;
66
        struct v4l2_control     ctrl2;
67
        int                     err;
68
 
69
        qctrl2.id = cid;
70
        err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
71
        if (err < 0)
72
                dprintk("VIDIOC_QUERYCTRL: %d\n",err);
73
        if (err == 0 &&
74
            !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
75
        {
76
                ctrl2.id = qctrl2.id;
77
                err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2);
78
                if (err < 0) {
79
                        dprintk("VIDIOC_G_CTRL: %d\n",err);
80
                        return 0;
81
                }
82
                return ((ctrl2.value - qctrl2.minimum) * 65535
83
                         + (qctrl2.maximum - qctrl2.minimum) / 2)
84
                        / (qctrl2.maximum - qctrl2.minimum);
85
        }
86
        return 0;
87
}
88
 
89
static int
90
set_v4l_control(struct inode            *inode,
91
                struct file             *file,
92
                int                     cid,
93
                int                     value,
94
                v4l2_kioctl             drv)
95
{
96
        struct v4l2_queryctrl   qctrl2;
97
        struct v4l2_control     ctrl2;
98
        int                     err;
99
 
100
        qctrl2.id = cid;
101
        err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
102
        if (err < 0)
103
                dprintk("VIDIOC_QUERYCTRL: %d\n",err);
104
        if (err == 0 &&
105
            !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
106
            !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED))
107
        {
108
                if (value < 0)
109
                        value = 0;
110
                if (value > 65535)
111
                        value = 65535;
112
                if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
113
                        value = 65535;
114
                ctrl2.id = qctrl2.id;
115
                ctrl2.value =
116
                        (value * (qctrl2.maximum - qctrl2.minimum)
117
                         + 32767)
118
                        / 65535;
119
                ctrl2.value += qctrl2.minimum;
120
                err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2);
121
                if (err < 0)
122
                        dprintk("VIDIOC_S_CTRL: %d\n",err);
123
        }
124
        return 0;
125
}
126
 
127
/* ----------------------------------------------------------------- */
128
 
129
const static unsigned int palette2pixelformat[] = {
130
        [VIDEO_PALETTE_GREY]    = V4L2_PIX_FMT_GREY,
131
        [VIDEO_PALETTE_RGB555]  = V4L2_PIX_FMT_RGB555,
132
        [VIDEO_PALETTE_RGB565]  = V4L2_PIX_FMT_RGB565,
133
        [VIDEO_PALETTE_RGB24]   = V4L2_PIX_FMT_BGR24,
134
        [VIDEO_PALETTE_RGB32]   = V4L2_PIX_FMT_BGR32,
135
        /* yuv packed pixel */
136
        [VIDEO_PALETTE_YUYV]    = V4L2_PIX_FMT_YUYV,
137
        [VIDEO_PALETTE_YUV422]  = V4L2_PIX_FMT_YUYV,
138
        [VIDEO_PALETTE_UYVY]    = V4L2_PIX_FMT_UYVY,
139
        /* yuv planar */
140
        [VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,
141
        [VIDEO_PALETTE_YUV420]  = V4L2_PIX_FMT_YUV420,
142
        [VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,
143
        [VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,
144
        [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
145
};
146
 
147
static unsigned int __pure
148
palette_to_pixelformat(unsigned int palette)
149
{
150
        if (palette < ARRAY_SIZE(palette2pixelformat))
151
                return palette2pixelformat[palette];
152
        else
153
                return 0;
154
}
155
 
156
static unsigned int __attribute_const__
157
pixelformat_to_palette(unsigned int pixelformat)
158
{
159
        int     palette = 0;
160
        switch (pixelformat)
161
        {
162
        case V4L2_PIX_FMT_GREY:
163
                palette = VIDEO_PALETTE_GREY;
164
                break;
165
        case V4L2_PIX_FMT_RGB555:
166
                palette = VIDEO_PALETTE_RGB555;
167
                break;
168
        case V4L2_PIX_FMT_RGB565:
169
                palette = VIDEO_PALETTE_RGB565;
170
                break;
171
        case V4L2_PIX_FMT_BGR24:
172
                palette = VIDEO_PALETTE_RGB24;
173
                break;
174
        case V4L2_PIX_FMT_BGR32:
175
                palette = VIDEO_PALETTE_RGB32;
176
                break;
177
        /* yuv packed pixel */
178
        case V4L2_PIX_FMT_YUYV:
179
                palette = VIDEO_PALETTE_YUYV;
180
                break;
181
        case V4L2_PIX_FMT_UYVY:
182
                palette = VIDEO_PALETTE_UYVY;
183
                break;
184
        /* yuv planar */
185
        case V4L2_PIX_FMT_YUV410:
186
                palette = VIDEO_PALETTE_YUV420;
187
                break;
188
        case V4L2_PIX_FMT_YUV420:
189
                palette = VIDEO_PALETTE_YUV420;
190
                break;
191
        case V4L2_PIX_FMT_YUV411P:
192
                palette = VIDEO_PALETTE_YUV411P;
193
                break;
194
        case V4L2_PIX_FMT_YUV422P:
195
                palette = VIDEO_PALETTE_YUV422P;
196
                break;
197
        }
198
        return palette;
199
}
200
 
201
/* ----------------------------------------------------------------- */
202
 
203
static int poll_one(struct file *file)
204
{
205
        int retval = 1;
206
        poll_table *table;
207
        struct poll_wqueues pwq;
208
 
209
        poll_initwait(&pwq);
210
        table = &pwq.pt;
211
        for (;;) {
212
                int mask;
213
                set_current_state(TASK_INTERRUPTIBLE);
214
                mask = file->f_op->poll(file, table);
215
                if (mask & POLLIN)
216
                        break;
217
                table = NULL;
218
                if (signal_pending(current)) {
219
                        retval = -ERESTARTSYS;
220
                        break;
221
                }
222
                schedule();
223
        }
224
        set_current_state(TASK_RUNNING);
225
        poll_freewait(&pwq);
226
        return retval;
227
}
228
 
229
static int count_inputs(struct inode         *inode,
230
                        struct file          *file,
231
                        v4l2_kioctl          drv)
232
{
233
        struct v4l2_input input2;
234
        int i;
235
 
236
        for (i = 0;; i++) {
237
                memset(&input2,0,sizeof(input2));
238
                input2.index = i;
239
                if (0 != drv(inode,file,VIDIOC_ENUMINPUT, &input2))
240
                        break;
241
        }
242
        return i;
243
}
244
 
245
static int check_size(struct inode         *inode,
246
                      struct file          *file,
247
                      v4l2_kioctl          drv,
248
                      int *maxw, int *maxh)
249
{
250
        struct v4l2_fmtdesc desc2;
251
        struct v4l2_format  fmt2;
252
 
253
        memset(&desc2,0,sizeof(desc2));
254
        memset(&fmt2,0,sizeof(fmt2));
255
 
256
        desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
257
        if (0 != drv(inode,file,VIDIOC_ENUM_FMT, &desc2))
258
                goto done;
259
 
260
        fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
261
        fmt2.fmt.pix.width       = 10000;
262
        fmt2.fmt.pix.height      = 10000;
263
        fmt2.fmt.pix.pixelformat = desc2.pixelformat;
264
        if (0 != drv(inode,file,VIDIOC_TRY_FMT, &fmt2))
265
                goto done;
266
 
267
        *maxw = fmt2.fmt.pix.width;
268
        *maxh = fmt2.fmt.pix.height;
269
 
270
 done:
271
        return 0;
272
}
273
 
274
/* ----------------------------------------------------------------- */
275
 
276
/*
277
 *      This function is exported.
278
 */
279
int
280
v4l_compat_translate_ioctl(struct inode         *inode,
281
                           struct file          *file,
282
                           int                  cmd,
283
                           void                 *arg,
284
                           v4l2_kioctl          drv)
285
{
286
        struct v4l2_capability  *cap2 = NULL;
287
        struct v4l2_format      *fmt2 = NULL;
288
        enum v4l2_buf_type      captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
289
 
290
        struct v4l2_framebuffer fbuf2;
291
        struct v4l2_input       input2;
292
        struct v4l2_tuner       tun2;
293
        struct v4l2_standard    std2;
294
        struct v4l2_frequency   freq2;
295
        struct v4l2_audio       aud2;
296
        struct v4l2_queryctrl   qctrl2;
297
        struct v4l2_buffer      buf2;
298
        v4l2_std_id             sid;
299
        int i, err = 0;
300
 
301
        switch (cmd) {
302
        case VIDIOCGCAP:        /* capability */
303
        {
304
                struct video_capability *cap = arg;
305
 
306
                cap2 = kzalloc(sizeof(*cap2),GFP_KERNEL);
307
                memset(cap, 0, sizeof(*cap));
308
                memset(&fbuf2, 0, sizeof(fbuf2));
309
 
310
                err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
311
                if (err < 0) {
312
                        dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n",err);
313
                        break;
314
                }
315
                if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
316
                        err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
317
                        if (err < 0) {
318
                                dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n",err);
319
                                memset(&fbuf2, 0, sizeof(fbuf2));
320
                        }
321
                        err = 0;
322
                }
323
 
324
                memcpy(cap->name, cap2->card,
325
                       min(sizeof(cap->name), sizeof(cap2->card)));
326
                cap->name[sizeof(cap->name) - 1] = 0;
327
                if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
328
                        cap->type |= VID_TYPE_CAPTURE;
329
                if (cap2->capabilities & V4L2_CAP_TUNER)
330
                        cap->type |= VID_TYPE_TUNER;
331
                if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
332
                        cap->type |= VID_TYPE_TELETEXT;
333
                if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
334
                        cap->type |= VID_TYPE_OVERLAY;
335
                if (fbuf2.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
336
                        cap->type |= VID_TYPE_CLIPPING;
337
 
338
                cap->channels  = count_inputs(inode,file,drv);
339
                check_size(inode,file,drv,
340
                           &cap->maxwidth,&cap->maxheight);
341
                cap->audios    =  0; /* FIXME */
342
                cap->minwidth  = 48; /* FIXME */
343
                cap->minheight = 32; /* FIXME */
344
                break;
345
        }
346
        case VIDIOCGFBUF: /*  get frame buffer  */
347
        {
348
                struct video_buffer     *buffer = arg;
349
 
350
                memset(buffer, 0, sizeof(*buffer));
351
                memset(&fbuf2, 0, sizeof(fbuf2));
352
 
353
                err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
354
                if (err < 0) {
355
                        dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n",err);
356
                        break;
357
                }
358
                buffer->base   = fbuf2.base;
359
                buffer->height = fbuf2.fmt.height;
360
                buffer->width  = fbuf2.fmt.width;
361
 
362
                switch (fbuf2.fmt.pixelformat) {
363
                case V4L2_PIX_FMT_RGB332:
364
                        buffer->depth = 8;
365
                        break;
366
                case V4L2_PIX_FMT_RGB555:
367
                        buffer->depth = 15;
368
                        break;
369
                case V4L2_PIX_FMT_RGB565:
370
                        buffer->depth = 16;
371
                        break;
372
                case V4L2_PIX_FMT_BGR24:
373
                        buffer->depth = 24;
374
                        break;
375
                case V4L2_PIX_FMT_BGR32:
376
                        buffer->depth = 32;
377
                        break;
378
                default:
379
                        buffer->depth = 0;
380
                }
381
                if (fbuf2.fmt.bytesperline) {
382
                        buffer->bytesperline = fbuf2.fmt.bytesperline;
383
                        if (!buffer->depth && buffer->width)
384
                                buffer->depth   = ((fbuf2.fmt.bytesperline<<3)
385
                                                  + (buffer->width-1) )
386
                                                  /buffer->width;
387
                } else {
388
                        buffer->bytesperline =
389
                                (buffer->width * buffer->depth + 7) & 7;
390
                        buffer->bytesperline >>= 3;
391
                }
392
                break;
393
        }
394
        case VIDIOCSFBUF: /*  set frame buffer  */
395
        {
396
                struct video_buffer     *buffer = arg;
397
 
398
                memset(&fbuf2, 0, sizeof(fbuf2));
399
                fbuf2.base       = buffer->base;
400
                fbuf2.fmt.height = buffer->height;
401
                fbuf2.fmt.width  = buffer->width;
402
                switch (buffer->depth) {
403
                case 8:
404
                        fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB332;
405
                        break;
406
                case 15:
407
                        fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB555;
408
                        break;
409
                case 16:
410
                        fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
411
                        break;
412
                case 24:
413
                        fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR24;
414
                        break;
415
                case 32:
416
                        fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR32;
417
                        break;
418
                }
419
                fbuf2.fmt.bytesperline = buffer->bytesperline;
420
                err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
421
                if (err < 0)
422
                        dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n",err);
423
                break;
424
        }
425
        case VIDIOCGWIN: /*  get window or capture dimensions  */
426
        {
427
                struct video_window     *win = arg;
428
 
429
                fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
430
                memset(win,0,sizeof(*win));
431
 
432
                fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
433
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
434
                if (err < 0)
435
                        dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n",err);
436
                if (err == 0) {
437
                        win->x         = fmt2->fmt.win.w.left;
438
                        win->y         = fmt2->fmt.win.w.top;
439
                        win->width     = fmt2->fmt.win.w.width;
440
                        win->height    = fmt2->fmt.win.w.height;
441
                        win->chromakey = fmt2->fmt.win.chromakey;
442
                        win->clips     = NULL;
443
                        win->clipcount = 0;
444
                        break;
445
                }
446
 
447
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
448
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
449
                if (err < 0) {
450
                        dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n",err);
451
                        break;
452
                }
453
                win->x         = 0;
454
                win->y         = 0;
455
                win->width     = fmt2->fmt.pix.width;
456
                win->height    = fmt2->fmt.pix.height;
457
                win->chromakey = 0;
458
                win->clips     = NULL;
459
                win->clipcount = 0;
460
                break;
461
        }
462
        case VIDIOCSWIN: /*  set window and/or capture dimensions  */
463
        {
464
                struct video_window     *win = arg;
465
                int err1,err2;
466
 
467
                fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
468
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
469
                drv(inode, file, VIDIOC_STREAMOFF, &fmt2->type);
470
                err1 = drv(inode, file, VIDIOC_G_FMT, fmt2);
471
                if (err1 < 0)
472
                        dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n",err);
473
                if (err1 == 0) {
474
                        fmt2->fmt.pix.width  = win->width;
475
                        fmt2->fmt.pix.height = win->height;
476
                        fmt2->fmt.pix.field  = V4L2_FIELD_ANY;
477
                        fmt2->fmt.pix.bytesperline = 0;
478
                        err = drv(inode, file, VIDIOC_S_FMT, fmt2);
479
                        if (err < 0)
480
                                dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
481
                                        err);
482
                        win->width  = fmt2->fmt.pix.width;
483
                        win->height = fmt2->fmt.pix.height;
484
                }
485
 
486
                memset(fmt2,0,sizeof(*fmt2));
487
                fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
488
                fmt2->fmt.win.w.left    = win->x;
489
                fmt2->fmt.win.w.top     = win->y;
490
                fmt2->fmt.win.w.width   = win->width;
491
                fmt2->fmt.win.w.height  = win->height;
492
                fmt2->fmt.win.chromakey = win->chromakey;
493
                fmt2->fmt.win.clips     = (void __user *)win->clips;
494
                fmt2->fmt.win.clipcount = win->clipcount;
495
                err2 = drv(inode, file, VIDIOC_S_FMT, fmt2);
496
                if (err2 < 0)
497
                        dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n",err);
498
 
499
                if (err1 != 0 && err2 != 0)
500
                        err = err1;
501
                break;
502
        }
503
        case VIDIOCCAPTURE: /*  turn on/off preview  */
504
        {
505
                int *on = arg;
506
 
507
                if (0 == *on) {
508
                        /* dirty hack time.  But v4l1 has no STREAMOFF
509
                         * equivalent in the API, and this one at
510
                         * least comes close ... */
511
                        drv(inode, file, VIDIOC_STREAMOFF, &captype);
512
                }
513
                err = drv(inode, file, VIDIOC_OVERLAY, arg);
514
                if (err < 0)
515
                        dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n",err);
516
                break;
517
        }
518
        case VIDIOCGCHAN: /*  get input information  */
519
        {
520
                struct video_channel    *chan = arg;
521
 
522
                memset(&input2,0,sizeof(input2));
523
                input2.index = chan->channel;
524
                err = drv(inode, file, VIDIOC_ENUMINPUT, &input2);
525
                if (err < 0) {
526
                        dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
527
                                "channel=%d err=%d\n",chan->channel,err);
528
                        break;
529
                }
530
                chan->channel = input2.index;
531
                memcpy(chan->name, input2.name,
532
                       min(sizeof(chan->name), sizeof(input2.name)));
533
                chan->name[sizeof(chan->name) - 1] = 0;
534
                chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0;
535
                chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0;
536
                switch (input2.type) {
537
                case V4L2_INPUT_TYPE_TUNER:
538
                        chan->type = VIDEO_TYPE_TV;
539
                        break;
540
                default:
541
                case V4L2_INPUT_TYPE_CAMERA:
542
                        chan->type = VIDEO_TYPE_CAMERA;
543
                        break;
544
                }
545
                chan->norm = 0;
546
                err = drv(inode, file, VIDIOC_G_STD, &sid);
547
                if (err < 0)
548
                        dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n",err);
549
                if (err == 0) {
550
                        if (sid & V4L2_STD_PAL)
551
                                chan->norm = VIDEO_MODE_PAL;
552
                        if (sid & V4L2_STD_NTSC)
553
                                chan->norm = VIDEO_MODE_NTSC;
554
                        if (sid & V4L2_STD_SECAM)
555
                                chan->norm = VIDEO_MODE_SECAM;
556
                }
557
                break;
558
        }
559
        case VIDIOCSCHAN: /*  set input  */
560
        {
561
                struct video_channel *chan = arg;
562
 
563
                sid = 0;
564
                err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel);
565
                if (err < 0)
566
                        dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n",err);
567
                switch (chan->norm) {
568
                case VIDEO_MODE_PAL:
569
                        sid = V4L2_STD_PAL;
570
                        break;
571
                case VIDEO_MODE_NTSC:
572
                        sid = V4L2_STD_NTSC;
573
                        break;
574
                case VIDEO_MODE_SECAM:
575
                        sid = V4L2_STD_SECAM;
576
                        break;
577
                }
578
                if (0 != sid) {
579
                        err = drv(inode, file, VIDIOC_S_STD, &sid);
580
                        if (err < 0)
581
                                dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n",err);
582
                }
583
                break;
584
        }
585
        case VIDIOCGPICT: /*  get tone controls & partial capture format  */
586
        {
587
                struct video_picture    *pict = arg;
588
 
589
                pict->brightness = get_v4l_control(inode, file,
590
                                                   V4L2_CID_BRIGHTNESS,drv);
591
                pict->hue = get_v4l_control(inode, file,
592
                                            V4L2_CID_HUE, drv);
593
                pict->contrast = get_v4l_control(inode, file,
594
                                                 V4L2_CID_CONTRAST, drv);
595
                pict->colour = get_v4l_control(inode, file,
596
                                               V4L2_CID_SATURATION, drv);
597
                pict->whiteness = get_v4l_control(inode, file,
598
                                                  V4L2_CID_WHITENESS, drv);
599
 
600
                fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
601
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
602
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
603
                if (err < 0) {
604
                        dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
605
                        break;
606
                }
607
 
608
                pict->depth   = ((fmt2->fmt.pix.bytesperline<<3)
609
                                 + (fmt2->fmt.pix.width-1) )
610
                                 /fmt2->fmt.pix.width;
611
                pict->palette = pixelformat_to_palette(
612
                        fmt2->fmt.pix.pixelformat);
613
                break;
614
        }
615
        case VIDIOCSPICT: /*  set tone controls & partial capture format  */
616
        {
617
                struct video_picture    *pict = arg;
618
                int mem_err = 0, ovl_err = 0;
619
 
620
                memset(&fbuf2, 0, sizeof(fbuf2));
621
 
622
                set_v4l_control(inode, file,
623
                                V4L2_CID_BRIGHTNESS, pict->brightness, drv);
624
                set_v4l_control(inode, file,
625
                                V4L2_CID_HUE, pict->hue, drv);
626
                set_v4l_control(inode, file,
627
                                V4L2_CID_CONTRAST, pict->contrast, drv);
628
                set_v4l_control(inode, file,
629
                                V4L2_CID_SATURATION, pict->colour, drv);
630
                set_v4l_control(inode, file,
631
                                V4L2_CID_WHITENESS, pict->whiteness, drv);
632
                /*
633
                 * V4L1 uses this ioctl to set both memory capture and overlay
634
                 * pixel format, while V4L2 has two different ioctls for this.
635
                 * Some cards may not support one or the other, and may support
636
                 * different pixel formats for memory vs overlay.
637
                 */
638
 
639
                fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
640
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
641
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
642
                /* If VIDIOC_G_FMT failed, then the driver likely doesn't
643
                   support memory capture.  Trying to set the memory capture
644
                   parameters would be pointless.  */
645
                if (err < 0) {
646
                        dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
647
                        mem_err = -1000;  /* didn't even try */
648
                } else if (fmt2->fmt.pix.pixelformat !=
649
                         palette_to_pixelformat(pict->palette)) {
650
                        fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
651
                                pict->palette);
652
                        mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2);
653
                        if (mem_err < 0)
654
                                dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
655
                                        mem_err);
656
                }
657
 
658
                err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
659
                /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
660
                   support overlay.  Trying to set the overlay parameters
661
                   would be quite pointless.  */
662
                if (err < 0) {
663
                        dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
664
                        ovl_err = -1000;  /* didn't even try */
665
                } else if (fbuf2.fmt.pixelformat !=
666
                         palette_to_pixelformat(pict->palette)) {
667
                        fbuf2.fmt.pixelformat = palette_to_pixelformat(
668
                                pict->palette);
669
                        ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
670
                        if (ovl_err < 0)
671
                                dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
672
                                        ovl_err);
673
                }
674
                if (ovl_err < 0 && mem_err < 0)
675
                        /* ioctl failed, couldn't set either parameter */
676
                        if (mem_err != -1000) {
677
                            err = mem_err;
678
                        } else if (ovl_err == -EPERM) {
679
                            err = 0;
680
                        } else {
681
                            err = ovl_err;
682
                        }
683
                else
684
                        err = 0;
685
                break;
686
        }
687
        case VIDIOCGTUNER: /*  get tuner information  */
688
        {
689
                struct video_tuner      *tun = arg;
690
 
691
                memset(&tun2,0,sizeof(tun2));
692
                err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
693
                if (err < 0) {
694
                        dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n",err);
695
                        break;
696
                }
697
                memcpy(tun->name, tun2.name,
698
                       min(sizeof(tun->name), sizeof(tun2.name)));
699
                tun->name[sizeof(tun->name) - 1] = 0;
700
                tun->rangelow = tun2.rangelow;
701
                tun->rangehigh = tun2.rangehigh;
702
                tun->flags = 0;
703
                tun->mode = VIDEO_MODE_AUTO;
704
 
705
                for (i = 0; i < 64; i++) {
706
                        memset(&std2,0,sizeof(std2));
707
                        std2.index = i;
708
                        if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2))
709
                                break;
710
                        if (std2.id & V4L2_STD_PAL)
711
                                tun->flags |= VIDEO_TUNER_PAL;
712
                        if (std2.id & V4L2_STD_NTSC)
713
                                tun->flags |= VIDEO_TUNER_NTSC;
714
                        if (std2.id & V4L2_STD_SECAM)
715
                                tun->flags |= VIDEO_TUNER_SECAM;
716
                }
717
 
718
                err = drv(inode, file, VIDIOC_G_STD, &sid);
719
                if (err < 0)
720
                        dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n",err);
721
                if (err == 0) {
722
                        if (sid & V4L2_STD_PAL)
723
                                tun->mode = VIDEO_MODE_PAL;
724
                        if (sid & V4L2_STD_NTSC)
725
                                tun->mode = VIDEO_MODE_NTSC;
726
                        if (sid & V4L2_STD_SECAM)
727
                                tun->mode = VIDEO_MODE_SECAM;
728
                }
729
 
730
                if (tun2.capability & V4L2_TUNER_CAP_LOW)
731
                        tun->flags |= VIDEO_TUNER_LOW;
732
                if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
733
                        tun->flags |= VIDEO_TUNER_STEREO_ON;
734
                tun->signal = tun2.signal;
735
                break;
736
        }
737
        case VIDIOCSTUNER: /*  select a tuner input  */
738
        {
739
                struct video_tuner      *tun = arg;
740
                struct v4l2_tuner       t;
741
                memset(&t,0,sizeof(t));
742
 
743
                t.index=tun->tuner;
744
 
745
                err = drv(inode, file, VIDIOC_S_INPUT, &t);
746
                if (err < 0)
747
                        dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
748
 
749
                break;
750
        }
751
        case VIDIOCGFREQ: /*  get frequency  */
752
        {
753
                unsigned long *freq = arg;
754
                memset(&freq2,0,sizeof(freq2));
755
 
756
                freq2.tuner = 0;
757
                err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
758
                if (err < 0)
759
                        dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n",err);
760
                if (0 == err)
761
                        *freq = freq2.frequency;
762
                break;
763
        }
764
        case VIDIOCSFREQ: /*  set frequency  */
765
        {
766
                unsigned long *freq = arg;
767
                memset(&freq2,0,sizeof(freq2));
768
 
769
                drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
770
                freq2.frequency = *freq;
771
                err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2);
772
                if (err < 0)
773
                        dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n",err);
774
                break;
775
        }
776
        case VIDIOCGAUDIO: /*  get audio properties/controls  */
777
        {
778
                struct video_audio      *aud = arg;
779
                memset(&aud2,0,sizeof(aud2));
780
 
781
                err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
782
                if (err < 0) {
783
                        dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n",err);
784
                        break;
785
                }
786
                memcpy(aud->name, aud2.name,
787
                       min(sizeof(aud->name), sizeof(aud2.name)));
788
                aud->name[sizeof(aud->name) - 1] = 0;
789
                aud->audio = aud2.index;
790
                aud->flags = 0;
791
                i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
792
                if (i >= 0) {
793
                        aud->volume = i;
794
                        aud->flags |= VIDEO_AUDIO_VOLUME;
795
                }
796
                i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
797
                if (i >= 0) {
798
                        aud->bass = i;
799
                        aud->flags |= VIDEO_AUDIO_BASS;
800
                }
801
                i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
802
                if (i >= 0) {
803
                        aud->treble = i;
804
                        aud->flags |= VIDEO_AUDIO_TREBLE;
805
                }
806
                i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
807
                if (i >= 0) {
808
                        aud->balance = i;
809
                        aud->flags |= VIDEO_AUDIO_BALANCE;
810
                }
811
                i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
812
                if (i >= 0) {
813
                        if (i)
814
                                aud->flags |= VIDEO_AUDIO_MUTE;
815
                        aud->flags |= VIDEO_AUDIO_MUTABLE;
816
                }
817
                aud->step = 1;
818
                qctrl2.id = V4L2_CID_AUDIO_VOLUME;
819
                if (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
820
                    !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
821
                        aud->step = qctrl2.step;
822
                aud->mode = 0;
823
 
824
                memset(&tun2,0,sizeof(tun2));
825
                err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
826
                if (err < 0) {
827
                        dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err);
828
                        err = 0;
829
                        break;
830
                }
831
 
832
                if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
833
                        aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
834
                else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
835
                        aud->mode = VIDEO_SOUND_STEREO;
836
                else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
837
                        aud->mode = VIDEO_SOUND_MONO;
838
                break;
839
        }
840
        case VIDIOCSAUDIO: /*  set audio controls  */
841
        {
842
                struct video_audio      *aud = arg;
843
 
844
                memset(&aud2,0,sizeof(aud2));
845
                memset(&tun2,0,sizeof(tun2));
846
 
847
                aud2.index = aud->audio;
848
                err = drv(inode, file, VIDIOC_S_AUDIO, &aud2);
849
                if (err < 0) {
850
                        dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n",err);
851
                        break;
852
                }
853
 
854
                set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME,
855
                                aud->volume, drv);
856
                set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS,
857
                                aud->bass, drv);
858
                set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE,
859
                                aud->treble, drv);
860
                set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE,
861
                                aud->balance, drv);
862
                set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE,
863
                                !!(aud->flags & VIDEO_AUDIO_MUTE), drv);
864
 
865
                err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
866
                if (err < 0)
867
                        dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n",err);
868
                if (err == 0) {
869
                        switch (aud->mode) {
870
                        default:
871
                        case VIDEO_SOUND_MONO:
872
                        case VIDEO_SOUND_LANG1:
873
                                tun2.audmode = V4L2_TUNER_MODE_MONO;
874
                                break;
875
                        case VIDEO_SOUND_STEREO:
876
                                tun2.audmode = V4L2_TUNER_MODE_STEREO;
877
                                break;
878
                        case VIDEO_SOUND_LANG2:
879
                                tun2.audmode = V4L2_TUNER_MODE_LANG2;
880
                                break;
881
                        }
882
                        err = drv(inode, file, VIDIOC_S_TUNER, &tun2);
883
                        if (err < 0)
884
                                dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n",err);
885
                }
886
                err = 0;
887
                break;
888
        }
889
        case VIDIOCMCAPTURE: /*  capture a frame  */
890
        {
891
                struct video_mmap       *mm = arg;
892
 
893
                fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
894
                memset(&buf2,0,sizeof(buf2));
895
 
896
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
897
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
898
                if (err < 0) {
899
                        dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err);
900
                        break;
901
                }
902
                if (mm->width   != fmt2->fmt.pix.width  ||
903
                    mm->height  != fmt2->fmt.pix.height ||
904
                    palette_to_pixelformat(mm->format) !=
905
                    fmt2->fmt.pix.pixelformat)
906
                {/* New capture format...  */
907
                        fmt2->fmt.pix.width = mm->width;
908
                        fmt2->fmt.pix.height = mm->height;
909
                        fmt2->fmt.pix.pixelformat =
910
                                palette_to_pixelformat(mm->format);
911
                        fmt2->fmt.pix.field = V4L2_FIELD_ANY;
912
                        fmt2->fmt.pix.bytesperline = 0;
913
                        err = drv(inode, file, VIDIOC_S_FMT, fmt2);
914
                        if (err < 0) {
915
                                dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err);
916
                                break;
917
                        }
918
                }
919
                buf2.index = mm->frame;
920
                buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
921
                err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
922
                if (err < 0) {
923
                        dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n",err);
924
                        break;
925
                }
926
                err = drv(inode, file, VIDIOC_QBUF, &buf2);
927
                if (err < 0) {
928
                        dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err);
929
                        break;
930
                }
931
                err = drv(inode, file, VIDIOC_STREAMON, &captype);
932
                if (err < 0)
933
                        dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n",err);
934
                break;
935
        }
936
        case VIDIOCSYNC: /*  wait for a frame  */
937
        {
938
                int                     *i = arg;
939
 
940
                memset(&buf2,0,sizeof(buf2));
941
                buf2.index = *i;
942
                buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
943
                err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
944
                if (err < 0) {
945
                        /*  No such buffer */
946
                        dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
947
                        break;
948
                }
949
                if (!(buf2.flags & V4L2_BUF_FLAG_MAPPED)) {
950
                        /* Buffer is not mapped  */
951
                        err = -EINVAL;
952
                        break;
953
                }
954
 
955
                /* make sure capture actually runs so we don't block forever */
956
                err = drv(inode, file, VIDIOC_STREAMON, &captype);
957
                if (err < 0) {
958
                        dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n",err);
959
                        break;
960
                }
961
 
962
                /*  Loop as long as the buffer is queued, but not done  */
963
                while ((buf2.flags &
964
                        (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
965
                       == V4L2_BUF_FLAG_QUEUED)
966
                {
967
                        err = poll_one(file);
968
                        if (err < 0 ||   /* error or sleep was interrupted  */
969
                            err == 0)    /* timeout? Shouldn't occur.  */
970
                                break;
971
                        err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
972
                        if (err < 0)
973
                                dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
974
                }
975
                if (!(buf2.flags & V4L2_BUF_FLAG_DONE)) /* not done */
976
                        break;
977
                do {
978
                        err = drv(inode, file, VIDIOC_DQBUF, &buf2);
979
                        if (err < 0)
980
                                dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n",err);
981
                } while (err == 0 && buf2.index != *i);
982
                break;
983
        }
984
 
985
        case VIDIOCGVBIFMT: /* query VBI data capture format */
986
        {
987
                struct vbi_format      *fmt = arg;
988
 
989
                fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
990
                fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
991
 
992
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
993
                if (err < 0) {
994
                        dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
995
                        break;
996
                }
997
                if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
998
                        err = -EINVAL;
999
                        break;
1000
                }
1001
                memset(fmt, 0, sizeof(*fmt));
1002
                fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
1003
                fmt->sampling_rate    = fmt2->fmt.vbi.sampling_rate;
1004
                fmt->sample_format    = VIDEO_PALETTE_RAW;
1005
                fmt->start[0]         = fmt2->fmt.vbi.start[0];
1006
                fmt->count[0]         = fmt2->fmt.vbi.count[0];
1007
                fmt->start[1]         = fmt2->fmt.vbi.start[1];
1008
                fmt->count[1]         = fmt2->fmt.vbi.count[1];
1009
                fmt->flags            = fmt2->fmt.vbi.flags & 0x03;
1010
                break;
1011
        }
1012
        case VIDIOCSVBIFMT:
1013
        {
1014
                struct vbi_format      *fmt = arg;
1015
 
1016
                if (VIDEO_PALETTE_RAW != fmt->sample_format) {
1017
                        err = -EINVAL;
1018
                        break;
1019
                }
1020
 
1021
                fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
1022
 
1023
                fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1024
                fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
1025
                fmt2->fmt.vbi.sampling_rate    = fmt->sampling_rate;
1026
                fmt2->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
1027
                fmt2->fmt.vbi.start[0]         = fmt->start[0];
1028
                fmt2->fmt.vbi.count[0]         = fmt->count[0];
1029
                fmt2->fmt.vbi.start[1]         = fmt->start[1];
1030
                fmt2->fmt.vbi.count[1]         = fmt->count[1];
1031
                fmt2->fmt.vbi.flags            = fmt->flags;
1032
                err = drv(inode, file, VIDIOC_TRY_FMT, fmt2);
1033
                if (err < 0) {
1034
                        dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err);
1035
                        break;
1036
                }
1037
 
1038
                if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
1039
                    fmt2->fmt.vbi.sampling_rate    != fmt->sampling_rate    ||
1040
                    fmt2->fmt.vbi.sample_format    != V4L2_PIX_FMT_GREY     ||
1041
                    fmt2->fmt.vbi.start[0]         != fmt->start[0]         ||
1042
                    fmt2->fmt.vbi.count[0]         != fmt->count[0]         ||
1043
                    fmt2->fmt.vbi.start[1]         != fmt->start[1]         ||
1044
                    fmt2->fmt.vbi.count[1]         != fmt->count[1]         ||
1045
                    fmt2->fmt.vbi.flags            != fmt->flags) {
1046
                        err = -EINVAL;
1047
                        break;
1048
                }
1049
                err = drv(inode, file, VIDIOC_S_FMT, fmt2);
1050
                if (err < 0)
1051
                        dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err);
1052
                break;
1053
        }
1054
 
1055
        default:
1056
                err = -ENOIOCTLCMD;
1057
                break;
1058
        }
1059
 
1060
        kfree(cap2);
1061
        kfree(fmt2);
1062
        return err;
1063
}
1064
 
1065
EXPORT_SYMBOL(v4l_compat_translate_ioctl);
1066
 
1067
/*
1068
 * Local variables:
1069
 * c-basic-offset: 8
1070
 * End:
1071
 */

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.