aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry MERLE <thierry.merle@free.fr>2007-05-08 17:22:29 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-07-18 14:23:20 -0300
commitc5f48367fe54c46805774eeea8e828de54a5ad7b (patch)
tree5a78194b89745dc55054e6f656cacec20ca1a79b
parentea1f83cee96badc28d3f67ef29ac29c9d0eb0a1b (diff)
V4L/DVB (5644): Usbvision: video_ioctl2 conversion
The ioctl entry point, a big switch/case, is splitted in little functions. These functions are set as callbacks for the video_ioctl2 video4linux facility. This improves the driver memory consumption and enables the v4l1 compatibility as a side effect. Signed-off-by: Thierry MERLE <thierry.merle@free.fr> Acked-by: Dwaine P. Garden <dwainegarden@rogers.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c8
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c1453
-rw-r--r--drivers/media/video/usbvision/usbvision.h12
3 files changed, 787 insertions, 686 deletions
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 02ccd96d5e5..0127be9c254 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -1831,10 +1831,10 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
frameRate = FRAMERATE_MAX;
}
- if (usbvision->tvnorm->id & V4L2_STD_625_50) {
+ if (usbvision->tvnormId & V4L2_STD_625_50) {
frameDrop = frameRate * 32 / 25 - 1;
}
- else if (usbvision->tvnorm->id & V4L2_STD_525_60) {
+ else if (usbvision->tvnormId & V4L2_STD_525_60) {
frameDrop = frameRate * 32 / 30 - 1;
}
@@ -2067,7 +2067,7 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
}
- if (usbvision->tvnorm->id & V4L2_STD_PAL) {
+ if (usbvision->tvnormId & V4L2_STD_PAL) {
value[0] = 0xC0;
value[1] = 0x02; //0x02C0 -> 704 Input video line length
value[2] = 0x20;
@@ -2076,7 +2076,7 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
value[5] = 0x00; //0x0060 -> 96 Input video h offset
value[6] = 0x16;
value[7] = 0x00; //0x0016 -> 22 Input video v offset
- } else if (usbvision->tvnorm->id & V4L2_STD_SECAM) {
+ } else if (usbvision->tvnormId & V4L2_STD_SECAM) {
value[0] = 0xC0;
value[1] = 0x02; //0x02C0 -> 704 Input video line length
value[2] = 0x20;
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index dab8bc968df..6b185a9a37e 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -36,7 +36,8 @@
* - use submit_urb for all setup packets
* - Fix memory settings for nt1004. It is 4 times as big as the
* nt1003 memory.
- * - Add audio on endpoint 3 for nt1004 chip. Seems impossible, needs a codec interface. Which one?
+ * - Add audio on endpoint 3 for nt1004 chip.
+ * Seems impossible, needs a codec interface. Which one?
* - Clean up the driver.
* - optimization for performance.
* - Add Videotext capability (VBI). Working on it.....
@@ -77,7 +78,8 @@
#include "usbvision.h"
#include "usbvision-cards.h"
-#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, Dwaine Garden <DwaineGarden@rogers.com>"
+#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>,\
+ Dwaine Garden <DwaineGarden@rogers.com>"
#define DRIVER_NAME "usbvision"
#define DRIVER_ALIAS "USBVision"
#define DRIVER_DESC "USBVision USB Video Device Driver for Linux"
@@ -85,20 +87,25 @@
#define USBVISION_DRIVER_VERSION_MAJOR 0
#define USBVISION_DRIVER_VERSION_MINOR 9
#define USBVISION_DRIVER_VERSION_PATCHLEVEL 9
-#define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,USBVISION_DRIVER_VERSION_MINOR,USBVISION_DRIVER_VERSION_PATCHLEVEL)
-#define USBVISION_VERSION_STRING __stringify(USBVISION_DRIVER_VERSION_MAJOR) "." __stringify(USBVISION_DRIVER_VERSION_MINOR) "." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL)
+#define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,\
+USBVISION_DRIVER_VERSION_MINOR,\
+USBVISION_DRIVER_VERSION_PATCHLEVEL)
+#define USBVISION_VERSION_STRING __stringify(USBVISION_DRIVER_VERSION_MAJOR)\
+ "." __stringify(USBVISION_DRIVER_VERSION_MINOR)\
+ "." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL)
#define ENABLE_HEXDUMP 0 /* Enable if you need it */
#ifdef USBVISION_DEBUG
#define PDEBUG(level, fmt, args...) \
- if (video_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args)
+ if (video_debug & (level)) \
+ info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ ,\
+ ## args)
#else
#define PDEBUG(level, fmt, args...) do {} while(0)
#endif
-#define DBG_IOCTL 1<<0
#define DBG_IO 1<<1
#define DBG_PROBE 1<<2
#define DBG_MMAP 1<<3
@@ -108,7 +115,8 @@
#define goto2next(str) while(*str!=' ') str++; while(*str==' ') str++;
-static int usbvision_nr = 0; // sequential number of usbvision device
+/* sequential number of usbvision device */
+static int usbvision_nr = 0;
static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = {
{ 1, 1, 8, V4L2_PIX_FMT_GREY , "GREY" },
@@ -121,54 +129,54 @@ static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = {
{ 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" }
};
-/* supported tv norms */
-static struct usbvision_tvnorm tvnorms[] = {
- {
- .name = "PAL",
- .id = V4L2_STD_PAL,
- }, {
- .name = "NTSC",
- .id = V4L2_STD_NTSC,
- }, {
- .name = "SECAM",
- .id = V4L2_STD_SECAM,
- }, {
- .name = "PAL-M",
- .id = V4L2_STD_PAL_M,
- }
-};
-
-#define TVNORMS ARRAY_SIZE(tvnorms)
-
-// Function prototypes
+/* Function prototypes */
static void usbvision_release(struct usb_usbvision *usbvision);
-// Default initalization of device driver parameters
-static int isocMode = ISOC_MODE_COMPRESS; // Set the default format for ISOC endpoint
-static int video_debug = 0; // Set the default Debug Mode of the device driver
-static int PowerOnAtOpen = 1; // Set the default device to power on at startup
-static int video_nr = -1; // Sequential Number of Video Device
-static int radio_nr = -1; // Sequential Number of Radio Device
-static int vbi_nr = -1; // Sequential Number of VBI Device
-
-// Grab parameters for the device driver
-
-#if defined(module_param) // Showing parameters under SYSFS
+/* Default initalization of device driver parameters */
+/* Set the default format for ISOC endpoint */
+static int isocMode = ISOC_MODE_COMPRESS;
+/* Set the default Debug Mode of the device driver */
+static int video_debug = 0;
+/* Set the default device to power on at startup */
+static int PowerOnAtOpen = 1;
+/* Sequential Number of Video Device */
+static int video_nr = -1;
+/* Sequential Number of Radio Device */
+static int radio_nr = -1;
+/* Sequential Number of VBI Device */
+static int vbi_nr = -1;
+
+/* Grab parameters for the device driver */
+
+/* Showing parameters under SYSFS */
+#if defined(module_param)
module_param(isocMode, int, 0444);
module_param(video_debug, int, 0444);
module_param(PowerOnAtOpen, int, 0444);
module_param(video_nr, int, 0444);
module_param(radio_nr, int, 0444);
module_param(vbi_nr, int, 0444);
-#else // Old Style
+#else
+/* Old Style */
MODULE_PARAM(isocMode, "i");
-MODULE_PARM(video_debug, "i"); // Grab the Debug Mode of the device driver
-MODULE_PARM(adjustCompression, "i"); // Grab the compression to be adaptive
-MODULE_PARM(PowerOnAtOpen, "i"); // Grab the device to power on at startup
-MODULE_PARM(SwitchSVideoInput, "i"); // To help people with Black and White output with using s-video input. Some cables and input device are wired differently.
-MODULE_PARM(video_nr, "i"); // video_nr option allows to specify a certain /dev/videoX device (like /dev/video0 or /dev/video1 ...)
-MODULE_PARM(radio_nr, "i"); // radio_nr option allows to specify a certain /dev/radioX device (like /dev/radio0 or /dev/radio1 ...)
-MODULE_PARM(vbi_nr, "i"); // vbi_nr option allows to specify a certain /dev/vbiX device (like /dev/vbi0 or /dev/vbi1 ...)
+/* Grab the Debug Mode of the device driver */
+MODULE_PARM(video_debug, "i");
+/* Grab the compression to be adaptive */
+MODULE_PARM(adjustCompression, "i");
+/* Grab the device to power on at startup */
+MODULE_PARM(PowerOnAtOpen, "i");
+/* To help people with Black and White output with using s-video input.
+ Some cables and input device are wired differently. */
+MODULE_PARM(SwitchSVideoInput, "i");
+/* video_nr option allows to specify a certain /dev/videoX device
+ (like /dev/video0 or /dev/video1 ...) */
+MODULE_PARM(video_nr, "i");
+/* radio_nr option allows to specify a certain /dev/radioX device
+ (like /dev/radio0 or /dev/radio1 ...) */
+MODULE_PARM(radio_nr, "i");
+/* vbi_nr option allows to specify a certain /dev/vbiX device
+ (like /dev/vbi0 or /dev/vbi1 ...) */
+MODULE_PARM(vbi_nr, "i");
#endif
MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
@@ -187,19 +195,21 @@ MODULE_VERSION(USBVISION_VERSION_STRING);
MODULE_ALIAS(DRIVER_ALIAS);
-/****************************************************************************************/
-/* SYSFS Code - Copied from the stv680.c usb module. */
-/* Device information is located at /sys/class/video4linux/video0 */
-/* Device parameters information is located at /sys/module/usbvision */
-/* Device USB Information is located at /sys/bus/usb/drivers/USBVision Video Grabber */
-/****************************************************************************************/
+/*****************************************************************************/
+/* SYSFS Code - Copied from the stv680.c usb module. */
+/* Device information is located at /sys/class/video4linux/video0 */
+/* Device parameters information is located at /sys/module/usbvision */
+/* Device USB Information is located at */
+/* /sys/bus/usb/drivers/USBVision Video Grabber */
+/*****************************************************************************/
#define YES_NO(x) ((x) ? "Yes" : "No")
static inline struct usb_usbvision *cd_to_usbvision(struct class_device *cd)
{
- struct video_device *vdev = container_of(cd, struct video_device, class_dev);
+ struct video_device *vdev =
+ container_of(cd, struct video_device, class_dev);
return video_get_drvdata(vdev);
}
@@ -211,15 +221,18 @@ static CLASS_DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
static ssize_t show_model(struct class_device *cd, char *buf)
{
- struct video_device *vdev = container_of(cd, struct video_device, class_dev);
+ struct video_device *vdev =
+ container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- return sprintf(buf, "%s\n", usbvision_device_data[usbvision->DevModel].ModelString);
+ return sprintf(buf, "%s\n",
+ usbvision_device_data[usbvision->DevModel].ModelString);
}
static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
static ssize_t show_hue(struct class_device *cd, char *buf)
{
- struct video_device *vdev = container_of(cd, struct video_device, class_dev);
+ struct video_device *vdev =
+ container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_HUE;
@@ -232,7 +245,8 @@ static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
static ssize_t show_contrast(struct class_device *cd, char *buf)
{
- struct video_device *vdev = container_of(cd, struct video_device, class_dev);
+ struct video_device *vdev =
+ container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_CONTRAST;
@@ -245,7 +259,8 @@ static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
static ssize_t show_brightness(struct class_device *cd, char *buf)
{
- struct video_device *vdev = container_of(cd, struct video_device, class_dev);
+ struct video_device *vdev =
+ container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_BRIGHTNESS;
@@ -258,7 +273,8 @@ static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
static ssize_t show_saturation(struct class_device *cd, char *buf)
{
- struct video_device *vdev = container_of(cd, struct video_device, class_dev);
+ struct video_device *vdev =
+ container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_SATURATION;
@@ -271,23 +287,28 @@ static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
static ssize_t show_streaming(struct class_device *cd, char *buf)
{
- struct video_device *vdev = container_of(cd, struct video_device, class_dev);
+ struct video_device *vdev =
+ container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- return sprintf(buf, "%s\n", YES_NO(usbvision->streaming==Stream_On?1:0));
+ return sprintf(buf, "%s\n",
+ YES_NO(usbvision->streaming==Stream_On?1:0));
}
static CLASS_DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);
static ssize_t show_compression(struct class_device *cd, char *buf)
{
- struct video_device *vdev = container_of(cd, struct video_device, class_dev);
+ struct video_device *vdev =
+ container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- return sprintf(buf, "%s\n", YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));
+ return sprintf(buf, "%s\n",
+ YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));
}
static CLASS_DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);
static ssize_t show_device_bridge(struct class_device *cd, char *buf)
{
- struct video_device *vdev = container_of(cd, struct video_device, class_dev);
+ struct video_device *vdev =
+ container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%d\n", usbvision->bridgeType);
}
@@ -376,7 +397,8 @@ static void usbvision_remove_sysfs(struct video_device *vdev)
static int usbvision_v4l2_open(struct inode *inode, struct file *file)
{
struct video_device *dev = video_devdata(file);
- struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
int errCode = 0;
PDEBUG(DBG_IO, "open");
@@ -390,7 +412,8 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
/* Allocate memory for the scratch ring buffer */
errCode = usbvision_scratch_alloc(usbvision);
if (isocMode==ISOC_MODE_COMPRESS) {
- /* Allocate intermediate decompression buffers only if needed */
+ /* Allocate intermediate decompression buffers
+ only if needed */
errCode = usbvision_decompress_alloc(usbvision);
}
if (errCode) {
@@ -421,11 +444,10 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
if (!errCode) {
usbvision_begin_streaming(usbvision);
errCode = usbvision_init_isoc(usbvision);
- /* device needs to be initialized before isoc transfer */
+ /* device must be initialized before isoc transfer */
usbvision_muxsel(usbvision,0);
usbvision->user++;
- }
- else {
+ } else {
if (PowerOnAtOpen) {
usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
@@ -456,7 +478,8 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
static int usbvision_v4l2_close(struct inode *inode, struct file *file)
{
struct video_device *dev = video_devdata(file);
- struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
PDEBUG(DBG_IO, "close");
down(&usbvision->lock);
@@ -473,7 +496,8 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file)
usbvision->user--;
if (PowerOnAtOpen) {
- /* power off in a little while to avoid off/on every close/open short sequences */
+ /* power off in a little while
+ to avoid off/on every close/open short sequences */
usbvision_set_powerOffTimer(usbvision);
usbvision->initialized = 0;
}
@@ -498,600 +522,611 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file)
* This is part of Video 4 Linux API. The procedure handles ioctl() calls.
*
*/
-static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register (struct file *file, void *priv,
+ struct v4l2_register *reg)
{
struct video_device *dev = video_devdata(file);
- struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev);
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return -EFAULT;
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
+ int errCode;
- switch (cmd) {
+ if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
+ return -EINVAL;
+ /* NT100x has a 8-bit register space */
+ errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
+ if (errCode < 0) {
+ err("%s: VIDIOC_DBG_G_REGISTER failed: error %d",
+ __FUNCTION__, errCode);
+ return errCode;
+ }
+ return 0;
+}
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- /* ioctls to allow direct acces to the NT100x registers */
- case VIDIOC_DBG_G_REGISTER:
- case VIDIOC_DBG_S_REGISTER:
- {
- struct v4l2_register *reg = arg;
- int errCode;
-
- if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- /* NT100x has a 8-bit register space */
- if (cmd == VIDIOC_DBG_G_REGISTER)
- errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
- else
- errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
- if (errCode < 0) {
- err("%s: VIDIOC_DBG_%c_REGISTER failed: error %d", __FUNCTION__,
- cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S', errCode);
- return errCode;
- }
- if (cmd == VIDIOC_DBG_S_REGISTER)
- reg->val = (u8)errCode;
+static int vidioc_s_register (struct file *file, void *priv,
+ struct v4l2_register *reg)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
+ int errCode;
- PDEBUG(DBG_IOCTL, "VIDIOC_DBG_%c_REGISTER reg=0x%02X, value=0x%02X",
- cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S',
- (unsigned int)reg->reg, (unsigned int)reg->val);
- return 0;
- }
+ if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
+ return -EINVAL;
+ /* NT100x has a 8-bit register space */
+ reg->val = (u8)usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
+ if (reg->val < 0) {
+ err("%s: VIDIOC_DBG_S_REGISTER failed: error %d",
+ __FUNCTION__, errCode);
+ return errCode;
+ }
+ return 0;
+}
#endif
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *vc=arg;
-
- memset(vc, 0, sizeof(*vc));
- strlcpy(vc->driver, "USBVision", sizeof(vc->driver));
- strlcpy(vc->card, usbvision_device_data[usbvision->DevModel].ModelString,
- sizeof(vc->card));
- strlcpy(vc->bus_info, usbvision->dev->dev.bus_id,
- sizeof(vc->bus_info));
- vc->version = USBVISION_DRIVER_VERSION;
- vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_AUDIO |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- (usbvision->have_tuner ? V4L2_CAP_TUNER : 0);
- PDEBUG(DBG_IOCTL, "VIDIOC_QUERYCAP");
- return 0;
- }
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *vi = arg;
- int chan;
-
- if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) )
- return -EINVAL;
- if (usbvision->have_tuner) {
- chan = vi->index;
- }
- else {
- chan = vi->index + 1; //skip Television string
- }
- switch(chan) {
- case 0:
- if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) {
- strcpy(vi->name, "White Video Input");
- }
- else {
- strcpy(vi->name, "Television");
- vi->type = V4L2_INPUT_TYPE_TUNER;
- vi->audioset = 1;
- vi->tuner = chan;
- vi->std = V4L2_STD_PAL | V4L2_STD_NTSC | V4L2_STD_SECAM;
- }
- break;
- case 1:
- vi->type = V4L2_INPUT_TYPE_CAMERA;
- if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) {
- strcpy(vi->name, "Green Video Input");
- }
- else {
- strcpy(vi->name, "Composite Video Input");
- }
- vi->std = V4L2_STD_PAL;
- break;
- case 2:
- vi->type = V4L2_INPUT_TYPE_CAMERA;
- if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) {
- strcpy(vi->name, "Yellow Video Input");
- }
- else {
- strcpy(vi->name, "S-Video Input");
- }
- vi->std = V4L2_STD_PAL;
- break;
- case 3:
- vi->type = V4L2_INPUT_TYPE_CAMERA;
- strcpy(vi->name, "Red Video Input");
- vi->std = V4L2_STD_PAL;
- break;
- }
- PDEBUG(DBG_IOCTL, "VIDIOC_ENUMINPUT name=%s:%d tuners=%d type=%d norm=%x",
- vi->name, vi->index, vi->tuner,vi->type,(int)vi->std);
- return 0;
- }
- case VIDIOC_ENUMSTD:
- {
- struct v4l2_standard *e = arg;
- unsigned int i;
- int ret;
-
- i = e->index;
- if (i >= TVNORMS)
- return -EINVAL;
- ret = v4l2_video_std_construct(e, tvnorms[e->index].id,
- tvnorms[e->index].name);
- e->index = i;
- if (ret < 0)
- return ret;
- return 0;
+
+static int vidioc_querycap (struct file *file, void *priv,
+ struct v4l2_capability *vc)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
+
+ strlcpy(vc->driver, "USBVision", sizeof(vc->driver));
+ strlcpy(vc->card,
+ usbvision_device_data[usbvision->DevModel].ModelString,
+ sizeof(vc->card));
+ strlcpy(vc->bus_info, usbvision->dev->dev.bus_id,
+ sizeof(vc->bus_info));
+ vc->version = USBVISION_DRIVER_VERSION;
+ vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_AUDIO |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING |
+ (usbvision->have_tuner ? V4L2_CAP_TUNER : 0);
+ return 0;
+}
+
+static int vidioc_enum_input (struct file *file, void *priv,
+ struct v4l2_input *vi)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
+ int chan;
+
+ if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) )
+ return -EINVAL;
+ if (usbvision->have_tuner) {
+ chan = vi->index;
+ } else {
+ chan = vi->index + 1; /*skip Television string*/
+ }
+ /* Determine the requested input characteristics
+ specific for each usbvision card model */
+ switch(chan) {
+ case 0:
+ if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) {
+ strcpy(vi->name, "White Video Input");
+ } else {
+ strcpy(vi->name, "Television");
+ vi->type = V4L2_INPUT_TYPE_TUNER;
+ vi->audioset = 1;
+ vi->tuner = chan;
+ vi->std = USBVISION_NORMS;
}
- case VIDIOC_G_INPUT:
- {
- int *input = arg;
- *input = usbvision->ctl_input;
- return 0;
+ break;
+ case 1:
+ vi->type = V4L2_INPUT_TYPE_CAMERA;
+ if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) {
+ strcpy(vi->name, "Green Video Input");
+ } else {
+ strcpy(vi->name, "Composite Video Input");
}
- case VIDIOC_S_INPUT:
- {
- int *input = arg;
- if ((*input >= usbvision->video_inputs) || (*input < 0) )
- return -EINVAL;
- usbvision->ctl_input = *input;
-
- down(&usbvision->lock);
- usbvision_muxsel(usbvision, usbvision->ctl_input);
- usbvision_set_input(usbvision);
- usbvision_set_output(usbvision, usbvision->curwidth, usbvision->curheight);
- up(&usbvision->lock);
- return 0;
+ vi->std = V4L2_STD_PAL;
+ break;
+ case 2:
+ vi->type = V4L2_INPUT_TYPE_CAMERA;
+ if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) {
+ strcpy(vi->name, "Yellow Video Input");
+ } else {
+ strcpy(vi->name, "S-Video Input");
}
- case VIDIOC_G_STD:
- {
- v4l2_std_id *id = arg;
+ vi->std = V4L2_STD_PAL;
+ break;
+ case 3:
+ vi->type = V4L2_INPUT_TYPE_CAMERA;
+ strcpy(vi->name, "Red Video Input");
+ vi->std = V4L2_STD_PAL;
+ break;
+ }
+ return 0;
+}
- *id = usbvision->tvnorm->id;
+static int vidioc_g_input (struct file *file, void *priv, unsigned int *input)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
- PDEBUG(DBG_IOCTL, "VIDIOC_G_STD std_id=%s", usbvision->tvnorm->name);
- return 0;
- }
- case VIDIOC_S_STD:
- {
- v4l2_std_id *id = arg;
- unsigned int i;
-
- for (i = 0; i < TVNORMS; i++)
- if (*id == tvnorms[i].id)
- break;
- if (i == TVNORMS)
- for (i = 0; i < TVNORMS; i++)
- if (*id & tvnorms[i].id)
- break;
- if (i == TVNORMS)
- return -EINVAL;
-
- down(&usbvision->lock);
- usbvision->tvnorm = &tvnorms[i];
-
- call_i2c_clients(usbvision, VIDIOC_S_STD,
- &usbvision->tvnorm->id);
+ *input = usbvision->ctl_input;
+ return 0;
+}
- up(&usbvision->lock);
+static int vidioc_s_input (struct file *file, void *priv, unsigned int input)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
- PDEBUG(DBG_IOCTL, "VIDIOC_S_STD std_id=%s", usbvision->tvnorm->name);
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *vt = arg;
-
- if (!usbvision->have_tuner || vt->index) // Only tuner 0
- return -EINVAL;
- if(usbvision->radio) {
- strcpy(vt->name, "Radio");
- vt->type = V4L2_TUNER_RADIO;
- }
- else {
- strcpy(vt->name, "Television");
- }
- /* Let clients fill in the remainder of this struct */
- call_i2c_clients(usbvision,VIDIOC_G_TUNER,vt);
+ if ((input >= usbvision->video_inputs) || (input < 0) )
+ return -EINVAL;
+ usbvision->ctl_input = input;
- PDEBUG(DBG_IOCTL, "VIDIOC_G_TUNER for %s signal=%x, afc=%x",
- vt->name, vt->signal,vt->afc);
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *vt = arg;
-
- // Only no or one tuner for now
- if (!usbvision->have_tuner || vt->index)
- return -EINVAL;
- /* let clients handle this */
- call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt);
-
- PDEBUG(DBG_IOCTL, "VIDIOC_S_TUNER");
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *freq = arg;
+ down(&usbvision->lock);
+ usbvision_muxsel(usbvision, usbvision->ctl_input);
+ usbvision_set_input(usbvision);
+ usbvision_set_output(usbvision,
+ usbvision->curwidth,
+ usbvision->curheight);
+ up(&usbvision->lock);
+ return 0;
+}
- freq->tuner = 0; // Only one tuner
- if(usbvision->radio) {
- freq->type = V4L2_TUNER_RADIO;
- }
- else {
- freq->type = V4L2_TUNER_ANALOG_TV;
- }
- freq->frequency = usbvision->freq;
- PDEBUG(DBG_IOCTL, "VIDIOC_G_FREQUENCY freq=0x%X", (unsigned)freq->frequency);
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *freq = arg;
-
- // Only no or one tuner for now
- if (!usbvision->have_tuner || freq->tuner)
- return -EINVAL;
-
- usbvision->freq = freq->frequency;
- call_i2c_clients(usbvision, cmd, freq);
- PDEBUG(DBG_IOCTL, "VIDIOC_S_FREQUENCY freq=0x%X", (unsigned)freq->frequency);
- return 0;
- }
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *v = arg;
- memset(v,0, sizeof(v));
- if(usbvision->radio) {
- strcpy(v->name,"Radio");
- }
- else {
- strcpy(v->name, "TV");
- }
- PDEBUG(DBG_IOCTL, "VIDIOC_G_AUDIO");
- return 0;
- }
- case VIDIOC_S_AUDIO:
- {
- struct v4l2_audio *v = arg;
- if(v->index) {
- return -EINVAL;
- }
- PDEBUG(DBG_IOCTL, "VIDIOC_S_AUDIO");
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *ctrl = arg;
- int id=ctrl->id;
+static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
+ usbvision->tvnormId=*id;
- memset(ctrl,0,sizeof(*ctrl));
- ctrl->id=id;
+ down(&usbvision->lock);
+ call_i2c_clients(usbvision, VIDIOC_S_STD,
+ &usbvision->tvnormId);
+ up(&usbvision->lock);
- call_i2c_clients(usbvision, cmd, arg);
+ return 0;
+}
- if (ctrl->type)
- return 0;
- else
- return -EINVAL;
+static int vidioc_g_tuner (struct file *file, void *priv,
+ struct v4l2_tuner *vt)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
- PDEBUG(DBG_IOCTL,"VIDIOC_QUERYCTRL id=%x value=%x",ctrl->id,ctrl->type);
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl = arg;
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
- PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value);
- return 0;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl = arg;
+ if (!usbvision->have_tuner || vt->index) // Only tuner 0
+ return -EINVAL;
+ if(usbvision->radio) {
+ strcpy(vt->name, "Radio");
+ vt->type = V4L2_TUNER_RADIO;
+ } else {
+ strcpy(vt->name, "Television");
+ }
+ /* Let clients fill in the remainder of this struct */
+ call_i2c_clients(usbvision,VIDIOC_G_TUNER,vt);
- PDEBUG(DBG_IOCTL, "VIDIOC_S_CTRL id=%x value=%x",ctrl->id,ctrl->value);
- call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl);
- return 0;
- }
- case VIDIOC_REQBUFS:
- {
- struct v4l2_requestbuffers *vr = arg;
- int ret;
+ return 0;
+}
- RESTRICT_TO_RANGE(vr->count,1,USBVISION_NUMFRAMES);
+static int vidioc_s_tuner (struct file *file, void *priv,
+ struct v4l2_tuner *vt)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
- // Check input validity : the user must do a VIDEO CAPTURE and MMAP method.
- if((vr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
- (vr->memory != V4L2_MEMORY_MMAP))
- return -EINVAL;
+ // Only no or one tuner for now
+ if (!usbvision->have_tuner || vt->index)
+ return -EINVAL;
+ /* let clients handle this */
+ call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt);
- if(usbvision->streaming == Stream_On) {
- if ((ret = usbvision_stream_interrupt(usbvision)))
- return ret;
- }
+ return 0;
+}
- usbvision_frames_free(usbvision);
- usbvision_empty_framequeues(usbvision);
- vr->count = usbvision_frames_alloc(usbvision,vr->count);
+static int vidioc_g_frequency (struct file *file, void *priv,
+ struct v4l2_frequency *freq)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
- usbvision->curFrame = NULL;
+ freq->tuner = 0; // Only one tuner
+ if(usbvision->radio) {
+ freq->type = V4L2_TUNER_RADIO;
+ } else {
+ freq->type = V4L2_TUNER_ANALOG_TV;
+ }
+ freq->frequency = usbvision->freq;
- PDEBUG(DBG_IOCTL, "VIDIOC_REQBUFS count=%d",vr->count);
- return 0;
- }
- case VIDIOC_QUERYBUF:
- {
- struct v4l2_buffer *vb = arg;
- struct usbvision_frame *frame;
+ return 0;
+}
- // FIXME : must control that buffers are mapped (VIDIOC_REQBUFS has been called)
+static int vidioc_s_frequency (struct file *file, void *priv,
+ struct v4l2_frequency *freq)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
- if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
- return -EINVAL;
- }
- if(vb->index>=usbvision->num_frames) {
- return -EINVAL;
- }
- // Updating the corresponding frame state
- vb->flags = 0;
- frame = &usbvision->frame[vb->index];
- if(frame->grabstate >= FrameState_Ready)
- vb->flags |= V4L2_BUF_FLAG_QUEUED;
- if(frame->grabstate >= FrameState_Done)
- vb->flags |= V4L2_BUF_FLAG_DONE;
- if(frame->grabstate == FrameState_Unused)
- vb->flags |= V4L2_BUF_FLAG_MAPPED;
- vb->memory = V4L2_MEMORY_MMAP;
-
- vb->m.offset = vb->index*PAGE_ALIGN(usbvision->max_frame_size);
-
- vb->memory = V4L2_MEMORY_MMAP;
- vb->field = V4L2_FIELD_NONE;
- vb->length = usbvision->curwidth*usbvision->curheight*usbvision->palette.bytes_per_pixel;
- vb->timestamp = usbvision->frame[vb->index].timestamp;
- vb->sequence = usbvision->frame[vb->index].sequence;
- return 0;
- }
- case VIDIOC_QBUF:
- {
- struct v4l2_buffer *vb = arg;
- struct usbvision_frame *frame;
- unsigned long lock_flags;
-
- // FIXME : works only on VIDEO_CAPTURE MODE, MMAP.
- if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
- return -EINVAL;
- }
- if(vb->index>=usbvision->num_frames) {
- return -EINVAL;
- }
+ // Only no or one tuner for now
+ if (!usbvision->have_tuner || freq->tuner)
+ return -EINVAL;
- frame = &usbvision->frame[vb->index];
+ usbvision->freq = freq->frequency;
+ call_i2c_clients(usbvision, VIDIOC_S_FREQUENCY, freq);
- if (frame->grabstate != FrameState_Unused) {
- return -EAGAIN;
- }
+ return 0;
+}
- /* Mark it as ready and enqueue frame */
- frame->grabstate = FrameState_Ready;
- frame->scanstate = ScanState_Scanning;
- frame->scanlength = 0; /* Accumulated in usbvision_parse_data() */
+static int vidioc_g_audio (struct file *file, void *priv, struct v4l2_audio *a)
+{
+ struct video_device *dev = video_devdata(file);
+ struct usb_usbvision *usbvision =
+ (struct usb_usbvision *) video_get_drvdata(dev);
- vb->flags &= ~V4L2_BUF_FLAG_DONE;
+ memset(a,0,sizeof(*a));
+ if(usbvision->radio) {
+ strcpy(a->name,"Radio");
+ } else {
+ strcpy(a->name, "TV");
+ }
- /* set v4l2_format index */
- frame->v4l2_format = usbvision->palette;
+ return 0;
+}
- spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
- list_add_tail(&usbvision->frame[vb->index].frame, &usbvision->inqueue);
- spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
+static int vidioc_s_audio (struct file *file, void *fh,
+ struct v4l2_audio *a)
+{
+ if(a->index) {
+ return -EINVAL;
+ }
- PDEBUG(DBG_IOCTL, "VIDIOC_QBUF frame #%d",vb->index);
- return 0;
- }
- case VIDIOC_DQBUF:
- {
- struct v4l2_buffer *vb = arg;
- int ret;
- struct usbvision_frame *f;
- unsigned long lock_flags;
-
- if (vb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (list_empty(&(usbvision->outqueue))) {
- if (usbvision->streaming == Stream_Idle)
- return -EINVAL;
- ret = wait_event_interruptible
- (usbvision->wait_frame,
- !list_empty(&(usbvision->outqueue)));
- if (ret)
- return ret;
- }
+ return 0;
+}
- spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
- f = list_entry(usbvision->outqueue.next,
- struct usbvision_frame, frame);
- list_del(usbvision->outqueue.next);
- spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
-
- f->grabstate = F