diff options
Diffstat (limited to 'drivers/media/video/videodev.c')
-rw-r--r-- | drivers/media/video/videodev.c | 319 |
1 files changed, 113 insertions, 206 deletions
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 0d9b63762a4..67a661cf521 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -18,14 +18,14 @@ #define dbgarg(cmd, fmt, arg...) \ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ - printk (KERN_DEBUG "%s: ", vfd->name); \ + printk(KERN_DEBUG "%s: ", vfd->name); \ v4l_printk_ioctl(cmd); \ - printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \ + printk(" " fmt, ## arg); \ } #define dbgarg2(fmt, arg...) \ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ - printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); + printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg); #include <linux/module.h> #include <linux/types.h> @@ -51,12 +51,51 @@ #define VIDEO_NUM_DEVICES 256 #define VIDEO_NAME "video4linux" +struct std_descr { + v4l2_std_id std; + const char *descr; +}; + +static const struct std_descr standards[] = { + { V4L2_STD_NTSC, "NTSC" }, + { V4L2_STD_NTSC_M, "NTSC-M" }, + { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, + { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, + { V4L2_STD_NTSC_443, "NTSC-443" }, + { V4L2_STD_PAL, "PAL" }, + { V4L2_STD_PAL_BG, "PAL-BG" }, + { V4L2_STD_PAL_B, "PAL-B" }, + { V4L2_STD_PAL_B1, "PAL-B1" }, + { V4L2_STD_PAL_G, "PAL-G" }, + { V4L2_STD_PAL_H, "PAL-H" }, + { V4L2_STD_PAL_I, "PAL-I" }, + { V4L2_STD_PAL_DK, "PAL-DK" }, + { V4L2_STD_PAL_D, "PAL-D" }, + { V4L2_STD_PAL_D1, "PAL-D1" }, + { V4L2_STD_PAL_K, "PAL-K" }, + { V4L2_STD_PAL_M, "PAL-M" }, + { V4L2_STD_PAL_N, "PAL-N" }, + { V4L2_STD_PAL_Nc, "PAL-Nc" }, + { V4L2_STD_PAL_60, "PAL-60" }, + { V4L2_STD_SECAM, "SECAM" }, + { V4L2_STD_SECAM_B, "SECAM-B" }, + { V4L2_STD_SECAM_G, "SECAM-G" }, + { V4L2_STD_SECAM_H, "SECAM-H" }, + { V4L2_STD_SECAM_DK, "SECAM-DK" }, + { V4L2_STD_SECAM_D, "SECAM-D" }, + { V4L2_STD_SECAM_K, "SECAM-K" }, + { V4L2_STD_SECAM_K1, "SECAM-K1" }, + { V4L2_STD_SECAM_L, "SECAM-L" }, + { V4L2_STD_SECAM_LC, "SECAM-Lc" }, + { 0, "Unknown" } +}; + /* video4linux standard ID conversion to standard name */ -char *v4l2_norm_to_name(v4l2_std_id id) +const char *v4l2_norm_to_name(v4l2_std_id id) { - char *name; u32 myid = id; + int i; /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle 64 bit comparations. So, on that architecture, with some gcc @@ -64,110 +103,17 @@ char *v4l2_norm_to_name(v4l2_std_id id) */ BUG_ON(myid != id); - switch (myid) { - case V4L2_STD_PAL: - name = "PAL"; - break; - case V4L2_STD_PAL_BG: - name = "PAL-BG"; - break; - case V4L2_STD_PAL_DK: - name = "PAL-DK"; - break; - case V4L2_STD_PAL_B: - name = "PAL-B"; - break; - case V4L2_STD_PAL_B1: - name = "PAL-B1"; - break; - case V4L2_STD_PAL_G: - name = "PAL-G"; - break; - case V4L2_STD_PAL_H: - name = "PAL-H"; - break; - case V4L2_STD_PAL_I: - name = "PAL-I"; - break; - case V4L2_STD_PAL_D: - name = "PAL-D"; - break; - case V4L2_STD_PAL_D1: - name = "PAL-D1"; - break; - case V4L2_STD_PAL_K: - name = "PAL-K"; - break; - case V4L2_STD_PAL_M: - name = "PAL-M"; - break; - case V4L2_STD_PAL_N: - name = "PAL-N"; - break; - case V4L2_STD_PAL_Nc: - name = "PAL-Nc"; - break; - case V4L2_STD_PAL_60: - name = "PAL-60"; - break; - case V4L2_STD_NTSC: - name = "NTSC"; - break; - case V4L2_STD_NTSC_M: - name = "NTSC-M"; - break; - case V4L2_STD_NTSC_M_JP: - name = "NTSC-M-JP"; - break; - case V4L2_STD_NTSC_443: - name = "NTSC-443"; - break; - case V4L2_STD_NTSC_M_KR: - name = "NTSC-M-KR"; - break; - case V4L2_STD_SECAM: - name = "SECAM"; - break; - case V4L2_STD_SECAM_DK: - name = "SECAM-DK"; - break; - case V4L2_STD_SECAM_B: - name = "SECAM-B"; - break; - case V4L2_STD_SECAM_D: - name = "SECAM-D"; - break; - case V4L2_STD_SECAM_G: - name = "SECAM-G"; - break; - case V4L2_STD_SECAM_H: - name = "SECAM-H"; - break; - case V4L2_STD_SECAM_K: - name = "SECAM-K"; - break; - case V4L2_STD_SECAM_K1: - name = "SECAM-K1"; - break; - case V4L2_STD_SECAM_L: - name = "SECAM-L"; - break; - case V4L2_STD_SECAM_LC: - name = "SECAM-LC"; - break; - default: - name = "Unknown"; - break; - } - - return name; + for (i = 0; standards[i].std; i++) + if (myid == standards[i].std) + break; + return standards[i].descr; } EXPORT_SYMBOL(v4l2_norm_to_name); /* Fill in the fields of a v4l2_standard structure according to the 'id' and 'transmission' parameters. Returns negative on error. */ int v4l2_video_std_construct(struct v4l2_standard *vs, - int id, char *name) + int id, const char *name) { u32 index = vs->index; @@ -378,38 +324,45 @@ static const char *v4l2_int_ioctls[] = { external ioctl messages as well as internal V4L ioctl */ void v4l_printk_ioctl(unsigned int cmd) { - char *dir; + char *dir, *type; - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "*ERR*"; break; - } switch (_IOC_TYPE(cmd)) { case 'd': - printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? - v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; + if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) { + type = "v4l2_int"; + break; + } + printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]); + return; #ifdef CONFIG_VIDEO_V4L1_COMPAT case 'v': - printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L1_IOCTLS) ? - v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; + if (_IOC_NR(cmd) >= V4L1_IOCTLS) { + type = "v4l1"; + break; + } + printk("%s", v4l1_ioctls[_IOC_NR(cmd)]); + return; #endif case 'V': - printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_IOCTLS) ? - v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; - + if (_IOC_NR(cmd) >= V4L2_IOCTLS) { + type = "v4l2"; + break; + } + printk("%s", v4l2_ioctls[_IOC_NR(cmd)]); + return; default: - printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", - _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); + type = "unknown"; } + + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: dir = "--"; break; + case _IOC_READ: dir = "r-"; break; + case _IOC_WRITE: dir = "-w"; break; + case _IOC_READ | _IOC_WRITE: dir = "rw"; break; + default: dir = "*ERR*"; break; + } + printk("%s ioctl '%c', dir=%s, #%d (0x%08x)", + type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); } EXPORT_SYMBOL(v4l_printk_ioctl); @@ -774,6 +727,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if ( (vfd->debug & V4L2_DEBUG_IOCTL) && !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { v4l_print_ioctl(vfd->name, cmd); + printk("\n"); } #ifdef CONFIG_VIDEO_V4L1_COMPAT @@ -1210,95 +1164,40 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_ENUMSTD: { struct v4l2_standard *p = arg; - v4l2_std_id id = vfd->tvnorms,curr_id=0; - unsigned int index = p->index,i; - - if (index<0) { - ret=-EINVAL; - break; - } - - /* Return norm array on a canonical way */ - for (i=0;i<= index && id; i++) { - if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) { - curr_id = V4L2_STD_PAL; - } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) { - curr_id = V4L2_STD_PAL_BG; - } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) { - curr_id = V4L2_STD_PAL_DK; - } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) { - curr_id = V4L2_STD_PAL_B; - } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) { - curr_id = V4L2_STD_PAL_B1; - } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) { - curr_id = V4L2_STD_PAL_G; - } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) { - curr_id = V4L2_STD_PAL_H; - } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) { - curr_id = V4L2_STD_PAL_I; - } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) { - curr_id = V4L2_STD_PAL_D; - } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) { - curr_id = V4L2_STD_PAL_D1; - } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) { - curr_id = V4L2_STD_PAL_K; - } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) { - curr_id = V4L2_STD_PAL_M; - } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) { - curr_id = V4L2_STD_PAL_N; - } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) { - curr_id = V4L2_STD_PAL_Nc; - } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) { - curr_id = V4L2_STD_PAL_60; - } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) { - curr_id = V4L2_STD_NTSC; - } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) { - curr_id = V4L2_STD_NTSC_M; - } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) { - curr_id = V4L2_STD_NTSC_M_JP; - } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) { - curr_id = V4L2_STD_NTSC_443; - } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) { - curr_id = V4L2_STD_NTSC_M_KR; - } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) { - curr_id = V4L2_STD_SECAM; - } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) { - curr_id = V4L2_STD_SECAM_DK; - } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) { - curr_id = V4L2_STD_SECAM_B; - } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) { - curr_id = V4L2_STD_SECAM_D; - } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) { - curr_id = V4L2_STD_SECAM_G; - } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) { - curr_id = V4L2_STD_SECAM_H; - } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) { - curr_id = V4L2_STD_SECAM_K; - } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) { - curr_id = V4L2_STD_SECAM_K1; - } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) { - curr_id = V4L2_STD_SECAM_L; - } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) { - curr_id = V4L2_STD_SECAM_LC; - } else { + v4l2_std_id id = vfd->tvnorms, curr_id = 0; + unsigned int index = p->index, i, j = 0; + const char *descr = ""; + + /* Return norm array in a canonical way */ + for (i = 0; i <= index && id; i++) { + /* last std value in the standards array is 0, so this + while always ends there since (id & 0) == 0. */ + while ((id & standards[j].std) != standards[j].std) + j++; + curr_id = standards[j].std; + descr = standards[j].descr; + j++; + if (curr_id == 0) break; - } - id &= ~curr_id; + if (curr_id != V4L2_STD_PAL && + curr_id != V4L2_STD_SECAM && + curr_id != V4L2_STD_NTSC) + id &= ~curr_id; } - if (i<=index) + if (i <= index) return -EINVAL; - v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id)); + v4l2_video_std_construct(p, curr_id, descr); p->index = index; - dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " + dbgarg(cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " "framelines=%d\n", p->index, (unsigned long long)p->id, p->name, p->frameperiod.numerator, p->frameperiod.denominator, p->framelines); - ret=0; + ret = 0; break; } case VIDIOC_G_STD: @@ -1853,12 +1752,20 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); break; } + default: + { + if (!vfd->vidioc_default) + break; + ret = vfd->vidioc_default(file, fh, cmd, arg); + break; + } } /* switch */ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { if (ret<0) { - printk ("%s: err:\n", vfd->name); + printk("%s: err: on ", vfd->name); v4l_print_ioctl(vfd->name, cmd); + printk("\n"); } } @@ -2019,7 +1926,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) break; default: printk(KERN_ERR "%s called with unknown type: %d\n", - __FUNCTION__, type); + __func__, type); return -1; } @@ -2057,7 +1964,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) ret = device_register(&vfd->class_dev); if (ret < 0) { printk(KERN_ERR "%s: device_register failed\n", - __FUNCTION__); + __func__); goto fail_minor; } |