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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [media/] [video/] [videodev.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
 * Video capture interface for Linux version 2
3
 *
4
 *      A generic video device interface for the LINUX operating system
5
 *      using a set of device structures/vectors for low level operations.
6
 *
7
 *      This program is free software; you can redistribute it and/or
8
 *      modify it under the terms of the GNU General Public License
9
 *      as published by the Free Software Foundation; either version
10
 *      2 of the License, or (at your option) any later version.
11
 *
12
 * Authors:     Alan Cox, <alan@redhat.com> (version 1)
13
 *              Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
14
 *
15
 * Fixes:       20000516  Claudio Matsuoka <claudio@conectiva.com>
16
 *              - Added procfs support
17
 */
18
 
19
#define dbgarg(cmd, fmt, arg...) \
20
                if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {                \
21
                        printk (KERN_DEBUG "%s: ",  vfd->name);         \
22
                        v4l_printk_ioctl(cmd);                          \
23
                        printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \
24
                }
25
 
26
#define dbgarg2(fmt, arg...) \
27
                if (vfd->debug & V4L2_DEBUG_IOCTL_ARG)                  \
28
                        printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
29
 
30
#include <linux/module.h>
31
#include <linux/types.h>
32
#include <linux/kernel.h>
33
#include <linux/mm.h>
34
#include <linux/string.h>
35
#include <linux/errno.h>
36
#include <linux/init.h>
37
#include <linux/kmod.h>
38
#include <linux/slab.h>
39
#include <asm/uaccess.h>
40
#include <asm/system.h>
41
 
42
#define __OLD_VIDIOC_ /* To allow fixing old calls*/
43
#include <linux/videodev2.h>
44
 
45
#ifdef CONFIG_VIDEO_V4L1
46
#include <linux/videodev.h>
47
#endif
48
#include <media/v4l2-common.h>
49
 
50
#define VIDEO_NUM_DEVICES       256
51
#define VIDEO_NAME              "video4linux"
52
 
53
/*
54
 *      sysfs stuff
55
 */
56
 
57
static ssize_t show_name(struct device *cd,
58
                         struct device_attribute *attr, char *buf)
59
{
60
        struct video_device *vfd = container_of(cd, struct video_device,
61
                                                class_dev);
62
        return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
63
}
64
 
65
struct video_device *video_device_alloc(void)
66
{
67
        struct video_device *vfd;
68
 
69
        vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
70
        return vfd;
71
}
72
 
73
void video_device_release(struct video_device *vfd)
74
{
75
        kfree(vfd);
76
}
77
 
78
static void video_release(struct device *cd)
79
{
80
        struct video_device *vfd = container_of(cd, struct video_device,
81
                                                                class_dev);
82
 
83
#if 1
84
        /* needed until all drivers are fixed */
85
        if (!vfd->release)
86
                return;
87
#endif
88
        vfd->release(vfd);
89
}
90
 
91
static struct device_attribute video_device_attrs[] = {
92
        __ATTR(name, S_IRUGO, show_name, NULL),
93
        __ATTR_NULL
94
};
95
 
96
static struct class video_class = {
97
        .name    = VIDEO_NAME,
98
        .dev_attrs = video_device_attrs,
99
        .dev_release = video_release,
100
};
101
 
102
/*
103
 *      Active devices
104
 */
105
 
106
static struct video_device *video_device[VIDEO_NUM_DEVICES];
107
static DEFINE_MUTEX(videodev_lock);
108
 
109
struct video_device* video_devdata(struct file *file)
110
{
111
        return video_device[iminor(file->f_path.dentry->d_inode)];
112
}
113
 
114
/*
115
 *      Open a video device - FIXME: Obsoleted
116
 */
117
static int video_open(struct inode *inode, struct file *file)
118
{
119
        unsigned int minor = iminor(inode);
120
        int err = 0;
121
        struct video_device *vfl;
122
        const struct file_operations *old_fops;
123
 
124
        if(minor>=VIDEO_NUM_DEVICES)
125
                return -ENODEV;
126
        mutex_lock(&videodev_lock);
127
        vfl=video_device[minor];
128
        if(vfl==NULL) {
129
                mutex_unlock(&videodev_lock);
130
                request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
131
                mutex_lock(&videodev_lock);
132
                vfl=video_device[minor];
133
                if (vfl==NULL) {
134
                        mutex_unlock(&videodev_lock);
135
                        return -ENODEV;
136
                }
137
        }
138
        old_fops = file->f_op;
139
        file->f_op = fops_get(vfl->fops);
140
        if(file->f_op->open)
141
                err = file->f_op->open(inode,file);
142
        if (err) {
143
                fops_put(file->f_op);
144
                file->f_op = fops_get(old_fops);
145
        }
146
        fops_put(old_fops);
147
        mutex_unlock(&videodev_lock);
148
        return err;
149
}
150
 
151
/*
152
 * helper function -- handles userspace copying for ioctl arguments
153
 */
154
 
155
#ifdef __OLD_VIDIOC_
156
static unsigned int
157
video_fix_command(unsigned int cmd)
158
{
159
        switch (cmd) {
160
        case VIDIOC_OVERLAY_OLD:
161
                cmd = VIDIOC_OVERLAY;
162
                break;
163
        case VIDIOC_S_PARM_OLD:
164
                cmd = VIDIOC_S_PARM;
165
                break;
166
        case VIDIOC_S_CTRL_OLD:
167
                cmd = VIDIOC_S_CTRL;
168
                break;
169
        case VIDIOC_G_AUDIO_OLD:
170
                cmd = VIDIOC_G_AUDIO;
171
                break;
172
        case VIDIOC_G_AUDOUT_OLD:
173
                cmd = VIDIOC_G_AUDOUT;
174
                break;
175
        case VIDIOC_CROPCAP_OLD:
176
                cmd = VIDIOC_CROPCAP;
177
                break;
178
        }
179
        return cmd;
180
}
181
#endif
182
 
183
/*
184
 * Obsolete usercopy function - Should be removed soon
185
 */
186
int
187
video_usercopy(struct inode *inode, struct file *file,
188
               unsigned int cmd, unsigned long arg,
189
               int (*func)(struct inode *inode, struct file *file,
190
                           unsigned int cmd, void *arg))
191
{
192
        char    sbuf[128];
193
        void    *mbuf = NULL;
194
        void    *parg = NULL;
195
        int     err  = -EINVAL;
196
        int     is_ext_ctrl;
197
        size_t  ctrls_size = 0;
198
        void __user *user_ptr = NULL;
199
 
200
#ifdef __OLD_VIDIOC_
201
        cmd = video_fix_command(cmd);
202
#endif
203
        is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
204
                       cmd == VIDIOC_TRY_EXT_CTRLS);
205
 
206
        /*  Copy arguments into temp kernel buffer  */
207
        switch (_IOC_DIR(cmd)) {
208
        case _IOC_NONE:
209
                parg = NULL;
210
                break;
211
        case _IOC_READ:
212
        case _IOC_WRITE:
213
        case (_IOC_WRITE | _IOC_READ):
214
                if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
215
                        parg = sbuf;
216
                } else {
217
                        /* too big to allocate from stack */
218
                        mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
219
                        if (NULL == mbuf)
220
                                return -ENOMEM;
221
                        parg = mbuf;
222
                }
223
 
224
                err = -EFAULT;
225
                if (_IOC_DIR(cmd) & _IOC_WRITE)
226
                        if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
227
                                goto out;
228
                break;
229
        }
230
        if (is_ext_ctrl) {
231
                struct v4l2_ext_controls *p = parg;
232
 
233
                /* In case of an error, tell the caller that it wasn't
234
                   a specific control that caused it. */
235
                p->error_idx = p->count;
236
                user_ptr = (void __user *)p->controls;
237
                if (p->count) {
238
                        ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
239
                        /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
240
                        mbuf = kmalloc(ctrls_size, GFP_KERNEL);
241
                        err = -ENOMEM;
242
                        if (NULL == mbuf)
243
                                goto out_ext_ctrl;
244
                        err = -EFAULT;
245
                        if (copy_from_user(mbuf, user_ptr, ctrls_size))
246
                                goto out_ext_ctrl;
247
                        p->controls = mbuf;
248
                }
249
        }
250
 
251
        /* call driver */
252
        err = func(inode, file, cmd, parg);
253
        if (err == -ENOIOCTLCMD)
254
                err = -EINVAL;
255
        if (is_ext_ctrl) {
256
                struct v4l2_ext_controls *p = parg;
257
 
258
                p->controls = (void *)user_ptr;
259
                if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
260
                        err = -EFAULT;
261
                goto out_ext_ctrl;
262
        }
263
        if (err < 0)
264
                goto out;
265
 
266
out_ext_ctrl:
267
        /*  Copy results into user buffer  */
268
        switch (_IOC_DIR(cmd))
269
        {
270
        case _IOC_READ:
271
        case (_IOC_WRITE | _IOC_READ):
272
                if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
273
                        err = -EFAULT;
274
                break;
275
        }
276
 
277
out:
278
        kfree(mbuf);
279
        return err;
280
}
281
 
282
/*
283
 * open/release helper functions -- handle exclusive opens
284
 * Should be removed soon
285
 */
286
int video_exclusive_open(struct inode *inode, struct file *file)
287
{
288
        struct  video_device *vfl = video_devdata(file);
289
        int retval = 0;
290
 
291
        mutex_lock(&vfl->lock);
292
        if (vfl->users) {
293
                retval = -EBUSY;
294
        } else {
295
                vfl->users++;
296
        }
297
        mutex_unlock(&vfl->lock);
298
        return retval;
299
}
300
 
301
int video_exclusive_release(struct inode *inode, struct file *file)
302
{
303
        struct  video_device *vfl = video_devdata(file);
304
 
305
        vfl->users--;
306
        return 0;
307
}
308
 
309
static char *v4l2_memory_names[] = {
310
        [V4L2_MEMORY_MMAP]    = "mmap",
311
        [V4L2_MEMORY_USERPTR] = "userptr",
312
        [V4L2_MEMORY_OVERLAY] = "overlay",
313
};
314
 
315
 
316
/* FIXME: Those stuff are replicated also on v4l2-common.c */
317
static char *v4l2_type_names_FIXME[] = {
318
        [V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "video-cap",
319
        [V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "video-over",
320
        [V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "video-out",
321
        [V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
322
        [V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
323
        [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
324
        [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
325
        [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
326
        [V4L2_BUF_TYPE_PRIVATE]            = "private",
327
};
328
 
329
static char *v4l2_field_names_FIXME[] = {
330
        [V4L2_FIELD_ANY]        = "any",
331
        [V4L2_FIELD_NONE]       = "none",
332
        [V4L2_FIELD_TOP]        = "top",
333
        [V4L2_FIELD_BOTTOM]     = "bottom",
334
        [V4L2_FIELD_INTERLACED] = "interlaced",
335
        [V4L2_FIELD_SEQ_TB]     = "seq-tb",
336
        [V4L2_FIELD_SEQ_BT]     = "seq-bt",
337
        [V4L2_FIELD_ALTERNATE]  = "alternate",
338
        [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
339
        [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
340
};
341
 
342
#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
343
 
344
static void dbgbuf(unsigned int cmd, struct video_device *vfd,
345
                                        struct v4l2_buffer *p)
346
{
347
        struct v4l2_timecode *tc=&p->timecode;
348
 
349
        dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
350
                "bytesused=%d, flags=0x%08d, "
351
                "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
352
                        (p->timestamp.tv_sec/3600),
353
                        (int)(p->timestamp.tv_sec/60)%60,
354
                        (int)(p->timestamp.tv_sec%60),
355
                        p->timestamp.tv_usec,
356
                        p->index,
357
                        prt_names(p->type,v4l2_type_names_FIXME),
358
                        p->bytesused,p->flags,
359
                        p->field,p->sequence,
360
                        prt_names(p->memory,v4l2_memory_names),
361
                        p->m.userptr, p->length);
362
        dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
363
                "flags=0x%08d, frames=%d, userbits=0x%08x\n",
364
                        tc->hours,tc->minutes,tc->seconds,
365
                        tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
366
}
367
 
368
static inline void dbgrect(struct video_device *vfd, char *s,
369
                                                        struct v4l2_rect *r)
370
{
371
        dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
372
                                                r->width, r->height);
373
};
374
 
375
static inline void v4l_print_pix_fmt (struct video_device *vfd,
376
                                                struct v4l2_pix_format *fmt)
377
{
378
        dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
379
                "bytesperline=%d sizeimage=%d, colorspace=%d\n",
380
                fmt->width,fmt->height,
381
                (fmt->pixelformat & 0xff),
382
                (fmt->pixelformat >>  8) & 0xff,
383
                (fmt->pixelformat >> 16) & 0xff,
384
                (fmt->pixelformat >> 24) & 0xff,
385
                prt_names(fmt->field,v4l2_field_names_FIXME),
386
                fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
387
};
388
 
389
 
390
static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
391
{
392
        switch (type) {
393
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
394
                if (vfd->vidioc_try_fmt_cap)
395
                        return (0);
396
                break;
397
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
398
                if (vfd->vidioc_try_fmt_overlay)
399
                        return (0);
400
                break;
401
        case V4L2_BUF_TYPE_VBI_CAPTURE:
402
                if (vfd->vidioc_try_fmt_vbi)
403
                        return (0);
404
                break;
405
        case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
406
                if (vfd->vidioc_try_fmt_vbi_output)
407
                        return (0);
408
                break;
409
        case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
410
                if (vfd->vidioc_try_fmt_vbi_capture)
411
                        return (0);
412
                break;
413
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
414
                if (vfd->vidioc_try_fmt_video_output)
415
                        return (0);
416
                break;
417
        case V4L2_BUF_TYPE_VBI_OUTPUT:
418
                if (vfd->vidioc_try_fmt_vbi_output)
419
                        return (0);
420
                break;
421
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
422
                if (vfd->vidioc_try_fmt_output_overlay)
423
                        return (0);
424
                break;
425
        case V4L2_BUF_TYPE_PRIVATE:
426
                if (vfd->vidioc_try_fmt_type_private)
427
                        return (0);
428
                break;
429
        }
430
        return (-EINVAL);
431
}
432
 
433
static int __video_do_ioctl(struct inode *inode, struct file *file,
434
                unsigned int cmd, void *arg)
435
{
436
        struct video_device *vfd = video_devdata(file);
437
        void                 *fh = file->private_data;
438
        int                  ret = -EINVAL;
439
 
440
        if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
441
                                !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
442
                v4l_print_ioctl(vfd->name, cmd);
443
        }
444
 
445
#ifdef CONFIG_VIDEO_V4L1_COMPAT
446
        /***********************************************************
447
         Handles calls to the obsoleted V4L1 API
448
         Due to the nature of VIDIOCGMBUF, each driver that supports
449
         V4L1 should implement its own handler for this ioctl.
450
         ***********************************************************/
451
 
452
        /* --- streaming capture ------------------------------------- */
453
        if (cmd == VIDIOCGMBUF) {
454
                struct video_mbuf *p=arg;
455
 
456
                memset(p, 0, sizeof(*p));
457
 
458
                if (!vfd->vidiocgmbuf)
459
                        return ret;
460
                ret=vfd->vidiocgmbuf(file, fh, p);
461
                if (!ret)
462
                        dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
463
                                                p->size, p->frames,
464
                                                (unsigned long)p->offsets);
465
                return ret;
466
        }
467
 
468
        /********************************************************
469
         All other V4L1 calls are handled by v4l1_compat module.
470
         Those calls will be translated into V4L2 calls, and
471
         __video_do_ioctl will be called again, with one or more
472
         V4L2 ioctls.
473
         ********************************************************/
474
        if (_IOC_TYPE(cmd)=='v')
475
                return v4l_compat_translate_ioctl(inode,file,cmd,arg,
476
                                                __video_do_ioctl);
477
#endif
478
 
479
        switch(cmd) {
480
        /* --- capabilities ------------------------------------------ */
481
        case VIDIOC_QUERYCAP:
482
        {
483
                struct v4l2_capability *cap = (struct v4l2_capability*)arg;
484
                memset(cap, 0, sizeof(*cap));
485
 
486
                if (!vfd->vidioc_querycap)
487
                        break;
488
 
489
                ret=vfd->vidioc_querycap(file, fh, cap);
490
                if (!ret)
491
                        dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
492
                                        "version=0x%08x, "
493
                                        "capabilities=0x%08x\n",
494
                                        cap->driver,cap->card,cap->bus_info,
495
                                        cap->version,
496
                                        cap->capabilities);
497
                break;
498
        }
499
 
500
        /* --- priority ------------------------------------------ */
501
        case VIDIOC_G_PRIORITY:
502
        {
503
                enum v4l2_priority *p=arg;
504
 
505
                if (!vfd->vidioc_g_priority)
506
                        break;
507
                ret=vfd->vidioc_g_priority(file, fh, p);
508
                if (!ret)
509
                        dbgarg(cmd, "priority is %d\n", *p);
510
                break;
511
        }
512
        case VIDIOC_S_PRIORITY:
513
        {
514
                enum v4l2_priority *p=arg;
515
 
516
                if (!vfd->vidioc_s_priority)
517
                        break;
518
                dbgarg(cmd, "setting priority to %d\n", *p);
519
                ret=vfd->vidioc_s_priority(file, fh, *p);
520
                break;
521
        }
522
 
523
        /* --- capture ioctls ---------------------------------------- */
524
        case VIDIOC_ENUM_FMT:
525
        {
526
                struct v4l2_fmtdesc *f = arg;
527
                enum v4l2_buf_type type;
528
                unsigned int index;
529
 
530
                index = f->index;
531
                type  = f->type;
532
                memset(f,0,sizeof(*f));
533
                f->index = index;
534
                f->type  = type;
535
 
536
                switch (type) {
537
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
538
                        if (vfd->vidioc_enum_fmt_cap)
539
                                ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
540
                        break;
541
                case V4L2_BUF_TYPE_VIDEO_OVERLAY:
542
                        if (vfd->vidioc_enum_fmt_overlay)
543
                                ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
544
                        break;
545
                case V4L2_BUF_TYPE_VBI_CAPTURE:
546
                        if (vfd->vidioc_enum_fmt_vbi)
547
                                ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
548
                        break;
549
                case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
550
                        if (vfd->vidioc_enum_fmt_vbi_output)
551
                                ret=vfd->vidioc_enum_fmt_vbi_output(file,
552
                                                                fh, f);
553
                        break;
554
                case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
555
                        if (vfd->vidioc_enum_fmt_vbi_capture)
556
                                ret=vfd->vidioc_enum_fmt_vbi_capture(file,
557
                                                                fh, f);
558
                        break;
559
                case V4L2_BUF_TYPE_VIDEO_OUTPUT:
560
                        if (vfd->vidioc_enum_fmt_video_output)
561
                                ret=vfd->vidioc_enum_fmt_video_output(file,
562
                                                                fh, f);
563
                        break;
564
                case V4L2_BUF_TYPE_VBI_OUTPUT:
565
                        if (vfd->vidioc_enum_fmt_vbi_output)
566
                                ret=vfd->vidioc_enum_fmt_vbi_output(file,
567
                                                                fh, f);
568
                        break;
569
                case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
570
                        if (vfd->vidioc_enum_fmt_output_overlay)
571
                                ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
572
                        break;
573
                case V4L2_BUF_TYPE_PRIVATE:
574
                        if (vfd->vidioc_enum_fmt_type_private)
575
                                ret=vfd->vidioc_enum_fmt_type_private(file,
576
                                                                fh, f);
577
                        break;
578
                }
579
                if (!ret)
580
                        dbgarg (cmd, "index=%d, type=%d, flags=%d, "
581
                                        "pixelformat=%c%c%c%c, description='%s'\n",
582
                                        f->index, f->type, f->flags,
583
                                        (f->pixelformat & 0xff),
584
                                        (f->pixelformat >>  8) & 0xff,
585
                                        (f->pixelformat >> 16) & 0xff,
586
                                        (f->pixelformat >> 24) & 0xff,
587
                                        f->description);
588
                break;
589
        }
590
        case VIDIOC_G_FMT:
591
        {
592
                struct v4l2_format *f = (struct v4l2_format *)arg;
593
                enum v4l2_buf_type type=f->type;
594
 
595
                memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
596
                f->type=type;
597
 
598
                /* FIXME: Should be one dump per type */
599
                dbgarg (cmd, "type=%s\n", prt_names(type,
600
                                        v4l2_type_names_FIXME));
601
 
602
                switch (type) {
603
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
604
                        if (vfd->vidioc_g_fmt_cap)
605
                                ret=vfd->vidioc_g_fmt_cap(file, fh, f);
606
                        if (!ret)
607
                                v4l_print_pix_fmt(vfd,&f->fmt.pix);
608
                        break;
609
                case V4L2_BUF_TYPE_VIDEO_OVERLAY:
610
                        if (vfd->vidioc_g_fmt_overlay)
611
                                ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
612
                        break;
613
                case V4L2_BUF_TYPE_VBI_CAPTURE:
614
                        if (vfd->vidioc_g_fmt_vbi)
615
                                ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
616
                        break;
617
                case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
618
                        if (vfd->vidioc_g_fmt_vbi_output)
619
                                ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
620
                        break;
621
                case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
622
                        if (vfd->vidioc_g_fmt_vbi_capture)
623
                                ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
624
                        break;
625
                case V4L2_BUF_TYPE_VIDEO_OUTPUT:
626
                        if (vfd->vidioc_g_fmt_video_output)
627
                                ret=vfd->vidioc_g_fmt_video_output(file,
628
                                                                fh, f);
629
                        break;
630
                case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
631
                        if (vfd->vidioc_g_fmt_output_overlay)
632
                                ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
633
                        break;
634
                case V4L2_BUF_TYPE_VBI_OUTPUT:
635
                        if (vfd->vidioc_g_fmt_vbi_output)
636
                                ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
637
                        break;
638
                case V4L2_BUF_TYPE_PRIVATE:
639
                        if (vfd->vidioc_g_fmt_type_private)
640
                                ret=vfd->vidioc_g_fmt_type_private(file,
641
                                                                fh, f);
642
                        break;
643
                }
644
 
645
                break;
646
        }
647
        case VIDIOC_S_FMT:
648
        {
649
                struct v4l2_format *f = (struct v4l2_format *)arg;
650
 
651
                /* FIXME: Should be one dump per type */
652
                dbgarg (cmd, "type=%s\n", prt_names(f->type,
653
                                        v4l2_type_names_FIXME));
654
 
655
                switch (f->type) {
656
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
657
                        v4l_print_pix_fmt(vfd,&f->fmt.pix);
658
                        if (vfd->vidioc_s_fmt_cap)
659
                                ret=vfd->vidioc_s_fmt_cap(file, fh, f);
660
                        break;
661
                case V4L2_BUF_TYPE_VIDEO_OVERLAY:
662
                        if (vfd->vidioc_s_fmt_overlay)
663
                                ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
664
                        break;
665
                case V4L2_BUF_TYPE_VBI_CAPTURE:
666
                        if (vfd->vidioc_s_fmt_vbi)
667
                                ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
668
                        break;
669
                case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
670
                        if (vfd->vidioc_s_fmt_vbi_output)
671
                                ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
672
                        break;
673
                case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
674
                        if (vfd->vidioc_s_fmt_vbi_capture)
675
                                ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
676
                        break;
677
                case V4L2_BUF_TYPE_VIDEO_OUTPUT:
678
                        if (vfd->vidioc_s_fmt_video_output)
679
                                ret=vfd->vidioc_s_fmt_video_output(file,
680
                                                                fh, f);
681
                        break;
682
                case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
683
                        if (vfd->vidioc_s_fmt_output_overlay)
684
                                ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
685
                        break;
686
                case V4L2_BUF_TYPE_VBI_OUTPUT:
687
                        if (vfd->vidioc_s_fmt_vbi_output)
688
                                ret=vfd->vidioc_s_fmt_vbi_output(file,
689
                                                                fh, f);
690
                        break;
691
                case V4L2_BUF_TYPE_PRIVATE:
692
                        if (vfd->vidioc_s_fmt_type_private)
693
                                ret=vfd->vidioc_s_fmt_type_private(file,
694
                                                                fh, f);
695
                        break;
696
                }
697
                break;
698
        }
699
        case VIDIOC_TRY_FMT:
700
        {
701
                struct v4l2_format *f = (struct v4l2_format *)arg;
702
 
703
                /* FIXME: Should be one dump per type */
704
                dbgarg (cmd, "type=%s\n", prt_names(f->type,
705
                                                v4l2_type_names_FIXME));
706
                switch (f->type) {
707
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
708
                        if (vfd->vidioc_try_fmt_cap)
709
                                ret=vfd->vidioc_try_fmt_cap(file, fh, f);
710
                        if (!ret)
711
                                v4l_print_pix_fmt(vfd,&f->fmt.pix);
712
                        break;
713
                case V4L2_BUF_TYPE_VIDEO_OVERLAY:
714
                        if (vfd->vidioc_try_fmt_overlay)
715
                                ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
716
                        break;
717
                case V4L2_BUF_TYPE_VBI_CAPTURE:
718
                        if (vfd->vidioc_try_fmt_vbi)
719
                                ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
720
                        break;
721
                case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
722
                        if (vfd->vidioc_try_fmt_vbi_output)
723
                                ret=vfd->vidioc_try_fmt_vbi_output(file,
724
                                                                fh, f);
725
                        break;
726
                case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
727
                        if (vfd->vidioc_try_fmt_vbi_capture)
728
                                ret=vfd->vidioc_try_fmt_vbi_capture(file,
729
                                                                fh, f);
730
                        break;
731
                case V4L2_BUF_TYPE_VIDEO_OUTPUT:
732
                        if (vfd->vidioc_try_fmt_video_output)
733
                                ret=vfd->vidioc_try_fmt_video_output(file,
734
                                                                fh, f);
735
                        break;
736
                case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
737
                        if (vfd->vidioc_try_fmt_output_overlay)
738
                                ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
739
                        break;
740
                case V4L2_BUF_TYPE_VBI_OUTPUT:
741
                        if (vfd->vidioc_try_fmt_vbi_output)
742
                                ret=vfd->vidioc_try_fmt_vbi_output(file,
743
                                                                fh, f);
744
                        break;
745
                case V4L2_BUF_TYPE_PRIVATE:
746
                        if (vfd->vidioc_try_fmt_type_private)
747
                                ret=vfd->vidioc_try_fmt_type_private(file,
748
                                                                fh, f);
749
                        break;
750
                }
751
 
752
                break;
753
        }
754
        /* FIXME: Those buf reqs could be handled here,
755
           with some changes on videobuf to allow its header to be included at
756
           videodev2.h or being merged at videodev2.
757
         */
758
        case VIDIOC_REQBUFS:
759
        {
760
                struct v4l2_requestbuffers *p=arg;
761
 
762
                if (!vfd->vidioc_reqbufs)
763
                        break;
764
                ret = check_fmt (vfd, p->type);
765
                if (ret)
766
                        break;
767
 
768
                ret=vfd->vidioc_reqbufs(file, fh, p);
769
                dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
770
                                p->count,
771
                                prt_names(p->type,v4l2_type_names_FIXME),
772
                                prt_names(p->memory,v4l2_memory_names));
773
                break;
774
        }
775
        case VIDIOC_QUERYBUF:
776
        {
777
                struct v4l2_buffer *p=arg;
778
 
779
                if (!vfd->vidioc_querybuf)
780
                        break;
781
                ret = check_fmt (vfd, p->type);
782
                if (ret)
783
                        break;
784
 
785
                ret=vfd->vidioc_querybuf(file, fh, p);
786
                if (!ret)
787
                        dbgbuf(cmd,vfd,p);
788
                break;
789
        }
790
        case VIDIOC_QBUF:
791
        {
792
                struct v4l2_buffer *p=arg;
793
 
794
                if (!vfd->vidioc_qbuf)
795
                        break;
796
                ret = check_fmt (vfd, p->type);
797
                if (ret)
798
                        break;
799
 
800
                ret=vfd->vidioc_qbuf(file, fh, p);
801
                if (!ret)
802
                        dbgbuf(cmd,vfd,p);
803
                break;
804
        }
805
        case VIDIOC_DQBUF:
806
        {
807
                struct v4l2_buffer *p=arg;
808
                if (!vfd->vidioc_dqbuf)
809
                        break;
810
                ret = check_fmt (vfd, p->type);
811
                if (ret)
812
                        break;
813
 
814
                ret=vfd->vidioc_dqbuf(file, fh, p);
815
                if (!ret)
816
                        dbgbuf(cmd,vfd,p);
817
                break;
818
        }
819
        case VIDIOC_OVERLAY:
820
        {
821
                int *i = arg;
822
 
823
                if (!vfd->vidioc_overlay)
824
                        break;
825
                dbgarg (cmd, "value=%d\n",*i);
826
                ret=vfd->vidioc_overlay(file, fh, *i);
827
                break;
828
        }
829
        case VIDIOC_G_FBUF:
830
        {
831
                struct v4l2_framebuffer *p=arg;
832
                if (!vfd->vidioc_g_fbuf)
833
                        break;
834
                ret=vfd->vidioc_g_fbuf(file, fh, arg);
835
                if (!ret) {
836
                        dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
837
                                        p->capability,p->flags,
838
                                        (unsigned long)p->base);
839
                        v4l_print_pix_fmt (vfd, &p->fmt);
840
                }
841
                break;
842
        }
843
        case VIDIOC_S_FBUF:
844
        {
845
                struct v4l2_framebuffer *p=arg;
846
                if (!vfd->vidioc_s_fbuf)
847
                        break;
848
 
849
                dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
850
                                p->capability,p->flags,(unsigned long)p->base);
851
                v4l_print_pix_fmt (vfd, &p->fmt);
852
                ret=vfd->vidioc_s_fbuf(file, fh, arg);
853
 
854
                break;
855
        }
856
        case VIDIOC_STREAMON:
857
        {
858
                enum v4l2_buf_type i = *(int *)arg;
859
                if (!vfd->vidioc_streamon)
860
                        break;
861
                dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
862
                ret=vfd->vidioc_streamon(file, fh,i);
863
                break;
864
        }
865
        case VIDIOC_STREAMOFF:
866
        {
867
                enum v4l2_buf_type i = *(int *)arg;
868
 
869
                if (!vfd->vidioc_streamoff)
870
                        break;
871
                dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
872
                ret=vfd->vidioc_streamoff(file, fh, i);
873
                break;
874
        }
875
        /* ---------- tv norms ---------- */
876
        case VIDIOC_ENUMSTD:
877
        {
878
                struct v4l2_standard *p = arg;
879
                v4l2_std_id id = vfd->tvnorms,curr_id=0;
880
                unsigned int index = p->index,i;
881
 
882
                if (index<0) {
883
                        ret=-EINVAL;
884
                        break;
885
                }
886
 
887
                /* Return norm array on a canonical way */
888
                for (i=0;i<= index && id; i++) {
889
                        if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
890
                                curr_id = V4L2_STD_PAL;
891
                        } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
892
                                curr_id = V4L2_STD_PAL_BG;
893
                        } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
894
                                curr_id = V4L2_STD_PAL_DK;
895
                        } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
896
                                curr_id = V4L2_STD_PAL_B;
897
                        } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
898
                                curr_id = V4L2_STD_PAL_B1;
899
                        } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
900
                                curr_id = V4L2_STD_PAL_G;
901
                        } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
902
                                curr_id = V4L2_STD_PAL_H;
903
                        } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
904
                                curr_id = V4L2_STD_PAL_I;
905
                        } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
906
                                curr_id = V4L2_STD_PAL_D;
907
                        } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
908
                                curr_id = V4L2_STD_PAL_D1;
909
                        } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
910
                                curr_id = V4L2_STD_PAL_K;
911
                        } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
912
                                curr_id = V4L2_STD_PAL_M;
913
                        } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
914
                                curr_id = V4L2_STD_PAL_N;
915
                        } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
916
                                curr_id = V4L2_STD_PAL_Nc;
917
                        } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
918
                                curr_id = V4L2_STD_PAL_60;
919
                        } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
920
                                curr_id = V4L2_STD_NTSC;
921
                        } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
922
                                curr_id = V4L2_STD_NTSC_M;
923
                        } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
924
                                curr_id = V4L2_STD_NTSC_M_JP;
925
                        } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
926
                                curr_id = V4L2_STD_NTSC_443;
927
                        } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
928
                                curr_id = V4L2_STD_NTSC_M_KR;
929
                        } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
930
                                curr_id = V4L2_STD_SECAM;
931
                        } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
932
                                curr_id = V4L2_STD_SECAM_DK;
933
                        } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
934
                                curr_id = V4L2_STD_SECAM_B;
935
                        } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
936
                                curr_id = V4L2_STD_SECAM_D;
937
                        } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
938
                                curr_id = V4L2_STD_SECAM_G;
939
                        } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
940
                                curr_id = V4L2_STD_SECAM_H;
941
                        } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
942
                                curr_id = V4L2_STD_SECAM_K;
943
                        } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
944
                                curr_id = V4L2_STD_SECAM_K1;
945
                        } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
946
                                curr_id = V4L2_STD_SECAM_L;
947
                        } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
948
                                curr_id = V4L2_STD_SECAM_LC;
949
                        } else {
950
                                break;
951
                        }
952
                        id &= ~curr_id;
953
                }
954
                if (i<=index)
955
                        return -EINVAL;
956
 
957
                v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
958
                p->index = index;
959
 
960
                dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
961
                                "framelines=%d\n", p->index,
962
                                (unsigned long long)p->id, p->name,
963
                                p->frameperiod.numerator,
964
                                p->frameperiod.denominator,
965
                                p->framelines);
966
 
967
                ret=0;
968
                break;
969
        }
970
        case VIDIOC_G_STD:
971
        {
972
                v4l2_std_id *id = arg;
973
 
974
                *id = vfd->current_norm;
975
 
976
                dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
977
 
978
                ret=0;
979
                break;
980
        }
981
        case VIDIOC_S_STD:
982
        {
983
                v4l2_std_id *id = arg,norm;
984
 
985
                dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
986
 
987
                norm = (*id) & vfd->tvnorms;
988
                if ( vfd->tvnorms && !norm)     /* Check if std is supported */
989
                        break;
990
 
991
                /* Calls the specific handler */
992
                if (vfd->vidioc_s_std)
993
                        ret=vfd->vidioc_s_std(file, fh, &norm);
994
                else
995
                        ret=-EINVAL;
996
 
997
                /* Updates standard information */
998
                if (ret>=0)
999
                        vfd->current_norm=norm;
1000
 
1001
                break;
1002
        }
1003
        case VIDIOC_QUERYSTD:
1004
        {
1005
                v4l2_std_id *p=arg;
1006
 
1007
                if (!vfd->vidioc_querystd)
1008
                        break;
1009
                ret=vfd->vidioc_querystd(file, fh, arg);
1010
                if (!ret)
1011
                        dbgarg (cmd, "detected std=%Lu\n",
1012
                                                (unsigned long long)*p);
1013
                break;
1014
        }
1015
        /* ------ input switching ---------- */
1016
        /* FIXME: Inputs can be handled inside videodev2 */
1017
        case VIDIOC_ENUMINPUT:
1018
        {
1019
                struct v4l2_input *p=arg;
1020
                int i=p->index;
1021
 
1022
                if (!vfd->vidioc_enum_input)
1023
                        break;
1024
                memset(p, 0, sizeof(*p));
1025
                p->index=i;
1026
 
1027
                ret=vfd->vidioc_enum_input(file, fh, p);
1028
                if (!ret)
1029
                        dbgarg (cmd, "index=%d, name=%s, type=%d, "
1030
                                        "audioset=%d, "
1031
                                        "tuner=%d, std=%Ld, status=%d\n",
1032
                                        p->index,p->name,p->type,p->audioset,
1033
                                        p->tuner,
1034
                                        (unsigned long long)p->std,
1035
                                        p->status);
1036
                break;
1037
        }
1038
        case VIDIOC_G_INPUT:
1039
        {
1040
                unsigned int *i = arg;
1041
 
1042
                if (!vfd->vidioc_g_input)
1043
                        break;
1044
                ret=vfd->vidioc_g_input(file, fh, i);
1045
                if (!ret)
1046
                        dbgarg (cmd, "value=%d\n",*i);
1047
                break;
1048
        }
1049
        case VIDIOC_S_INPUT:
1050
        {
1051
                unsigned int *i = arg;
1052
 
1053
                if (!vfd->vidioc_s_input)
1054
                        break;
1055
                dbgarg (cmd, "value=%d\n",*i);
1056
                ret=vfd->vidioc_s_input(file, fh, *i);
1057
                break;
1058
        }
1059
 
1060
        /* ------ output switching ---------- */
1061
        case VIDIOC_G_OUTPUT:
1062
        {
1063
                unsigned int *i = arg;
1064
 
1065
                if (!vfd->vidioc_g_output)
1066
                        break;
1067
                ret=vfd->vidioc_g_output(file, fh, i);
1068
                if (!ret)
1069
                        dbgarg (cmd, "value=%d\n",*i);
1070
                break;
1071
        }
1072
        case VIDIOC_S_OUTPUT:
1073
        {
1074
                unsigned int *i = arg;
1075
 
1076
                if (!vfd->vidioc_s_output)
1077
                        break;
1078
                dbgarg (cmd, "value=%d\n",*i);
1079
                ret=vfd->vidioc_s_output(file, fh, *i);
1080
                break;
1081
        }
1082
 
1083
        /* --- controls ---------------------------------------------- */
1084
        case VIDIOC_QUERYCTRL:
1085
        {
1086
                struct v4l2_queryctrl *p=arg;
1087
 
1088
                if (!vfd->vidioc_queryctrl)
1089
                        break;
1090
                ret=vfd->vidioc_queryctrl(file, fh, p);
1091
 
1092
                if (!ret)
1093
                        dbgarg (cmd, "id=%d, type=%d, name=%s, "
1094
                                        "min/max=%d/%d,"
1095
                                        " step=%d, default=%d, flags=0x%08x\n",
1096
                                        p->id,p->type,p->name,p->minimum,
1097
                                        p->maximum,p->step,p->default_value,
1098
                                        p->flags);
1099
                break;
1100
        }
1101
        case VIDIOC_G_CTRL:
1102
        {
1103
                struct v4l2_control *p = arg;
1104
 
1105
                if (!vfd->vidioc_g_ctrl)
1106
                        break;
1107
                dbgarg(cmd, "Enum for index=%d\n", p->id);
1108
 
1109
                ret=vfd->vidioc_g_ctrl(file, fh, p);
1110
                if (!ret)
1111
                        dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1112
                break;
1113
        }
1114
        case VIDIOC_S_CTRL:
1115
        {
1116
                struct v4l2_control *p = arg;
1117
 
1118
                if (!vfd->vidioc_s_ctrl)
1119
                        break;
1120
                dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1121
 
1122
                ret=vfd->vidioc_s_ctrl(file, fh, p);
1123
                break;
1124
        }
1125
        case VIDIOC_G_EXT_CTRLS:
1126
        {
1127
                struct v4l2_ext_controls *p = arg;
1128
 
1129
                if (vfd->vidioc_g_ext_ctrls) {
1130
                        dbgarg(cmd, "count=%d\n", p->count);
1131
 
1132
                        ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1133
                }
1134
                break;
1135
        }
1136
        case VIDIOC_S_EXT_CTRLS:
1137
        {
1138
                struct v4l2_ext_controls *p = arg;
1139
 
1140
                if (vfd->vidioc_s_ext_ctrls) {
1141
                        dbgarg(cmd, "count=%d\n", p->count);
1142
 
1143
                        ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1144
                }
1145
                break;
1146
        }
1147
        case VIDIOC_TRY_EXT_CTRLS:
1148
        {
1149
                struct v4l2_ext_controls *p = arg;
1150
 
1151
                if (vfd->vidioc_try_ext_ctrls) {
1152
                        dbgarg(cmd, "count=%d\n", p->count);
1153
 
1154
                        ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1155
                }
1156
                break;
1157
        }
1158
        case VIDIOC_QUERYMENU:
1159
        {
1160
                struct v4l2_querymenu *p=arg;
1161
                if (!vfd->vidioc_querymenu)
1162
                        break;
1163
                ret=vfd->vidioc_querymenu(file, fh, p);
1164
                if (!ret)
1165
                        dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1166
                                                p->id,p->index,p->name);
1167
                break;
1168
        }
1169
        /* --- audio ---------------------------------------------- */
1170
        case VIDIOC_ENUMAUDIO:
1171
        {
1172
                struct v4l2_audio *p=arg;
1173
 
1174
                if (!vfd->vidioc_enumaudio)
1175
                        break;
1176
                dbgarg(cmd, "Enum for index=%d\n", p->index);
1177
                ret=vfd->vidioc_enumaudio(file, fh, p);
1178
                if (!ret)
1179
                        dbgarg2("index=%d, name=%s, capability=%d, "
1180
                                        "mode=%d\n",p->index,p->name,
1181
                                        p->capability, p->mode);
1182
                break;
1183
        }
1184
        case VIDIOC_G_AUDIO:
1185
        {
1186
                struct v4l2_audio *p=arg;
1187
                __u32 index=p->index;
1188
 
1189
                if (!vfd->vidioc_g_audio)
1190
                        break;
1191
 
1192
                memset(p,0,sizeof(*p));
1193
                p->index=index;
1194
                dbgarg(cmd, "Get for index=%d\n", p->index);
1195
                ret=vfd->vidioc_g_audio(file, fh, p);
1196
                if (!ret)
1197
                        dbgarg2("index=%d, name=%s, capability=%d, "
1198
                                        "mode=%d\n",p->index,
1199
                                        p->name,p->capability, p->mode);
1200
                break;
1201
        }
1202
        case VIDIOC_S_AUDIO:
1203
        {
1204
                struct v4l2_audio *p=arg;
1205
 
1206
                if (!vfd->vidioc_s_audio)
1207
                        break;
1208
                dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1209
                                        "mode=%d\n", p->index, p->name,
1210
                                        p->capability, p->mode);
1211
                ret=vfd->vidioc_s_audio(file, fh, p);
1212
                break;
1213
        }
1214
        case VIDIOC_ENUMAUDOUT:
1215
        {
1216
                struct v4l2_audioout *p=arg;
1217
 
1218
                if (!vfd->vidioc_enumaudout)
1219
                        break;
1220
                dbgarg(cmd, "Enum for index=%d\n", p->index);
1221
                ret=vfd->vidioc_enumaudout(file, fh, p);
1222
                if (!ret)
1223
                        dbgarg2("index=%d, name=%s, capability=%d, "
1224
                                        "mode=%d\n", p->index, p->name,
1225
                                        p->capability,p->mode);
1226
                break;
1227
        }
1228
        case VIDIOC_G_AUDOUT:
1229
        {
1230
                struct v4l2_audioout *p=arg;
1231
 
1232
                if (!vfd->vidioc_g_audout)
1233
                        break;
1234
                dbgarg(cmd, "Enum for index=%d\n", p->index);
1235
                ret=vfd->vidioc_g_audout(file, fh, p);
1236
                if (!ret)
1237
                        dbgarg2("index=%d, name=%s, capability=%d, "
1238
                                        "mode=%d\n", p->index, p->name,
1239
                                        p->capability,p->mode);
1240
                break;
1241
        }
1242
        case VIDIOC_S_AUDOUT:
1243
        {
1244
                struct v4l2_audioout *p=arg;
1245
 
1246
                if (!vfd->vidioc_s_audout)
1247
                        break;
1248
                dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1249
                                        "mode=%d\n", p->index, p->name,
1250
                                        p->capability,p->mode);
1251
 
1252
                ret=vfd->vidioc_s_audout(file, fh, p);
1253
                break;
1254
        }
1255
        case VIDIOC_G_MODULATOR:
1256
        {
1257
                struct v4l2_modulator *p=arg;
1258
                if (!vfd->vidioc_g_modulator)
1259
                        break;
1260
                ret=vfd->vidioc_g_modulator(file, fh, p);
1261
                if (!ret)
1262
                        dbgarg(cmd, "index=%d, name=%s, "
1263
                                        "capability=%d, rangelow=%d,"
1264
                                        " rangehigh=%d, txsubchans=%d\n",
1265
                                        p->index, p->name,p->capability,
1266
                                        p->rangelow, p->rangehigh,
1267
                                        p->txsubchans);
1268
                break;
1269
        }
1270
        case VIDIOC_S_MODULATOR:
1271
        {
1272
                struct v4l2_modulator *p=arg;
1273
                if (!vfd->vidioc_s_modulator)
1274
                        break;
1275
                dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1276
                                "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1277
                                p->index, p->name,p->capability,p->rangelow,
1278
                                p->rangehigh,p->txsubchans);
1279
                        ret=vfd->vidioc_s_modulator(file, fh, p);
1280
                break;
1281
        }
1282
        case VIDIOC_G_CROP:
1283
        {
1284
                struct v4l2_crop *p=arg;
1285
                if (!vfd->vidioc_g_crop)
1286
                        break;
1287
                ret=vfd->vidioc_g_crop(file, fh, p);
1288
                if (!ret) {
1289
                        dbgarg(cmd, "type=%d\n", p->type);
1290
                        dbgrect(vfd, "", &p->c);
1291
                }
1292
                break;
1293
        }
1294
        case VIDIOC_S_CROP:
1295
        {
1296
                struct v4l2_crop *p=arg;
1297
                if (!vfd->vidioc_s_crop)
1298
                        break;
1299
                dbgarg(cmd, "type=%d\n", p->type);
1300
                dbgrect(vfd, "", &p->c);
1301
                ret=vfd->vidioc_s_crop(file, fh, p);
1302
                break;
1303
        }
1304
        case VIDIOC_CROPCAP:
1305
        {
1306
                struct v4l2_cropcap *p=arg;
1307
                /*FIXME: Should also show v4l2_fract pixelaspect */
1308
                if (!vfd->vidioc_cropcap)
1309
                        break;
1310
                dbgarg(cmd, "type=%d\n", p->type);
1311
                dbgrect(vfd, "bounds ", &p->bounds);
1312
                dbgrect(vfd, "defrect ", &p->defrect);
1313
                ret=vfd->vidioc_cropcap(file, fh, p);
1314
                break;
1315
        }
1316
        case VIDIOC_G_JPEGCOMP:
1317
        {
1318
                struct v4l2_jpegcompression *p=arg;
1319
                if (!vfd->vidioc_g_jpegcomp)
1320
                        break;
1321
                ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1322
                if (!ret)
1323
                        dbgarg (cmd, "quality=%d, APPn=%d, "
1324
                                                "APP_len=%d, COM_len=%d, "
1325
                                                "jpeg_markers=%d\n",
1326
                                                p->quality,p->APPn,p->APP_len,
1327
                                                p->COM_len,p->jpeg_markers);
1328
                break;
1329
        }
1330
        case VIDIOC_S_JPEGCOMP:
1331
        {
1332
                struct v4l2_jpegcompression *p=arg;
1333
                if (!vfd->vidioc_g_jpegcomp)
1334
                        break;
1335
                dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1336
                                        "COM_len=%d, jpeg_markers=%d\n",
1337
                                        p->quality,p->APPn,p->APP_len,
1338
                                        p->COM_len,p->jpeg_markers);
1339
                        ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1340
                break;
1341
        }
1342
        case VIDIOC_G_ENC_INDEX:
1343
        {
1344
                struct v4l2_enc_idx *p=arg;
1345
 
1346
                if (!vfd->vidioc_g_enc_index)
1347
                        break;
1348
                ret=vfd->vidioc_g_enc_index(file, fh, p);
1349
                if (!ret)
1350
                        dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1351
                                        p->entries,p->entries_cap);
1352
                break;
1353
        }
1354
        case VIDIOC_ENCODER_CMD:
1355
        {
1356
                struct v4l2_encoder_cmd *p=arg;
1357
 
1358
                if (!vfd->vidioc_encoder_cmd)
1359
                        break;
1360
                ret=vfd->vidioc_encoder_cmd(file, fh, p);
1361
                if (!ret)
1362
                        dbgarg (cmd, "cmd=%d, flags=%d\n",
1363
                                        p->cmd,p->flags);
1364
                break;
1365
        }
1366
        case VIDIOC_TRY_ENCODER_CMD:
1367
        {
1368
                struct v4l2_encoder_cmd *p=arg;
1369
 
1370
                if (!vfd->vidioc_try_encoder_cmd)
1371
                        break;
1372
                ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
1373
                if (!ret)
1374
                        dbgarg (cmd, "cmd=%d, flags=%d\n",
1375
                                        p->cmd,p->flags);
1376
                break;
1377
        }
1378
        case VIDIOC_G_PARM:
1379
        {
1380
                struct v4l2_streamparm *p=arg;
1381
                __u32 type=p->type;
1382
 
1383
                memset(p,0,sizeof(*p));
1384
                p->type=type;
1385
 
1386
                if (vfd->vidioc_g_parm) {
1387
                        ret=vfd->vidioc_g_parm(file, fh, p);
1388
                } else {
1389
                        struct v4l2_standard s;
1390
 
1391
                        if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1392
                                return -EINVAL;
1393
 
1394
                        v4l2_video_std_construct(&s, vfd->current_norm,
1395
                                                 v4l2_norm_to_name(vfd->current_norm));
1396
 
1397
                        p->parm.capture.timeperframe = s.frameperiod;
1398
                        ret=0;
1399
                }
1400
 
1401
                dbgarg (cmd, "type=%d\n", p->type);
1402
                break;
1403
        }
1404
        case VIDIOC_S_PARM:
1405
        {
1406
                struct v4l2_streamparm *p=arg;
1407
                if (!vfd->vidioc_s_parm)
1408
                        break;
1409
                dbgarg (cmd, "type=%d\n", p->type);
1410
                ret=vfd->vidioc_s_parm(file, fh, p);
1411
                break;
1412
        }
1413
        case VIDIOC_G_TUNER:
1414
        {
1415
                struct v4l2_tuner *p=arg;
1416
                __u32 index=p->index;
1417
 
1418
                if (!vfd->vidioc_g_tuner)
1419
                        break;
1420
 
1421
                memset(p,0,sizeof(*p));
1422
                p->index=index;
1423
 
1424
                ret=vfd->vidioc_g_tuner(file, fh, p);
1425
                if (!ret)
1426
                        dbgarg (cmd, "index=%d, name=%s, type=%d, "
1427
                                        "capability=%d, rangelow=%d, "
1428
                                        "rangehigh=%d, signal=%d, afc=%d, "
1429
                                        "rxsubchans=%d, audmode=%d\n",
1430
                                        p->index, p->name, p->type,
1431
                                        p->capability, p->rangelow,
1432
                                        p->rangehigh, p->rxsubchans,
1433
                                        p->audmode, p->signal, p->afc);
1434
                break;
1435
        }
1436
        case VIDIOC_S_TUNER:
1437
        {
1438
                struct v4l2_tuner *p=arg;
1439
                if (!vfd->vidioc_s_tuner)
1440
                        break;
1441
                dbgarg (cmd, "index=%d, name=%s, type=%d, "
1442
                                "capability=%d, rangelow=%d, rangehigh=%d, "
1443
                                "signal=%d, afc=%d, rxsubchans=%d, "
1444
                                "audmode=%d\n",p->index, p->name, p->type,
1445
                                p->capability, p->rangelow,p->rangehigh,
1446
                                p->rxsubchans, p->audmode, p->signal,
1447
                                p->afc);
1448
                ret=vfd->vidioc_s_tuner(file, fh, p);
1449
                break;
1450
        }
1451
        case VIDIOC_G_FREQUENCY:
1452
        {
1453
                struct v4l2_frequency *p=arg;
1454
                if (!vfd->vidioc_g_frequency)
1455
                        break;
1456
 
1457
                memset(p,0,sizeof(*p));
1458
 
1459
                ret=vfd->vidioc_g_frequency(file, fh, p);
1460
                if (!ret)
1461
                        dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1462
                                                p->tuner,p->type,p->frequency);
1463
                break;
1464
        }
1465
        case VIDIOC_S_FREQUENCY:
1466
        {
1467
                struct v4l2_frequency *p=arg;
1468
                if (!vfd->vidioc_s_frequency)
1469
                        break;
1470
                dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1471
                                p->tuner,p->type,p->frequency);
1472
                ret=vfd->vidioc_s_frequency(file, fh, p);
1473
                break;
1474
        }
1475
        case VIDIOC_G_SLICED_VBI_CAP:
1476
        {
1477
                struct v4l2_sliced_vbi_cap *p=arg;
1478
                if (!vfd->vidioc_g_sliced_vbi_cap)
1479
                        break;
1480
                ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1481
                if (!ret)
1482
                        dbgarg (cmd, "service_set=%d\n", p->service_set);
1483
                break;
1484
        }
1485
        case VIDIOC_LOG_STATUS:
1486
        {
1487
                if (!vfd->vidioc_log_status)
1488
                        break;
1489
                ret=vfd->vidioc_log_status(file, fh);
1490
                break;
1491
        }
1492
#ifdef CONFIG_VIDEO_ADV_DEBUG
1493
        case VIDIOC_DBG_G_REGISTER:
1494
        {
1495
                struct v4l2_register *p=arg;
1496
                if (!capable(CAP_SYS_ADMIN))
1497
                        ret=-EPERM;
1498
                else if (vfd->vidioc_g_register)
1499
                        ret=vfd->vidioc_g_register(file, fh, p);
1500
                break;
1501
        }
1502
        case VIDIOC_DBG_S_REGISTER:
1503
        {
1504
                struct v4l2_register *p=arg;
1505
                if (!capable(CAP_SYS_ADMIN))
1506
                        ret=-EPERM;
1507
                else if (vfd->vidioc_s_register)
1508
                        ret=vfd->vidioc_s_register(file, fh, p);
1509
                break;
1510
        }
1511
#endif
1512
        case VIDIOC_G_CHIP_IDENT:
1513
        {
1514
                struct v4l2_chip_ident *p=arg;
1515
                if (!vfd->vidioc_g_chip_ident)
1516
                        break;
1517
                ret=vfd->vidioc_g_chip_ident(file, fh, p);
1518
                if (!ret)
1519
                        dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1520
                break;
1521
        }
1522
        } /* switch */
1523
 
1524
        if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1525
                if (ret<0) {
1526
                        printk ("%s: err:\n", vfd->name);
1527
                        v4l_print_ioctl(vfd->name, cmd);
1528
                }
1529
        }
1530
 
1531
        return ret;
1532
}
1533
 
1534
int video_ioctl2 (struct inode *inode, struct file *file,
1535
               unsigned int cmd, unsigned long arg)
1536
{
1537
        char    sbuf[128];
1538
        void    *mbuf = NULL;
1539
        void    *parg = NULL;
1540
        int     err  = -EINVAL;
1541
        int     is_ext_ctrl;
1542
        size_t  ctrls_size = 0;
1543
        void __user *user_ptr = NULL;
1544
 
1545
#ifdef __OLD_VIDIOC_
1546
        cmd = video_fix_command(cmd);
1547
#endif
1548
        is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1549
                       cmd == VIDIOC_TRY_EXT_CTRLS);
1550
 
1551
        /*  Copy arguments into temp kernel buffer  */
1552
        switch (_IOC_DIR(cmd)) {
1553
        case _IOC_NONE:
1554
                parg = NULL;
1555
                break;
1556
        case _IOC_READ:
1557
        case _IOC_WRITE:
1558
        case (_IOC_WRITE | _IOC_READ):
1559
                if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1560
                        parg = sbuf;
1561
                } else {
1562
                        /* too big to allocate from stack */
1563
                        mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1564
                        if (NULL == mbuf)
1565
                                return -ENOMEM;
1566
                        parg = mbuf;
1567
                }
1568
 
1569
                err = -EFAULT;
1570
                if (_IOC_DIR(cmd) & _IOC_WRITE)
1571
                        if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1572
                                goto out;
1573
                break;
1574
        }
1575
 
1576
        if (is_ext_ctrl) {
1577
                struct v4l2_ext_controls *p = parg;
1578
 
1579
                /* In case of an error, tell the caller that it wasn't
1580
                   a specific control that caused it. */
1581
                p->error_idx = p->count;
1582
                user_ptr = (void __user *)p->controls;
1583
                if (p->count) {
1584
                        ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1585
                        /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1586
                        mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1587
                        err = -ENOMEM;
1588
                        if (NULL == mbuf)
1589
                                goto out_ext_ctrl;
1590
                        err = -EFAULT;
1591
                        if (copy_from_user(mbuf, user_ptr, ctrls_size))
1592
                                goto out_ext_ctrl;
1593
                        p->controls = mbuf;
1594
                }
1595
        }
1596
 
1597
        /* Handles IOCTL */
1598
        err = __video_do_ioctl(inode, file, cmd, parg);
1599
        if (err == -ENOIOCTLCMD)
1600
                err = -EINVAL;
1601
        if (is_ext_ctrl) {
1602
                struct v4l2_ext_controls *p = parg;
1603
 
1604
                p->controls = (void *)user_ptr;
1605
                if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1606
                        err = -EFAULT;
1607
                goto out_ext_ctrl;
1608
        }
1609
        if (err < 0)
1610
                goto out;
1611
 
1612
out_ext_ctrl:
1613
        /*  Copy results into user buffer  */
1614
        switch (_IOC_DIR(cmd))
1615
        {
1616
        case _IOC_READ:
1617
        case (_IOC_WRITE | _IOC_READ):
1618
                if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1619
                        err = -EFAULT;
1620
                break;
1621
        }
1622
 
1623
out:
1624
        kfree(mbuf);
1625
        return err;
1626
}
1627
 
1628
 
1629
static const struct file_operations video_fops;
1630
 
1631
/**
1632
 *      video_register_device - register video4linux devices
1633
 *      @vfd:  video device structure we want to register
1634
 *      @type: type of device to register
1635
 *      @nr:   which device number (0 == /dev/video0, 1 == /dev/video1, ...
1636
 *             -1 == first free)
1637
 *
1638
 *      The registration code assigns minor numbers based on the type
1639
 *      requested. -ENFILE is returned in all the device slots for this
1640
 *      category are full. If not then the minor field is set and the
1641
 *      driver initialize function is called (if non %NULL).
1642
 *
1643
 *      Zero is returned on success.
1644
 *
1645
 *      Valid types are
1646
 *
1647
 *      %VFL_TYPE_GRABBER - A frame grabber
1648
 *
1649
 *      %VFL_TYPE_VTX - A teletext device
1650
 *
1651
 *      %VFL_TYPE_VBI - Vertical blank data (undecoded)
1652
 *
1653
 *      %VFL_TYPE_RADIO - A radio card
1654
 */
1655
 
1656
int video_register_device(struct video_device *vfd, int type, int nr)
1657
{
1658
        int i=0;
1659
        int base;
1660
        int end;
1661
        int ret;
1662
        char *name_base;
1663
 
1664
        switch(type)
1665
        {
1666
                case VFL_TYPE_GRABBER:
1667
                        base=MINOR_VFL_TYPE_GRABBER_MIN;
1668
                        end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1669
                        name_base = "video";
1670
                        break;
1671
                case VFL_TYPE_VTX:
1672
                        base=MINOR_VFL_TYPE_VTX_MIN;
1673
                        end=MINOR_VFL_TYPE_VTX_MAX+1;
1674
                        name_base = "vtx";
1675
                        break;
1676
                case VFL_TYPE_VBI:
1677
                        base=MINOR_VFL_TYPE_VBI_MIN;
1678
                        end=MINOR_VFL_TYPE_VBI_MAX+1;
1679
                        name_base = "vbi";
1680
                        break;
1681
                case VFL_TYPE_RADIO:
1682
                        base=MINOR_VFL_TYPE_RADIO_MIN;
1683
                        end=MINOR_VFL_TYPE_RADIO_MAX+1;
1684
                        name_base = "radio";
1685
                        break;
1686
                default:
1687
                        printk(KERN_ERR "%s called with unknown type: %d\n",
1688
                               __FUNCTION__, type);
1689
                        return -1;
1690
        }
1691
 
1692
        /* pick a minor number */
1693
        mutex_lock(&videodev_lock);
1694
        if (nr >= 0  &&  nr < end-base) {
1695
                /* use the one the driver asked for */
1696
                i = base+nr;
1697
                if (NULL != video_device[i]) {
1698
                        mutex_unlock(&videodev_lock);
1699
                        return -ENFILE;
1700
                }
1701
        } else {
1702
                /* use first free */
1703
                for(i=base;i<end;i++)
1704
                        if (NULL == video_device[i])
1705
                                break;
1706
                if (i == end) {
1707
                        mutex_unlock(&videodev_lock);
1708
                        return -ENFILE;
1709
                }
1710
        }
1711
        video_device[i]=vfd;
1712
        vfd->minor=i;
1713
        mutex_unlock(&videodev_lock);
1714
        mutex_init(&vfd->lock);
1715
 
1716
        /* sysfs class */
1717
        memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1718
        if (vfd->dev)
1719
                vfd->class_dev.parent = vfd->dev;
1720
        vfd->class_dev.class       = &video_class;
1721
        vfd->class_dev.devt        = MKDEV(VIDEO_MAJOR, vfd->minor);
1722
        sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
1723
        ret = device_register(&vfd->class_dev);
1724
        if (ret < 0) {
1725
                printk(KERN_ERR "%s: device_register failed\n",
1726
                       __FUNCTION__);
1727
                goto fail_minor;
1728
        }
1729
 
1730
#if 1
1731
        /* needed until all drivers are fixed */
1732
        if (!vfd->release)
1733
                printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1734
                       "Please fix your driver for proper sysfs support, see "
1735
                       "http://lwn.net/Articles/36850/\n", vfd->name);
1736
#endif
1737
        return 0;
1738
 
1739
fail_minor:
1740
        mutex_lock(&videodev_lock);
1741
        video_device[vfd->minor] = NULL;
1742
        vfd->minor = -1;
1743
        mutex_unlock(&videodev_lock);
1744
        return ret;
1745
}
1746
 
1747
/**
1748
 *      video_unregister_device - unregister a video4linux device
1749
 *      @vfd: the device to unregister
1750
 *
1751
 *      This unregisters the passed device and deassigns the minor
1752
 *      number. Future open calls will be met with errors.
1753
 */
1754
 
1755
void video_unregister_device(struct video_device *vfd)
1756
{
1757
        mutex_lock(&videodev_lock);
1758
        if(video_device[vfd->minor]!=vfd)
1759
                panic("videodev: bad unregister");
1760
 
1761
        video_device[vfd->minor]=NULL;
1762
        device_unregister(&vfd->class_dev);
1763
        mutex_unlock(&videodev_lock);
1764
}
1765
 
1766
/*
1767
 * Video fs operations
1768
 */
1769
static const struct file_operations video_fops=
1770
{
1771
        .owner          = THIS_MODULE,
1772
        .llseek         = no_llseek,
1773
        .open           = video_open,
1774
};
1775
 
1776
/*
1777
 *      Initialise video for linux
1778
 */
1779
 
1780
static int __init videodev_init(void)
1781
{
1782
        int ret;
1783
 
1784
        printk(KERN_INFO "Linux video capture interface: v2.00\n");
1785
        if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1786
                printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1787
                return -EIO;
1788
        }
1789
 
1790
        ret = class_register(&video_class);
1791
        if (ret < 0) {
1792
                unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1793
                printk(KERN_WARNING "video_dev: class_register failed\n");
1794
                return -EIO;
1795
        }
1796
 
1797
        return 0;
1798
}
1799
 
1800
static void __exit videodev_exit(void)
1801
{
1802
        class_unregister(&video_class);
1803
        unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1804
}
1805
 
1806
module_init(videodev_init)
1807
module_exit(videodev_exit)
1808
 
1809
EXPORT_SYMBOL(video_register_device);
1810
EXPORT_SYMBOL(video_unregister_device);
1811
EXPORT_SYMBOL(video_devdata);
1812
EXPORT_SYMBOL(video_usercopy);
1813
EXPORT_SYMBOL(video_exclusive_open);
1814
EXPORT_SYMBOL(video_exclusive_release);
1815
EXPORT_SYMBOL(video_ioctl2);
1816
EXPORT_SYMBOL(video_device_alloc);
1817
EXPORT_SYMBOL(video_device_release);
1818
 
1819
MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1820
MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1821
MODULE_LICENSE("GPL");
1822
 
1823
 
1824
/*
1825
 * Local variables:
1826
 * c-basic-offset: 8
1827
 * End:
1828
 */

powered by: WebSVN 2.1.0

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