/*
*
* Video for Linux Two
* Backward Compatibility Layer
*
* Support subroutines for providing V4L2 drivers with backward
* compatibility with applications using the old API.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Author: Bill Dirks <bdirks@pacbell.net>
* et al.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
static unsigned int debug = 0;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,"enable debug messages");
MODULE_AUTHOR("Bill Dirks");
MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
MODULE_LICENSE("GPL");
#define dprintk(fmt, arg...) if (debug) \
printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg)
/*
* I O C T L T R A N S L A T I O N
*
* From here on down is the code for translating the numerous
* ioctl commands from the old API to the new API.
*/
static int
get_v4l_control(struct inode *inode,
struct file *file,
int cid,
v4l2_kioctl drv)
{
struct v4l2_queryctrl qctrl2;
struct v4l2_control ctrl2;
int err;
qctrl2.id = cid;
err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
if (err < 0)
dprintk("VIDIOC_QUERYCTRL: %d\n",err);
if (err == 0 &&
!(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
{
ctrl2.id = qctrl2.id;
err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2);
if (err < 0) {
dprintk("VIDIOC_G_CTRL: %d\n",err);
return 0;
}
return ((ctrl2.value - qctrl2.minimum) * 65535
+ (qctrl2.maximum - qctrl2.minimum) / 2)
/ (qctrl2.maximum - qctrl2.minimum);
}
return 0;
}
static int
set_v4l_control(struct inode *inode,
struct file *file,
int cid,
int value,
v4l2_kioctl drv)
{
struct v4l2_queryctrl qctrl2;
struct v4l2_control ctrl2;
int err;
qctrl2.id = cid;
err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
if (err < 0)
dprintk("VIDIOC_QUERYCTRL: %d\n",err);
if (err == 0 &&
!(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
!(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED))
{
if (value < 0)
value = 0;
if (value > 65535)
value = 65535;
if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
value = 65535;
ctrl2.id = qctrl2.id;
ctrl2.value =
(value * (qctrl2.maximum - qctrl2.minimum)
+ 32767)
/ 65535;
ctrl2.value += qctrl2.minimum;
err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2);
if (err < 0)
dprintk("VIDIOC_S_CTRL: %d\n",err);
}
return 0;
}
/* ----------------------------------------------------------------- */
static int palette2pixelformat[] = {
[VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY,
[VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555,
[VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565,
[VIDEO_PALETTE_RGB24] = V4L2_PIX_FMT_BGR24,
[VIDEO_PALETTE_RGB32] = V4L2_PIX_FMT_BGR32,
/* yuv packed pixel */
[VIDEO_PALETTE_YUYV] = V4L2_PIX_FMT_YUYV,
[VIDEO_PALETTE_YUV422] = V4L2_PIX_FMT_YUYV,
[VIDEO_PALETTE_UYVY] = V4L2_PIX_FMT_UYVY,
/* yuv planar */
[VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,
[VIDEO_PALETTE_YUV420] = V4L2_PIX_FMT_YUV420,
[VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,
[VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,