2006-12-04 08:31:45 -03:00
/*
2009-04-01 03:15:52 -03:00
* USB USBVISION Video device driver 0.9 .10
2006-12-04 08:31:45 -03:00
*
*
*
* Copyright ( c ) 1999 - 2005 Joerg Heckenbach < joerg @ heckenbach - aw . de >
*
* This module is part of usbvision driver project .
*
* 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 .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*
* Let ' s call the version 0. . . . until compression decoding is completely
* implemented .
*
* This driver is written by Jose Ignacio Gijon and Joerg Heckenbach .
* It was based on USB CPiA driver written by Peter Pregler ,
* Scott J . Bertin and Johannes Erdfelt
* Ideas are taken from bttv driver by Ralph Metzler , Marcus Metzler &
* Gerd Knorr and zoran 36120 / 36125 driver by Pauline Middelink
* Updates to driver completed by Dwaine P . Garden
*
*
* TODO :
* - use submit_urb for all setup packets
* - Fix memory settings for nt1004 . It is 4 times as big as the
* nt1003 memory .
2007-05-08 17:22:29 -03:00
* - Add audio on endpoint 3 for nt1004 chip .
* Seems impossible , needs a codec interface . Which one ?
2006-12-04 08:31:45 -03:00
* - Clean up the driver .
* - optimization for performance .
* - Add Videotext capability ( VBI ) . Working on it . . . . .
* - Check audio for other devices
*
*/
# include <linux/kernel.h>
# include <linux/list.h>
# include <linux/timer.h>
# include <linux/slab.h>
# include <linux/mm.h>
# include <linux/highmem.h>
# include <linux/vmalloc.h>
# include <linux/module.h>
# include <linux/init.h>
# include <linux/spinlock.h>
2010-12-29 13:53:21 -03:00
# include <linux/io.h>
2006-12-04 08:31:45 -03:00
# include <linux/videodev2.h>
# include <linux/i2c.h>
# include <media/saa7115.h>
# include <media/v4l2-common.h>
2008-07-20 08:12:02 -03:00
# include <media/v4l2-ioctl.h>
2015-07-20 09:59:29 -03:00
# include <media/v4l2-event.h>
2006-12-04 08:31:45 -03:00
# include <media/tuner.h>
2006-12-09 11:41:59 -03:00
# include <linux/workqueue.h>
2006-12-04 08:31:45 -03:00
# include "usbvision.h"
2007-04-14 15:09:59 -03:00
# include "usbvision-cards.h"
2006-12-04 08:31:45 -03:00
2011-04-23 20:38:19 -07:00
# define DRIVER_AUTHOR \
" Joerg Heckenbach <joerg@heckenbach-aw.de>, " \
" Dwaine Garden <DwaineGarden@rogers.com> "
2006-12-04 08:31:45 -03:00
# define DRIVER_NAME "usbvision"
# define DRIVER_ALIAS "USBVision"
# define DRIVER_DESC "USBVision USB Video Device Driver for Linux"
# define DRIVER_LICENSE "GPL"
[media] Stop using linux/version.h on most video drivers
All the modified drivers didn't have any version increment since
Jan, 1 2011. Several of them didn't have any version increment
for a long time, even having new features and important bug fixes
happening.
As we're now filling the QUERYCAP version with the current Kernel
Release, we don't need to maintain a per-driver version control
anymore. So, let's just use the default.
In order to preserve the Kernel module version history, a
KERNEL_VERSION() macro were added to all modified drivers, and
the extraver number were incremented.
I opted to preserve the per-driver version control to a few
pwc, pvrusb2, s2255, s5p-fimc and sh_vou.
A few drivers are still using the legacy way to handle ioctl's.
So, we can't do such change on them, otherwise, they'll break.
Those are: uvc, et61x251 and sn9c102.
The rationale is that the per-driver version control seems to be
actively maintained on those.
Yet, I think that the better for them would be to just use the
default version numbering, instead of doing that by themselves.
While here, removed a few uneeded include linux/version.h
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2011-06-24 14:45:49 -03:00
# define USBVISION_VERSION_STRING "0.9.11"
2006-12-04 08:31:45 -03:00
# define ENABLE_HEXDUMP 0 /* Enable if you need it */
# ifdef USBVISION_DEBUG
2008-04-04 21:00:57 -03:00
# define PDEBUG(level, fmt, args...) { \
2007-05-08 17:22:29 -03:00
if ( video_debug & ( level ) ) \
2008-10-10 05:08:23 -03:00
printk ( KERN_INFO KBUILD_MODNAME " :[%s:%d] " fmt , \
__func__ , __LINE__ , # # args ) ; \
2008-04-04 21:00:57 -03:00
}
2006-12-04 08:31:45 -03:00
# else
2010-12-29 13:53:21 -03:00
# define PDEBUG(level, fmt, args...) do {} while (0)
2006-12-04 08:31:45 -03:00
# endif
2010-12-29 13:53:21 -03:00
# define DBG_IO (1 << 1)
# define DBG_PROBE (1 << 2)
# define DBG_MMAP (1 << 3)
2006-12-04 08:31:45 -03:00
2010-12-19 20:33:51 -03:00
/* String operations */
2010-12-29 13:53:21 -03:00
# define rmspace(str) while (*str == ' ') str++;
# define goto2next(str) while (*str != ' ') str++; while (*str == ' ') str++;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
/* sequential number of usbvision device */
2008-04-22 14:41:48 -03:00
static int usbvision_nr ;
2006-12-04 08:31:45 -03:00
static struct usbvision_v4l2_format_st usbvision_v4l2_format [ ] = {
{ 1 , 1 , 8 , V4L2_PIX_FMT_GREY , " GREY " } ,
{ 1 , 2 , 16 , V4L2_PIX_FMT_RGB565 , " RGB565 " } ,
{ 1 , 3 , 24 , V4L2_PIX_FMT_RGB24 , " RGB24 " } ,
{ 1 , 4 , 32 , V4L2_PIX_FMT_RGB32 , " RGB32 " } ,
{ 1 , 2 , 16 , V4L2_PIX_FMT_RGB555 , " RGB555 " } ,
{ 1 , 2 , 16 , V4L2_PIX_FMT_YUYV , " YUV422 " } ,
2010-12-19 20:33:51 -03:00
{ 1 , 2 , 12 , V4L2_PIX_FMT_YVU420 , " YUV420P " } , /* 1.5 ! */
2006-12-04 08:31:45 -03:00
{ 1 , 2 , 16 , V4L2_PIX_FMT_YUV422P , " YUV422P " }
} ;
2007-05-08 17:22:29 -03:00
/* Function prototypes */
2006-12-04 08:31:45 -03:00
static void usbvision_release ( struct usb_usbvision * usbvision ) ;
2008-02-03 17:18:59 +02:00
/* Default initialization of device driver parameters */
2007-05-08 17:22:29 -03:00
/* Set the default format for ISOC endpoint */
2010-12-19 20:21:36 -03:00
static int isoc_mode = ISOC_MODE_COMPRESS ;
2007-05-08 17:22:29 -03:00
/* Set the default Debug Mode of the device driver */
2008-04-22 14:41:48 -03:00
static int video_debug ;
2007-05-08 17:22:29 -03:00
/* Sequential Number of Video Device */
static int video_nr = - 1 ;
/* Sequential Number of Radio Device */
static int radio_nr = - 1 ;
/* Grab parameters for the device driver */
/* Showing parameters under SYSFS */
2010-12-19 20:21:36 -03:00
module_param ( isoc_mode , int , 0444 ) ;
2006-12-04 08:31:45 -03:00
module_param ( video_debug , int , 0444 ) ;
module_param ( video_nr , int , 0444 ) ;
module_param ( radio_nr , int , 0444 ) ;
2010-12-19 20:21:36 -03:00
MODULE_PARM_DESC ( isoc_mode , " Set the default format for ISOC endpoint. Default: 0x60 (Compression On) " ) ;
2006-12-04 08:31:45 -03:00
MODULE_PARM_DESC ( video_debug , " Set the default Debug Mode of the device driver. Default: 0 (Off) " ) ;
MODULE_PARM_DESC ( video_nr , " Set video device number (/dev/videoX). Default: -1 (autodetect) " ) ;
MODULE_PARM_DESC ( radio_nr , " Set radio device number (/dev/radioX). Default: -1 (autodetect) " ) ;
2010-12-19 20:33:51 -03:00
/* Misc stuff */
2006-12-04 08:31:45 -03:00
MODULE_AUTHOR ( DRIVER_AUTHOR ) ;
MODULE_DESCRIPTION ( DRIVER_DESC ) ;
MODULE_LICENSE ( DRIVER_LICENSE ) ;
2006-12-09 11:41:59 -03:00
MODULE_VERSION ( USBVISION_VERSION_STRING ) ;
MODULE_ALIAS ( DRIVER_ALIAS ) ;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
/*****************************************************************************/
/* 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 */
/*****************************************************************************/
2006-12-04 08:31:45 -03:00
# define YES_NO(x) ((x) ? "Yes" : "No")
2007-10-08 16:26:13 -03:00
static inline struct usb_usbvision * cd_to_usbvision ( struct device * cd )
2006-12-04 08:31:45 -03:00
{
2007-05-08 17:22:29 -03:00
struct video_device * vdev =
2008-07-20 06:35:02 -03:00
container_of ( cd , struct video_device , dev ) ;
2006-12-04 08:31:45 -03:00
return video_get_drvdata ( vdev ) ;
}
2007-10-08 16:26:13 -03:00
static ssize_t show_version ( struct device * cd ,
struct device_attribute * attr , char * buf )
2006-12-04 08:31:45 -03:00
{
return sprintf ( buf , " %s \n " , USBVISION_VERSION_STRING ) ;
}
2007-10-08 16:26:13 -03:00
static DEVICE_ATTR ( version , S_IRUGO , show_version , NULL ) ;
2006-12-04 08:31:45 -03:00
2007-10-08 16:26:13 -03:00
static ssize_t show_model ( struct device * cd ,
struct device_attribute * attr , char * buf )
2006-12-04 08:31:45 -03:00
{
2007-05-08 17:22:29 -03:00
struct video_device * vdev =
2008-07-20 06:35:02 -03:00
container_of ( cd , struct video_device , dev ) ;
2006-12-04 08:31:45 -03:00
struct usb_usbvision * usbvision = video_get_drvdata ( vdev ) ;
2007-05-08 17:22:29 -03:00
return sprintf ( buf , " %s \n " ,
2010-12-19 20:21:36 -03:00
usbvision_device_data [ usbvision - > dev_model ] . model_string ) ;
2006-12-04 08:31:45 -03:00
}
2007-10-08 16:26:13 -03:00
static DEVICE_ATTR ( model , S_IRUGO , show_model , NULL ) ;
2006-12-04 08:31:45 -03:00
2007-10-08 16:26:13 -03:00
static ssize_t show_hue ( struct device * cd ,
struct device_attribute * attr , char * buf )
2006-12-04 08:31:45 -03:00
{
2007-05-08 17:22:29 -03:00
struct video_device * vdev =
2008-07-20 06:35:02 -03:00
container_of ( cd , struct video_device , dev ) ;
2006-12-04 08:31:45 -03:00
struct usb_usbvision * usbvision = video_get_drvdata ( vdev ) ;
struct v4l2_control ctrl ;
ctrl . id = V4L2_CID_HUE ;
ctrl . value = 0 ;
2010-12-29 13:53:21 -03:00
if ( usbvision - > user )
2009-02-21 18:11:31 -03:00
call_all ( usbvision , core , g_ctrl , & ctrl ) ;
2007-02-07 10:14:38 -03:00
return sprintf ( buf , " %d \n " , ctrl . value ) ;
2006-12-04 08:31:45 -03:00
}
2007-10-08 16:26:13 -03:00
static DEVICE_ATTR ( hue , S_IRUGO , show_hue , NULL ) ;
2006-12-04 08:31:45 -03:00
2007-10-08 16:26:13 -03:00
static ssize_t show_contrast ( struct device * cd ,
struct device_attribute * attr , char * buf )
2006-12-04 08:31:45 -03:00
{
2007-05-08 17:22:29 -03:00
struct video_device * vdev =
2008-07-20 06:35:02 -03:00
container_of ( cd , struct video_device , dev ) ;
2006-12-04 08:31:45 -03:00
struct usb_usbvision * usbvision = video_get_drvdata ( vdev ) ;
struct v4l2_control ctrl ;
ctrl . id = V4L2_CID_CONTRAST ;
ctrl . value = 0 ;
2010-12-29 13:53:21 -03:00
if ( usbvision - > user )
2009-02-21 18:11:31 -03:00
call_all ( usbvision , core , g_ctrl , & ctrl ) ;
2007-02-07 10:14:38 -03:00
return sprintf ( buf , " %d \n " , ctrl . value ) ;
2006-12-04 08:31:45 -03:00
}
2007-10-08 16:26:13 -03:00
static DEVICE_ATTR ( contrast , S_IRUGO , show_contrast , NULL ) ;
2006-12-04 08:31:45 -03:00
2007-10-08 16:26:13 -03:00
static ssize_t show_brightness ( struct device * cd ,
struct device_attribute * attr , char * buf )
2006-12-04 08:31:45 -03:00
{
2007-05-08 17:22:29 -03:00
struct video_device * vdev =
2008-07-20 06:35:02 -03:00
container_of ( cd , struct video_device , dev ) ;
2006-12-04 08:31:45 -03:00
struct usb_usbvision * usbvision = video_get_drvdata ( vdev ) ;
struct v4l2_control ctrl ;
ctrl . id = V4L2_CID_BRIGHTNESS ;
ctrl . value = 0 ;
2010-12-29 13:53:21 -03:00
if ( usbvision - > user )
2009-02-21 18:11:31 -03:00
call_all ( usbvision , core , g_ctrl , & ctrl ) ;
2007-02-07 10:14:38 -03:00
return sprintf ( buf , " %d \n " , ctrl . value ) ;
2006-12-04 08:31:45 -03:00
}
2007-10-08 16:26:13 -03:00
static DEVICE_ATTR ( brightness , S_IRUGO , show_brightness , NULL ) ;
2006-12-04 08:31:45 -03:00
2007-10-08 16:26:13 -03:00
static ssize_t show_saturation ( struct device * cd ,
struct device_attribute * attr , char * buf )
2006-12-04 08:31:45 -03:00
{
2007-05-08 17:22:29 -03:00
struct video_device * vdev =
2008-07-20 06:35:02 -03:00
container_of ( cd , struct video_device , dev ) ;
2006-12-04 08:31:45 -03:00
struct usb_usbvision * usbvision = video_get_drvdata ( vdev ) ;
struct v4l2_control ctrl ;
ctrl . id = V4L2_CID_SATURATION ;
ctrl . value = 0 ;
2010-12-29 13:53:21 -03:00
if ( usbvision - > user )
2009-02-21 18:11:31 -03:00
call_all ( usbvision , core , g_ctrl , & ctrl ) ;
2007-02-07 10:14:38 -03:00
return sprintf ( buf , " %d \n " , ctrl . value ) ;
2006-12-04 08:31:45 -03:00
}
2007-10-08 16:26:13 -03:00
static DEVICE_ATTR ( saturation , S_IRUGO , show_saturation , NULL ) ;
2006-12-04 08:31:45 -03:00
2007-10-08 16:26:13 -03:00
static ssize_t show_streaming ( struct device * cd ,
struct device_attribute * attr , char * buf )
2006-12-04 08:31:45 -03:00
{
2007-05-08 17:22:29 -03:00
struct video_device * vdev =
2008-07-20 06:35:02 -03:00
container_of ( cd , struct video_device , dev ) ;
2006-12-04 08:31:45 -03:00
struct usb_usbvision * usbvision = video_get_drvdata ( vdev ) ;
2007-05-08 17:22:29 -03:00
return sprintf ( buf , " %s \n " ,
2010-12-29 13:53:21 -03:00
YES_NO ( usbvision - > streaming = = stream_on ? 1 : 0 ) ) ;
2006-12-04 08:31:45 -03:00
}
2007-10-08 16:26:13 -03:00
static DEVICE_ATTR ( streaming , S_IRUGO , show_streaming , NULL ) ;
2006-12-04 08:31:45 -03:00
2007-10-08 16:26:13 -03:00
static ssize_t show_compression ( struct device * cd ,
struct device_attribute * attr , char * buf )
2006-12-04 08:31:45 -03:00
{
2007-05-08 17:22:29 -03:00
struct video_device * vdev =
2008-07-20 06:35:02 -03:00
container_of ( cd , struct video_device , dev ) ;
2006-12-04 08:31:45 -03:00
struct usb_usbvision * usbvision = video_get_drvdata ( vdev ) ;
2007-05-08 17:22:29 -03:00
return sprintf ( buf , " %s \n " ,
2010-12-29 13:53:21 -03:00
YES_NO ( usbvision - > isoc_mode = = ISOC_MODE_COMPRESS ) ) ;
2006-12-04 08:31:45 -03:00
}
2007-10-08 16:26:13 -03:00
static DEVICE_ATTR ( compression , S_IRUGO , show_compression , NULL ) ;
2006-12-04 08:31:45 -03:00
2007-10-08 16:26:13 -03:00
static ssize_t show_device_bridge ( struct device * cd ,
struct device_attribute * attr , char * buf )
2006-12-04 08:31:45 -03:00
{
2007-05-08 17:22:29 -03:00
struct video_device * vdev =
2008-07-20 06:35:02 -03:00
container_of ( cd , struct video_device , dev ) ;
2006-12-04 08:31:45 -03:00
struct usb_usbvision * usbvision = video_get_drvdata ( vdev ) ;
2010-12-19 20:21:36 -03:00
return sprintf ( buf , " %d \n " , usbvision - > bridge_type ) ;
2006-12-04 08:31:45 -03:00
}
2007-10-08 16:26:13 -03:00
static DEVICE_ATTR ( bridge , S_IRUGO , show_device_bridge , NULL ) ;
2006-12-04 08:31:45 -03:00
static void usbvision_create_sysfs ( struct video_device * vdev )
{
int res ;
2010-12-29 13:53:21 -03:00
2006-12-27 10:23:28 -02:00
if ( ! vdev )
return ;
do {
2008-07-20 06:35:02 -03:00
res = device_create_file ( & vdev - > dev , & dev_attr_version ) ;
2010-12-29 13:53:21 -03:00
if ( res < 0 )
2006-12-27 10:23:28 -02:00
break ;
2008-07-20 06:35:02 -03:00
res = device_create_file ( & vdev - > dev , & dev_attr_model ) ;
2010-12-29 13:53:21 -03:00
if ( res < 0 )
2006-12-27 10:23:28 -02:00
break ;
2008-07-20 06:35:02 -03:00
res = device_create_file ( & vdev - > dev , & dev_attr_hue ) ;
2010-12-29 13:53:21 -03:00
if ( res < 0 )
2006-12-27 10:23:28 -02:00
break ;
2008-07-20 06:35:02 -03:00
res = device_create_file ( & vdev - > dev , & dev_attr_contrast ) ;
2010-12-29 13:53:21 -03:00
if ( res < 0 )
2006-12-27 10:23:28 -02:00
break ;
2008-07-20 06:35:02 -03:00
res = device_create_file ( & vdev - > dev , & dev_attr_brightness ) ;
2010-12-29 13:53:21 -03:00
if ( res < 0 )
2006-12-27 10:23:28 -02:00
break ;
2008-07-20 06:35:02 -03:00
res = device_create_file ( & vdev - > dev , & dev_attr_saturation ) ;
2010-12-29 13:53:21 -03:00
if ( res < 0 )
2006-12-27 10:23:28 -02:00
break ;
2008-07-20 06:35:02 -03:00
res = device_create_file ( & vdev - > dev , & dev_attr_streaming ) ;
2010-12-29 13:53:21 -03:00
if ( res < 0 )
2006-12-27 10:23:28 -02:00
break ;
2008-07-20 06:35:02 -03:00
res = device_create_file ( & vdev - > dev , & dev_attr_compression ) ;
2010-12-29 13:53:21 -03:00
if ( res < 0 )
2006-12-27 10:23:28 -02:00
break ;
2008-07-20 06:35:02 -03:00
res = device_create_file ( & vdev - > dev , & dev_attr_bridge ) ;
2010-12-29 13:53:21 -03:00
if ( res > = 0 )
2006-12-27 10:23:28 -02:00
return ;
} while ( 0 ) ;
2009-01-08 09:13:42 -03:00
dev_err ( & vdev - > dev , " %s error: %d \n " , __func__ , res ) ;
2006-12-04 08:31:45 -03:00
}
static void usbvision_remove_sysfs ( struct video_device * vdev )
{
if ( vdev ) {
2008-07-20 06:35:02 -03:00
device_remove_file ( & vdev - > dev , & dev_attr_version ) ;
device_remove_file ( & vdev - > dev , & dev_attr_model ) ;
device_remove_file ( & vdev - > dev , & dev_attr_hue ) ;
device_remove_file ( & vdev - > dev , & dev_attr_contrast ) ;
device_remove_file ( & vdev - > dev , & dev_attr_brightness ) ;
device_remove_file ( & vdev - > dev , & dev_attr_saturation ) ;
device_remove_file ( & vdev - > dev , & dev_attr_streaming ) ;
device_remove_file ( & vdev - > dev , & dev_attr_compression ) ;
device_remove_file ( & vdev - > dev , & dev_attr_bridge ) ;
2006-12-04 08:31:45 -03:00
}
}
/*
* usbvision_open ( )
*
* This is part of Video 4 Linux API . The driver can be opened by one
* client only ( checks internal counter ' usbvision - > user ' ) . The procedure
* then allocates buffers needed for video processing .
*
*/
2008-12-30 06:58:20 -03:00
static int usbvision_v4l2_open ( struct file * file )
2006-12-04 08:31:45 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2010-12-19 20:21:36 -03:00
int err_code = 0 ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_IO , " open " ) ;
2012-06-23 08:03:50 -03:00
if ( mutex_lock_interruptible ( & usbvision - > v4l2_lock ) )
return - ERESTARTSYS ;
2006-12-04 08:31:45 -03:00
2015-07-20 09:59:28 -03:00
if ( usbvision - > user ) {
2010-12-19 20:21:36 -03:00
err_code = - EBUSY ;
2015-07-20 09:59:28 -03:00
} else {
2015-07-20 09:59:29 -03:00
err_code = v4l2_fh_open ( file ) ;
if ( err_code )
goto unlock ;
2007-02-07 10:13:11 -03:00
/* Allocate memory for the scratch ring buffer */
2010-12-19 20:21:36 -03:00
err_code = usbvision_scratch_alloc ( usbvision ) ;
2010-12-29 13:53:21 -03:00
if ( isoc_mode = = ISOC_MODE_COMPRESS ) {
2007-05-08 17:22:29 -03:00
/* Allocate intermediate decompression buffers
only if needed */
2010-12-19 20:21:36 -03:00
err_code = usbvision_decompress_alloc ( usbvision ) ;
2006-12-04 08:31:45 -03:00
}
2010-12-19 20:21:36 -03:00
if ( err_code ) {
2006-12-04 08:31:45 -03:00
/* Deallocate all buffers if trouble */
usbvision_scratch_free ( usbvision ) ;
usbvision_decompress_free ( usbvision ) ;
}
}
/* If so far no errors then we shall start the camera */
2010-12-19 20:21:36 -03:00
if ( ! err_code ) {
2006-12-04 08:31:45 -03:00
/* Send init sequence only once, it's large! */
if ( ! usbvision - > initialized ) {
int setup_ok = 0 ;
2010-12-29 13:53:21 -03:00
setup_ok = usbvision_setup ( usbvision , isoc_mode ) ;
2006-12-04 08:31:45 -03:00
if ( setup_ok )
usbvision - > initialized = 1 ;
else
2010-12-19 20:21:36 -03:00
err_code = - EBUSY ;
2006-12-04 08:31:45 -03:00
}
2010-12-19 20:21:36 -03:00
if ( ! err_code ) {
2006-12-04 08:31:45 -03:00
usbvision_begin_streaming ( usbvision ) ;
2010-12-19 20:21:36 -03:00
err_code = usbvision_init_isoc ( usbvision ) ;
2007-05-08 17:22:29 -03:00
/* device must be initialized before isoc transfer */
2010-12-29 13:53:21 -03:00
usbvision_muxsel ( usbvision , 0 ) ;
2015-07-20 09:59:28 -03:00
/* prepare queues */
usbvision_empty_framequeues ( usbvision ) ;
2006-12-04 08:31:45 -03:00
usbvision - > user + + ;
}
}
2015-07-20 09:59:29 -03:00
unlock :
2012-06-23 08:03:50 -03:00
mutex_unlock ( & usbvision - > v4l2_lock ) ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_IO , " success " ) ;
2010-12-19 20:21:36 -03:00
return err_code ;
2006-12-04 08:31:45 -03:00
}
/*
* usbvision_v4l2_close ( )
*
* This is part of Video 4 Linux API . The procedure
* stops streaming and deallocates all buffers that were earlier
* allocated in usbvision_v4l2_open ( ) .
*
*/
2008-12-30 06:58:20 -03:00
static int usbvision_v4l2_close ( struct file * file )
2006-12-04 08:31:45 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_IO , " close " ) ;
2012-06-23 08:03:50 -03:00
mutex_lock ( & usbvision - > v4l2_lock ) ;
2006-12-04 08:31:45 -03:00
usbvision_audio_off ( usbvision ) ;
usbvision_restart_isoc ( usbvision ) ;
usbvision_stop_isoc ( usbvision ) ;
usbvision_decompress_free ( usbvision ) ;
2006-12-15 16:46:53 -03:00
usbvision_frames_free ( usbvision ) ;
2007-02-07 10:13:11 -03:00
usbvision_empty_framequeues ( usbvision ) ;
2006-12-04 08:31:45 -03:00
usbvision_scratch_free ( usbvision ) ;
usbvision - > user - - ;
if ( usbvision - > remove_pending ) {
2008-04-04 20:50:07 -03:00
printk ( KERN_INFO " %s: Final disconnect \n " , __func__ ) ;
2006-12-04 08:31:45 -03:00
usbvision_release ( usbvision ) ;
2014-10-16 04:57:21 -03:00
return 0 ;
2006-12-04 08:31:45 -03:00
}
2012-06-23 08:03:50 -03:00
mutex_unlock ( & usbvision - > v4l2_lock ) ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_IO , " success " ) ;
2015-07-20 09:59:29 -03:00
return v4l2_fh_release ( file ) ;
2006-12-04 08:31:45 -03:00
}
/*
* usbvision_ioctl ( )
*
* This is part of Video 4 Linux API . The procedure handles ioctl ( ) calls .
*
*/
2007-05-08 17:22:29 -03:00
# ifdef CONFIG_VIDEO_ADV_DEBUG
2010-12-29 13:53:21 -03:00
static int vidioc_g_register ( struct file * file , void * priv ,
2008-12-30 07:14:19 -03:00
struct v4l2_dbg_register * reg )
2006-12-04 08:31:45 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2010-12-19 20:21:36 -03:00
int err_code ;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
/* NT100x has a 8-bit register space */
2010-12-19 20:21:36 -03:00
err_code = usbvision_read_reg ( usbvision , reg - > reg & 0xff ) ;
if ( err_code < 0 ) {
2015-03-09 13:34:12 -03:00
dev_err ( & usbvision - > vdev . dev ,
2009-01-08 09:13:42 -03:00
" %s: VIDIOC_DBG_G_REGISTER failed: error %d \n " ,
2010-12-19 20:21:36 -03:00
__func__ , err_code ) ;
return err_code ;
2007-05-08 17:22:29 -03:00
}
2010-12-19 20:21:36 -03:00
reg - > val = err_code ;
2008-12-30 07:14:19 -03:00
reg - > size = 1 ;
2007-05-08 17:22:29 -03:00
return 0 ;
}
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
static int vidioc_s_register ( struct file * file , void * priv ,
2013-03-24 08:28:46 -03:00
const struct v4l2_dbg_register * reg )
2007-05-08 17:22:29 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2010-12-19 20:21:36 -03:00
int err_code ;
2007-01-30 23:25:41 -03:00
2007-05-08 17:22:29 -03:00
/* NT100x has a 8-bit register space */
2010-12-29 13:53:21 -03:00
err_code = usbvision_write_reg ( usbvision , reg - > reg & 0xff , reg - > val ) ;
2010-12-19 20:21:36 -03:00
if ( err_code < 0 ) {
2015-03-09 13:34:12 -03:00
dev_err ( & usbvision - > vdev . dev ,
2009-01-08 09:13:42 -03:00
" %s: VIDIOC_DBG_S_REGISTER failed: error %d \n " ,
2010-12-19 20:21:36 -03:00
__func__ , err_code ) ;
return err_code ;
2007-05-08 17:22:29 -03:00
}
return 0 ;
}
2006-12-04 08:31:45 -03:00
# endif
2007-05-08 17:22:29 -03:00
2010-12-29 13:53:21 -03:00
static int vidioc_querycap ( struct file * file , void * priv ,
2007-05-08 17:22:29 -03:00
struct v4l2_capability * vc )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2015-07-20 09:59:32 -03:00
struct video_device * vdev = video_devdata ( file ) ;
2007-05-08 17:22:29 -03:00
strlcpy ( vc - > driver , " USBVision " , sizeof ( vc - > driver ) ) ;
strlcpy ( vc - > card ,
2010-12-19 20:21:36 -03:00
usbvision_device_data [ usbvision - > dev_model ] . model_string ,
2007-05-08 17:22:29 -03:00
sizeof ( vc - > card ) ) ;
2009-01-20 17:40:44 -03:00
usb_make_path ( usbvision - > dev , vc - > bus_info , sizeof ( vc - > bus_info ) ) ;
2015-07-20 09:59:32 -03:00
vc - > device_caps = usbvision - > have_tuner ? V4L2_CAP_TUNER : 0 ;
if ( vdev - > vfl_type = = VFL_TYPE_GRABBER )
vc - > device_caps | = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING ;
else
vc - > device_caps | = V4L2_CAP_RADIO ;
vc - > capabilities = vc - > device_caps | V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS ;
if ( usbvision_device_data [ usbvision - > dev_model ] . radio )
vc - > capabilities | = V4L2_CAP_RADIO ;
2007-05-08 17:22:29 -03:00
return 0 ;
}
2010-12-29 13:53:21 -03:00
static int vidioc_enum_input ( struct file * file , void * priv ,
2007-05-08 17:22:29 -03:00
struct v4l2_input * vi )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2007-05-08 17:22:29 -03:00
int chan ;
2009-05-02 16:38:47 -03:00
if ( vi - > index > = usbvision - > video_inputs )
2007-05-08 17:22:29 -03:00
return - EINVAL ;
2010-12-29 13:53:21 -03:00
if ( usbvision - > have_tuner )
2007-05-08 17:22:29 -03:00
chan = vi - > index ;
2010-12-29 13:53:21 -03:00
else
2010-12-19 20:33:51 -03:00
chan = vi - > index + 1 ; /* skip Television string*/
2010-12-29 13:53:21 -03:00
2007-05-08 17:22:29 -03:00
/* Determine the requested input characteristics
specific for each usbvision card model */
2010-12-29 13:53:21 -03:00
switch ( chan ) {
2007-05-08 17:22:29 -03:00
case 0 :
2010-12-19 20:21:36 -03:00
if ( usbvision_device_data [ usbvision - > dev_model ] . video_channels = = 4 ) {
2007-05-08 17:22:29 -03:00
strcpy ( vi - > name , " White Video Input " ) ;
} else {
strcpy ( vi - > name , " Television " ) ;
vi - > type = V4L2_INPUT_TYPE_TUNER ;
vi - > tuner = chan ;
vi - > std = USBVISION_NORMS ;
2006-12-04 08:31:45 -03:00
}
2007-05-08 17:22:29 -03:00
break ;
case 1 :
vi - > type = V4L2_INPUT_TYPE_CAMERA ;
2010-12-29 13:53:21 -03:00
if ( usbvision_device_data [ usbvision - > dev_model ] . video_channels = = 4 )
2007-05-08 17:22:29 -03:00
strcpy ( vi - > name , " Green Video Input " ) ;
2010-12-29 13:53:21 -03:00
else
2007-05-08 17:22:29 -03:00
strcpy ( vi - > name , " Composite Video Input " ) ;
vi - > std = V4L2_STD_PAL ;
break ;
case 2 :
vi - > type = V4L2_INPUT_TYPE_CAMERA ;
2010-12-29 13:53:21 -03:00
if ( usbvision_device_data [ usbvision - > dev_model ] . video_channels = = 4 )
2007-05-08 17:22:29 -03:00
strcpy ( vi - > name , " Yellow Video Input " ) ;
2010-12-29 13:53:21 -03:00
else
2007-05-08 17:22:29 -03:00
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 ;
}
return 0 ;
}
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
static int vidioc_g_input ( struct file * file , void * priv , unsigned int * input )
2007-05-08 17:22:29 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
* input = usbvision - > ctl_input ;
return 0 ;
}
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
static int vidioc_s_input ( struct file * file , void * priv , unsigned int input )
2007-05-08 17:22:29 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
2009-10-23 07:59:42 -03:00
if ( input > = usbvision - > video_inputs )
2007-05-08 17:22:29 -03:00
return - EINVAL ;
2006-12-04 08:31:45 -03:00
2007-06-26 16:35:30 -03:00
usbvision_muxsel ( usbvision , input ) ;
2007-05-08 17:22:29 -03:00
usbvision_set_input ( usbvision ) ;
usbvision_set_output ( usbvision ,
usbvision - > curwidth ,
usbvision - > curheight ) ;
return 0 ;
}
2006-12-04 08:31:45 -03:00
2013-03-15 06:10:40 -03:00
static int vidioc_s_std ( struct file * file , void * priv , v4l2_std_id id )
2007-05-08 17:22:29 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2013-03-15 06:10:40 -03:00
usbvision - > tvnorm_id = id ;
2006-12-04 08:31:45 -03:00
2014-04-28 16:53:01 -03:00
call_all ( usbvision , video , s_std , usbvision - > tvnorm_id ) ;
2007-06-26 16:35:30 -03:00
/* propagate the change to the decoder */
usbvision_muxsel ( usbvision , usbvision - > ctl_input ) ;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
return 0 ;
}
2006-12-04 08:31:45 -03:00
2013-06-03 05:36:47 -03:00
static int vidioc_g_std ( struct file * file , void * priv , v4l2_std_id * id )
{
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
* id = usbvision - > tvnorm_id ;
return 0 ;
}
2010-12-29 13:53:21 -03:00
static int vidioc_g_tuner ( struct file * file , void * priv ,
2007-05-08 17:22:29 -03:00
struct v4l2_tuner * vt )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:33:51 -03:00
if ( ! usbvision - > have_tuner | | vt - > index ) /* Only tuner 0 */
2007-05-08 17:22:29 -03:00
return - EINVAL ;
2010-12-29 13:53:21 -03:00
if ( usbvision - > radio ) {
2007-05-08 17:22:29 -03:00
strcpy ( vt - > name , " Radio " ) ;
vt - > type = V4L2_TUNER_RADIO ;
} else {
strcpy ( vt - > name , " Television " ) ;
}
/* Let clients fill in the remainder of this struct */
2009-02-21 18:11:31 -03:00
call_all ( usbvision , tuner , g_tuner , vt ) ;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
return 0 ;
}
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
static int vidioc_s_tuner ( struct file * file , void * priv ,
2013-03-15 06:10:06 -03:00
const struct v4l2_tuner * vt )
2007-05-08 17:22:29 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:33:51 -03:00
/* Only no or one tuner for now */
2007-05-08 17:22:29 -03:00
if ( ! usbvision - > have_tuner | | vt - > index )
return - EINVAL ;
/* let clients handle this */
2009-02-21 18:11:31 -03:00
call_all ( usbvision , tuner , s_tuner , vt ) ;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
return 0 ;
}
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
static int vidioc_g_frequency ( struct file * file , void * priv ,
2007-05-08 17:22:29 -03:00
struct v4l2_frequency * freq )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:33:51 -03:00
freq - > tuner = 0 ; /* Only one tuner */
2010-12-29 13:53:21 -03:00
if ( usbvision - > radio )
2007-05-08 17:22:29 -03:00
freq - > type = V4L2_TUNER_RADIO ;
2010-12-29 13:53:21 -03:00
else
2007-05-08 17:22:29 -03:00
freq - > type = V4L2_TUNER_ANALOG_TV ;
freq - > frequency = usbvision - > freq ;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
return 0 ;
}
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
static int vidioc_s_frequency ( struct file * file , void * priv ,
2013-03-19 04:09:26 -03:00
const struct v4l2_frequency * freq )
2007-05-08 17:22:29 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:33:51 -03:00
/* Only no or one tuner for now */
2007-05-08 17:22:29 -03:00
if ( ! usbvision - > have_tuner | | freq - > tuner )
return - EINVAL ;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
usbvision - > freq = freq - > frequency ;
2009-02-21 18:11:31 -03:00
call_all ( usbvision , tuner , s_frequency , freq ) ;
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
return 0 ;
}
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
static int vidioc_reqbufs ( struct file * file ,
2007-05-08 17:22:29 -03:00
void * priv , struct v4l2_requestbuffers * vr )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2007-05-08 17:22:29 -03:00
int ret ;
2010-12-29 13:53:21 -03:00
RESTRICT_TO_RANGE ( vr - > count , 1 , USBVISION_NUMFRAMES ) ;
2007-05-08 17:22:29 -03:00
/* Check input validity:
the user must do a VIDEO CAPTURE and MMAP method . */
2009-03-28 22:25:36 -03:00
if ( vr - > memory ! = V4L2_MEMORY_MMAP )
2007-05-08 17:22:29 -03:00
return - EINVAL ;
2010-12-29 13:53:21 -03:00
if ( usbvision - > streaming = = stream_on ) {
ret = usbvision_stream_interrupt ( usbvision ) ;
if ( ret )
2007-05-08 17:22:29 -03:00
return ret ;
2006-12-04 08:31:45 -03:00
}
2007-05-08 17:22:29 -03:00
usbvision_frames_free ( usbvision ) ;
usbvision_empty_framequeues ( usbvision ) ;
2010-12-29 13:53:21 -03:00
vr - > count = usbvision_frames_alloc ( usbvision , vr - > count ) ;
2007-05-08 17:22:29 -03:00
2010-12-19 20:21:36 -03:00
usbvision - > cur_frame = NULL ;
2007-05-08 17:22:29 -03:00
2006-12-04 08:31:45 -03:00
return 0 ;
}
2010-12-29 13:53:21 -03:00
static int vidioc_querybuf ( struct file * file ,
2007-05-08 17:22:29 -03:00
void * priv , struct v4l2_buffer * vb )
2006-12-04 08:31:45 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2007-05-08 17:22:29 -03:00
struct usbvision_frame * frame ;
/* FIXME : must control
that buffers are mapped ( VIDIOC_REQBUFS has been called ) */
2010-12-29 13:53:21 -03:00
if ( vb - > index > = usbvision - > num_frames )
2007-05-08 17:22:29 -03:00
return - EINVAL ;
/* Updating the corresponding frame state */
2012-10-22 17:10:16 -03:00
vb - > flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC ;
2007-05-08 17:22:29 -03:00
frame = & usbvision - > frame [ vb - > index ] ;
2010-12-29 13:53:21 -03:00
if ( frame - > grabstate > = frame_state_ready )
2007-05-08 17:22:29 -03:00
vb - > flags | = V4L2_BUF_FLAG_QUEUED ;
2010-12-29 13:53:21 -03:00
if ( frame - > grabstate > = frame_state_done )
2007-05-08 17:22:29 -03:00
vb - > flags | = V4L2_BUF_FLAG_DONE ;
2010-12-29 13:53:21 -03:00
if ( frame - > grabstate = = frame_state_unused )
2007-05-08 17:22:29 -03:00
vb - > flags | = V4L2_BUF_FLAG_MAPPED ;
vb - > memory = V4L2_MEMORY_MMAP ;
2010-12-29 13:53:21 -03:00
vb - > m . offset = vb - > index * PAGE_ALIGN ( usbvision - > max_frame_size ) ;
2007-05-08 17:22:29 -03:00
vb - > memory = V4L2_MEMORY_MMAP ;
vb - > field = V4L2_FIELD_NONE ;
2010-12-29 13:53:21 -03:00
vb - > length = usbvision - > curwidth *
usbvision - > curheight *
2007-05-08 17:22:29 -03:00
usbvision - > palette . bytes_per_pixel ;
vb - > timestamp = usbvision - > frame [ vb - > index ] . timestamp ;
vb - > sequence = usbvision - > frame [ vb - > index ] . sequence ;
return 0 ;
2006-12-04 08:31:45 -03:00
}
2010-12-29 13:53:21 -03:00
static int vidioc_qbuf ( struct file * file , void * priv , struct v4l2_buffer * vb )
2007-05-08 17:22:29 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2007-05-08 17:22:29 -03:00
struct usbvision_frame * frame ;
unsigned long lock_flags ;
/* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */
2010-12-29 13:53:21 -03:00
if ( vb - > index > = usbvision - > num_frames )
2007-05-08 17:22:29 -03:00
return - EINVAL ;
frame = & usbvision - > frame [ vb - > index ] ;
2010-12-29 13:53:21 -03:00
if ( frame - > grabstate ! = frame_state_unused )
2007-05-08 17:22:29 -03:00
return - EAGAIN ;
/* Mark it as ready and enqueue frame */
2010-12-19 20:21:36 -03:00
frame - > grabstate = frame_state_ready ;
frame - > scanstate = scan_state_scanning ;
2007-05-08 17:22:29 -03:00
frame - > scanlength = 0 ; /* Accumulated in usbvision_parse_data() */
vb - > flags & = ~ V4L2_BUF_FLAG_DONE ;
/* set v4l2_format index */
frame - > v4l2_format = usbvision - > palette ;
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 ) ;
return 0 ;
}
2010-12-29 13:53:21 -03:00
static int vidioc_dqbuf ( struct file * file , void * priv , struct v4l2_buffer * vb )
2007-05-08 17:22:29 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2007-05-08 17:22:29 -03:00
int ret ;
struct usbvision_frame * f ;
unsigned long lock_flags ;
if ( list_empty ( & ( usbvision - > outqueue ) ) ) {
2010-12-19 20:21:36 -03:00
if ( usbvision - > streaming = = stream_idle )
2007-05-08 17:22:29 -03:00
return - EINVAL ;
ret = wait_event_interruptible
( usbvision - > wait_frame ,
! list_empty ( & ( usbvision - > outqueue ) ) ) ;
if ( ret )
return ret ;
}
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 ) ;
2010-12-19 20:21:36 -03:00
f - > grabstate = frame_state_unused ;
2007-05-08 17:22:29 -03:00
vb - > memory = V4L2_MEMORY_MMAP ;
vb - > flags = V4L2_BUF_FLAG_MAPPED |
V4L2_BUF_FLAG_QUEUED |
2012-10-22 17:10:16 -03:00
V4L2_BUF_FLAG_DONE |
V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC ;
2007-05-08 17:22:29 -03:00
vb - > index = f - > index ;
vb - > sequence = f - > sequence ;
vb - > timestamp = f - > timestamp ;
vb - > field = V4L2_FIELD_NONE ;
vb - > bytesused = f - > scanlength ;
return 0 ;
}
static int vidioc_streamon ( struct file * file , void * priv , enum v4l2_buf_type i )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2007-05-08 17:22:29 -03:00
2010-12-19 20:21:36 -03:00
usbvision - > streaming = stream_on ;
2009-02-21 18:11:31 -03:00
call_all ( usbvision , video , s_stream , 1 ) ;
2007-05-08 17:22:29 -03:00
return 0 ;
}
static int vidioc_streamoff ( struct file * file ,
void * priv , enum v4l2_buf_type type )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2007-05-08 17:22:29 -03:00
if ( type ! = V4L2_BUF_TYPE_VIDEO_CAPTURE )
return - EINVAL ;
2010-12-29 13:53:21 -03:00
if ( usbvision - > streaming = = stream_on ) {
2007-05-08 17:22:29 -03:00
usbvision_stream_interrupt ( usbvision ) ;
/* Stop all video streamings */
2009-02-21 18:11:31 -03:00
call_all ( usbvision , video , s_stream , 0 ) ;
2007-05-08 17:22:29 -03:00
}
usbvision_empty_framequeues ( usbvision ) ;
return 0 ;
}
2010-12-29 13:53:21 -03:00
static int vidioc_enum_fmt_vid_cap ( struct file * file , void * priv ,
2007-05-08 17:22:29 -03:00
struct v4l2_fmtdesc * vfd )
{
2010-12-29 13:53:21 -03:00
if ( vfd - > index > = USBVISION_SUPPORTED_PALETTES - 1 )
2007-05-08 17:22:29 -03:00
return - EINVAL ;
2010-12-29 13:53:21 -03:00
strcpy ( vfd - > description , usbvision_v4l2_format [ vfd - > index ] . desc ) ;
2007-05-08 17:22:29 -03:00
vfd - > pixelformat = usbvision_v4l2_format [ vfd - > index ] . format ;
return 0 ;
}
2010-12-29 13:53:21 -03:00
static int vidioc_g_fmt_vid_cap ( struct file * file , void * priv ,
2007-05-08 17:22:29 -03:00
struct v4l2_format * vf )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2007-05-08 17:22:29 -03:00
vf - > fmt . pix . width = usbvision - > curwidth ;
vf - > fmt . pix . height = usbvision - > curheight ;
vf - > fmt . pix . pixelformat = usbvision - > palette . format ;
vf - > fmt . pix . bytesperline =
2010-12-29 13:53:21 -03:00
usbvision - > curwidth * usbvision - > palette . bytes_per_pixel ;
vf - > fmt . pix . sizeimage = vf - > fmt . pix . bytesperline * usbvision - > curheight ;
2007-05-08 17:22:29 -03:00
vf - > fmt . pix . colorspace = V4L2_COLORSPACE_SMPTE170M ;
vf - > fmt . pix . field = V4L2_FIELD_NONE ; /* Always progressive image */
return 0 ;
}
2010-12-29 13:53:21 -03:00
static int vidioc_try_fmt_vid_cap ( struct file * file , void * priv ,
2007-05-08 17:22:29 -03:00
struct v4l2_format * vf )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2010-12-19 20:21:36 -03:00
int format_idx ;
2007-05-08 17:22:29 -03:00
/* Find requested format in available ones */
2010-12-29 13:53:21 -03:00
for ( format_idx = 0 ; format_idx < USBVISION_SUPPORTED_PALETTES ; format_idx + + ) {
if ( vf - > fmt . pix . pixelformat = =
2010-12-19 20:21:36 -03:00
usbvision_v4l2_format [ format_idx ] . format ) {
usbvision - > palette = usbvision_v4l2_format [ format_idx ] ;
2007-05-08 17:22:29 -03:00
break ;
}
}
/* robustness */
2010-12-29 13:53:21 -03:00
if ( format_idx = = USBVISION_SUPPORTED_PALETTES )
2007-05-08 17:22:29 -03:00
return - EINVAL ;
RESTRICT_TO_RANGE ( vf - > fmt . pix . width , MIN_FRAME_WIDTH , MAX_FRAME_WIDTH ) ;
RESTRICT_TO_RANGE ( vf - > fmt . pix . height , MIN_FRAME_HEIGHT , MAX_FRAME_HEIGHT ) ;
vf - > fmt . pix . bytesperline = vf - > fmt . pix . width *
usbvision - > palette . bytes_per_pixel ;
vf - > fmt . pix . sizeimage = vf - > fmt . pix . bytesperline * vf - > fmt . pix . height ;
return 0 ;
}
2008-05-28 12:16:41 -03:00
static int vidioc_s_fmt_vid_cap ( struct file * file , void * priv ,
2007-05-08 17:22:29 -03:00
struct v4l2_format * vf )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2007-05-08 17:22:29 -03:00
int ret ;
2010-12-29 13:53:21 -03:00
ret = vidioc_try_fmt_vid_cap ( file , priv , vf ) ;
if ( ret )
2007-05-08 17:22:29 -03:00
return ret ;
/* stop io in case it is already in progress */
2010-12-29 13:53:21 -03:00
if ( usbvision - > streaming = = stream_on ) {
ret = usbvision_stream_interrupt ( usbvision ) ;
if ( ret )
2007-05-08 17:22:29 -03:00
return ret ;
}
usbvision_frames_free ( usbvision ) ;
usbvision_empty_framequeues ( usbvision ) ;
2010-12-19 20:21:36 -03:00
usbvision - > cur_frame = NULL ;
2007-05-08 17:22:29 -03:00
/* by now we are committed to the new data... */
usbvision_set_output ( usbvision , vf - > fmt . pix . width , vf - > fmt . pix . height ) ;
return 0 ;
}
2006-12-04 08:31:45 -03:00
2012-06-23 08:03:50 -03:00
static ssize_t usbvision_read ( struct file * file , char __user * buf ,
2006-12-04 08:31:45 -03:00
size_t count , loff_t * ppos )
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
int noblock = file - > f_flags & O_NONBLOCK ;
unsigned long lock_flags ;
2010-12-29 13:53:21 -03:00
int ret , i ;
2006-12-04 08:31:45 -03:00
struct usbvision_frame * frame ;
2008-04-04 20:50:07 -03:00
PDEBUG ( DBG_IO , " %s: %ld bytes, noblock=%d " , __func__ ,
2007-05-08 17:22:29 -03:00
( unsigned long ) count , noblock ) ;
2006-12-04 08:31:45 -03:00
if ( ! USBVISION_IS_OPERATIONAL ( usbvision ) | | ( buf = = NULL ) )
return - EFAULT ;
2007-05-08 17:22:29 -03:00
/* This entry point is compatible with the mmap routines
so that a user can do either VIDIOC_QBUF / VIDIOC_DQBUF
to get frames or call read on the device . */
2010-12-29 13:53:21 -03:00
if ( ! usbvision - > num_frames ) {
2007-05-08 17:22:29 -03:00
/* First, allocate some frames to work with
if this has not been done with VIDIOC_REQBUF */
2007-02-07 10:13:11 -03:00
usbvision_frames_free ( usbvision ) ;
usbvision_empty_framequeues ( usbvision ) ;
2010-12-29 13:53:21 -03:00
usbvision_frames_alloc ( usbvision , USBVISION_NUMFRAMES ) ;
2007-02-07 10:13:11 -03:00
}
2010-12-29 13:53:21 -03:00
if ( usbvision - > streaming ! = stream_on ) {
2007-02-07 10:13:11 -03:00
/* no stream is running, make it running ! */
2010-12-19 20:21:36 -03:00
usbvision - > streaming = stream_on ;
2009-02-21 18:11:31 -03:00
call_all ( usbvision , video , s_stream , 1 ) ;
2007-02-07 10:13:11 -03:00
}
2006-12-04 08:31:45 -03:00
2007-05-08 17:22:29 -03:00
/* Then, enqueue as many frames as possible
( like a user of VIDIOC_QBUF would do ) */
2010-12-29 13:53:21 -03:00
for ( i = 0 ; i < usbvision - > num_frames ; i + + ) {
2006-12-04 08:31:45 -03:00
frame = & usbvision - > frame [ i ] ;
2010-12-29 13:53:21 -03:00
if ( frame - > grabstate = = frame_state_unused ) {
2006-12-04 08:31:45 -03:00
/* Mark it as ready and enqueue frame */
2010-12-19 20:21:36 -03:00
frame - > grabstate = frame_state_ready ;
frame - > scanstate = scan_state_scanning ;
2007-05-08 17:22:29 -03:00
/* Accumulated in usbvision_parse_data() */
frame - > scanlength = 0 ;
2006-12-04 08:31:45 -03:00
/* set v4l2_format index */
frame - > v4l2_format = usbvision - > palette ;
spin_lock_irqsave ( & usbvision - > queue_lock , lock_flags ) ;
list_add_tail ( & frame - > frame , & usbvision - > inqueue ) ;
2007-05-08 17:22:29 -03:00
spin_unlock_irqrestore ( & usbvision - > queue_lock ,
lock_flags ) ;
2006-12-04 08:31:45 -03:00
}
}
/* Then try to steal a frame (like a VIDIOC_DQBUF would do) */
if ( list_empty ( & ( usbvision - > outqueue ) ) ) {
2010-12-29 13:53:21 -03:00
if ( noblock )
2006-12-04 08:31:45 -03:00
return - EAGAIN ;
ret = wait_event_interruptible
( usbvision - > wait_frame ,
! list_empty ( & ( usbvision - > outqueue ) ) ) ;
if ( ret )
return ret ;
}
spin_lock_irqsave ( & usbvision - > queue_lock , lock_flags ) ;
frame = list_entry ( usbvision - > outqueue . next ,
struct usbvision_frame , frame ) ;
list_del ( usbvision - > outqueue . next ) ;
spin_unlock_irqrestore ( & usbvision - > queue_lock , lock_flags ) ;
/* An error returns an empty frame */
2010-12-19 20:21:36 -03:00
if ( frame - > grabstate = = frame_state_error ) {
2006-12-04 08:31:45 -03:00
frame - > bytes_read = 0 ;
return 0 ;
}
2007-05-08 17:22:29 -03:00
PDEBUG ( DBG_IO , " %s: frmx=%d, bytes_read=%ld, scanlength=%ld " ,
2008-04-04 20:50:07 -03:00
__func__ ,
2007-05-08 17:22:29 -03:00
frame - > index , frame - > bytes_read , frame - > scanlength ) ;
2006-12-04 08:31:45 -03:00
/* copy bytes to user space; we allow for partials reads */
if ( ( count + frame - > bytes_read ) > ( unsigned long ) frame - > scanlength )
count = frame - > scanlength - frame - > bytes_read ;
2010-12-29 13:53:21 -03:00
if ( copy_to_user ( buf , frame - > data + frame - > bytes_read , count ) )
2006-12-04 08:31:45 -03:00
return - EFAULT ;
frame - > bytes_read + = count ;
2007-05-08 17:22:29 -03:00
PDEBUG ( DBG_IO , " %s: {copy} count used=%ld, new bytes_read=%ld " ,
2008-04-04 20:50:07 -03:00
__func__ ,
2007-05-08 17:22:29 -03:00
( unsigned long ) count , frame - > bytes_read ) ;
2006-12-04 08:31:45 -03:00
2015-06-05 10:47:36 -03:00
# if 1
/*
* FIXME :
* For now , forget the frame if it has not been read in one shot .
*/
frame - > bytes_read = 0 ;
/* Mark it as available to be used again. */
frame - > grabstate = frame_state_unused ;
# else
if ( frame - > bytes_read > = frame - > scanlength ) {
/* All data has been read */
2006-12-04 08:31:45 -03:00
frame - > bytes_read = 0 ;
/* Mark it as available to be used again. */
2010-12-19 20:21:36 -03:00
frame - > grabstate = frame_state_unused ;
2015-06-05 10:47:36 -03:00
}
# endif
2006-12-04 08:31:45 -03:00
return count ;
}
2012-06-23 08:03:50 -03:00
static ssize_t usbvision_v4l2_read ( struct file * file , char __user * buf ,
size_t count , loff_t * ppos )
{
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
int res ;
if ( mutex_lock_interruptible ( & usbvision - > v4l2_lock ) )
return - ERESTARTSYS ;
res = usbvision_read ( file , buf , count , ppos ) ;
mutex_unlock ( & usbvision - > v4l2_lock ) ;
return res ;
}
static int usbvision_mmap ( struct file * file , struct vm_area_struct * vma )
2006-12-04 08:31:45 -03:00
{
unsigned long size = vma - > vm_end - vma - > vm_start ,
start = vma - > vm_start ;
void * pos ;
u32 i ;
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
2007-02-07 10:13:11 -03:00
PDEBUG ( DBG_MMAP , " mmap " ) ;
2010-12-29 13:53:21 -03:00
if ( ! USBVISION_IS_OPERATIONAL ( usbvision ) )
2006-12-04 08:31:45 -03:00
return - EFAULT ;
if ( ! ( vma - > vm_flags & VM_WRITE ) | |
2007-02-07 10:13:11 -03:00
size ! = PAGE_ALIGN ( usbvision - > max_frame_size ) ) {
2006-12-04 08:31:45 -03:00
return - EINVAL ;
}
2007-02-07 10:13:11 -03:00
for ( i = 0 ; i < usbvision - > num_frames ; i + + ) {
2007-05-08 17:22:29 -03:00
if ( ( ( PAGE_ALIGN ( usbvision - > max_frame_size ) * i ) > > PAGE_SHIFT ) = =
vma - > vm_pgoff )
2006-12-04 08:31:45 -03:00
break ;
}
2007-02-07 10:13:11 -03:00
if ( i = = usbvision - > num_frames ) {
2007-05-08 17:22:29 -03:00
PDEBUG ( DBG_MMAP ,
" mmap: user supplied mapping address is out of range " ) ;
2006-12-04 08:31:45 -03:00
return - EINVAL ;
}
/* VM_IO is eventually going to replace PageReserved altogether */
mm: kill vma flag VM_RESERVED and mm->reserved_vm counter
A long time ago, in v2.4, VM_RESERVED kept swapout process off VMA,
currently it lost original meaning but still has some effects:
| effect | alternative flags
-+------------------------+---------------------------------------------
1| account as reserved_vm | VM_IO
2| skip in core dump | VM_IO, VM_DONTDUMP
3| do not merge or expand | VM_IO, VM_DONTEXPAND, VM_HUGETLB, VM_PFNMAP
4| do not mlock | VM_IO, VM_DONTEXPAND, VM_HUGETLB, VM_PFNMAP
This patch removes reserved_vm counter from mm_struct. Seems like nobody
cares about it, it does not exported into userspace directly, it only
reduces total_vm showed in proc.
Thus VM_RESERVED can be replaced with VM_IO or pair VM_DONTEXPAND | VM_DONTDUMP.
remap_pfn_range() and io_remap_pfn_range() set VM_IO|VM_DONTEXPAND|VM_DONTDUMP.
remap_vmalloc_range() set VM_DONTEXPAND | VM_DONTDUMP.
[akpm@linux-foundation.org: drivers/vfio/pci/vfio_pci.c fixup]
Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Carsten Otte <cotte@de.ibm.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Eric Paris <eparis@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Morris <james.l.morris@oracle.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Kentaro Takeda <takedakn@nttdata.co.jp>
Cc: Matt Helsley <matthltc@us.ibm.com>
Cc: Nick Piggin <npiggin@kernel.dk>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Venkatesh Pallipadi <venki@google.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-10-08 16:29:02 -07:00
vma - > vm_flags | = VM_IO | VM_DONTEXPAND | VM_DONTDUMP ;
2006-12-04 08:31:45 -03:00
pos = usbvision - > frame [ i ] . data ;
while ( size > 0 ) {
if ( vm_insert_page ( vma , start , vmalloc_to_page ( pos ) ) ) {
2006-12-09 16:42:54 -03:00
PDEBUG ( DBG_MMAP , " mmap: vm_insert_page failed " ) ;
2006-12-04 08:31:45 -03:00
return - EAGAIN ;
}
start + = PAGE_SIZE ;
pos + = PAGE_SIZE ;
size - = PAGE_SIZE ;
}
return 0 ;
}
2012-06-23 08:03:50 -03:00
static int usbvision_v4l2_mmap ( struct file * file , struct vm_area_struct * vma )
{
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
int res ;
if ( mutex_lock_interruptible ( & usbvision - > v4l2_lock ) )
return - ERESTARTSYS ;
res = usbvision_mmap ( file , vma ) ;
mutex_unlock ( & usbvision - > v4l2_lock ) ;
return res ;
}
2006-12-04 08:31:45 -03:00
/*
* Here comes the stuff for radio on usbvision based devices
*
*/
2008-12-30 06:58:20 -03:00
static int usbvision_radio_open ( struct file * file )
2006-12-04 08:31:45 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2010-12-19 20:21:36 -03:00
int err_code = 0 ;
2006-12-04 08:31:45 -03:00
2008-04-04 20:50:07 -03:00
PDEBUG ( DBG_IO , " %s: " , __func__ ) ;
2006-12-04 08:31:45 -03:00
2012-06-23 08:03:50 -03:00
if ( mutex_lock_interruptible ( & usbvision - > v4l2_lock ) )
return - ERESTARTSYS ;
2015-07-20 09:59:29 -03:00
err_code = v4l2_fh_open ( file ) ;
if ( err_code )
goto out ;
2006-12-04 08:31:45 -03:00
if ( usbvision - > user ) {
2015-03-09 13:34:12 -03:00
dev_err ( & usbvision - > rdev . dev ,
2009-01-08 09:13:42 -03:00
" %s: Someone tried to open an already opened USBVision Radio! \n " ,
__func__ ) ;
2010-12-19 20:21:36 -03:00
err_code = - EBUSY ;
2010-12-29 13:53:21 -03:00
} else {
2007-02-07 10:14:38 -03:00
/* Alternate interface 1 is is the biggest frame size */
2010-12-19 20:21:36 -03:00
err_code = usbvision_set_alternate ( usbvision ) ;
if ( err_code < 0 ) {
usbvision - > last_error = err_code ;
err_code = - EBUSY ;
2007-12-12 18:25:23 -03:00
goto out ;
2007-02-07 10:14:38 -03:00
}
2010-12-19 20:33:51 -03:00
/* If so far no errors then we shall start the radio */
2006-12-04 08:31:45 -03:00
usbvision - > radio = 1 ;
2009-02-21 18:11:31 -03:00
call_all ( usbvision , tuner , s_radio ) ;
2006-12-04 08:31:45 -03:00
usbvision_set_audio ( usbvision , USBVISION_AUDIO_RADIO ) ;
usbvision - > user + + ;
}
2007-12-12 18:25:23 -03:00
out :
2012-06-23 08:03:50 -03:00
mutex_unlock ( & usbvision - > v4l2_lock ) ;
2010-12-19 20:21:36 -03:00
return err_code ;
2006-12-04 08:31:45 -03:00
}
2008-12-30 06:58:20 -03:00
static int usbvision_radio_close ( struct file * file )
2006-12-04 08:31:45 -03:00
{
2008-08-23 08:32:09 -03:00
struct usb_usbvision * usbvision = video_drvdata ( file ) ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_IO , " " ) ;
2012-06-23 08:03:50 -03:00
mutex_lock ( & usbvision - > v4l2_lock ) ;
2007-02-07 10:14:38 -03:00
/* Set packet size to 0 */
2010-12-29 13:53:21 -03:00
usbvision - > iface_alt = 0 ;
2015-07-20 09:59:29 -03:00
usb_set_interface ( usbvision - > dev , usbvision - > iface ,
2010-12-19 20:21:36 -03:00
usbvision - > iface_alt ) ;
2007-02-07 10:14:38 -03:00
2006-12-04 08:31:45 -03:00
usbvision_audio_off ( usbvision ) ;
2010-12-29 13:53:21 -03:00
usbvision - > radio = 0 ;
2006-12-04 08:31:45 -03:00
usbvision - > user - - ;
if ( usbvision - > remove_pending ) {
2008-04-04 20:50:07 -03:00
printk ( KERN_INFO " %s: Final disconnect \n " , __func__ ) ;
2015-07-20 09:59:29 -03:00
v4l2_fh_release ( file ) ;
2006-12-04 08:31:45 -03:00
usbvision_release ( usbvision ) ;
2015-07-20 09:59:29 -03:00
return 0 ;
2006-12-04 08:31:45 -03:00
}
2012-06-23 08:03:50 -03:00
mutex_unlock ( & usbvision - > v4l2_lock ) ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_IO , " success " ) ;
2015-07-20 09:59:29 -03:00
return v4l2_fh_release ( file ) ;
2006-12-04 08:31:45 -03:00
}
2010-12-19 20:33:51 -03:00
/* Video registration stuff */
2006-12-04 08:31:45 -03:00
2010-12-19 20:33:51 -03:00
/* Video template */
2008-12-30 06:58:20 -03:00
static const struct v4l2_file_operations usbvision_fops = {
2006-12-04 08:31:45 -03:00
. owner = THIS_MODULE ,
. open = usbvision_v4l2_open ,
. release = usbvision_v4l2_close ,
. read = usbvision_v4l2_read ,
. mmap = usbvision_v4l2_mmap ,
2010-12-18 11:06:09 -03:00
. unlocked_ioctl = video_ioctl2 ,
2006-12-04 08:31:45 -03:00
} ;
2008-07-21 02:57:38 -03:00
static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
2007-05-08 17:22:29 -03:00
. vidioc_querycap = vidioc_querycap ,
2008-05-28 12:16:41 -03:00
. vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap ,
. vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap ,
. vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap ,
. vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap ,
2007-05-08 17:22:29 -03:00
. vidioc_reqbufs = vidioc_reqbufs ,
. vidioc_querybuf = vidioc_querybuf ,
. vidioc_qbuf = vidioc_qbuf ,
. vidioc_dqbuf = vidioc_dqbuf ,
. vidioc_s_std = vidioc_s_std ,
2013-06-03 05:36:47 -03:00
. vidioc_g_std = vidioc_g_std ,
2007-05-08 17:22:29 -03:00
. vidioc_enum_input = vidioc_enum_input ,
. vidioc_g_input = vidioc_g_input ,
. vidioc_s_input = vidioc_s_input ,
. vidioc_streamon = vidioc_streamon ,
. vidioc_streamoff = vidioc_streamoff ,
. vidioc_g_tuner = vidioc_g_tuner ,
. vidioc_s_tuner = vidioc_s_tuner ,
. vidioc_g_frequency = vidioc_g_frequency ,
. vidioc_s_frequency = vidioc_s_frequency ,
2015-07-20 09:59:29 -03:00
. vidioc_log_status = v4l2_ctrl_log_status ,
. vidioc_subscribe_event = v4l2_ctrl_subscribe_event ,
. vidioc_unsubscribe_event = v4l2_event_unsubscribe ,
2007-05-08 17:22:29 -03:00
# ifdef CONFIG_VIDEO_ADV_DEBUG
. vidioc_g_register = vidioc_g_register ,
. vidioc_s_register = vidioc_s_register ,
# endif
2008-07-21 02:57:38 -03:00
} ;
static struct video_device usbvision_video_template = {
. fops = & usbvision_fops ,
2010-12-29 13:53:21 -03:00
. ioctl_ops = & usbvision_ioctl_ops ,
2008-07-21 02:57:38 -03:00
. name = " usbvision-video " ,
2015-03-09 13:34:12 -03:00
. release = video_device_release_empty ,
2010-12-29 13:53:21 -03:00
. tvnorms = USBVISION_NORMS ,
2006-12-04 08:31:45 -03:00
} ;
2010-12-19 20:33:51 -03:00
/* Radio template */
2008-12-30 06:58:20 -03:00
static const struct v4l2_file_operations usbvision_radio_fops = {
2006-12-04 08:31:45 -03:00
. owner = THIS_MODULE ,
. open = usbvision_radio_open ,
. release = usbvision_radio_close ,
2015-07-20 09:59:29 -03:00
. poll = v4l2_ctrl_poll ,
2010-12-18 11:06:09 -03:00
. unlocked_ioctl = video_ioctl2 ,
2006-12-04 08:31:45 -03:00
} ;
2008-07-21 02:57:38 -03:00
static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = {
2007-05-08 17:22:29 -03:00
. vidioc_querycap = vidioc_querycap ,
. vidioc_g_tuner = vidioc_g_tuner ,
. vidioc_s_tuner = vidioc_s_tuner ,
. vidioc_g_frequency = vidioc_g_frequency ,
. vidioc_s_frequency = vidioc_s_frequency ,
2015-07-20 09:59:29 -03:00
. vidioc_log_status = v4l2_ctrl_log_status ,
. vidioc_subscribe_event = v4l2_ctrl_subscribe_event ,
. vidioc_unsubscribe_event = v4l2_event_unsubscribe ,
2008-07-21 02:57:38 -03:00
} ;
static struct video_device usbvision_radio_template = {
. fops = & usbvision_radio_fops ,
2010-12-29 13:53:21 -03:00
. name = " usbvision-radio " ,
2015-03-09 13:34:12 -03:00
. release = video_device_release_empty ,
2010-12-29 13:53:21 -03:00
. ioctl_ops = & usbvision_radio_ioctl_ops ,
2006-12-04 08:31:45 -03:00
} ;
2015-03-09 13:34:12 -03:00
static void usbvision_vdev_init ( struct usb_usbvision * usbvision ,
struct video_device * vdev ,
const struct video_device * vdev_template ,
const char * name )
2006-12-04 08:31:45 -03:00
{
struct usb_device * usb_dev = usbvision - > dev ;
if ( usb_dev = = NULL ) {
2009-01-08 09:13:42 -03:00
dev_err ( & usbvision - > dev - > dev ,
" %s: usbvision->dev is not set \n " , __func__ ) ;
2015-03-09 13:34:12 -03:00
return ;
2006-12-04 08:31:45 -03:00
}
* vdev = * vdev_template ;
2010-12-18 11:06:09 -03:00
vdev - > lock = & usbvision - > v4l2_lock ;
2009-02-21 18:11:31 -03:00
vdev - > v4l2_dev = & usbvision - > v4l2_dev ;
2006-12-04 08:31:45 -03:00
snprintf ( vdev - > name , sizeof ( vdev - > name ) , " %s " , name ) ;
video_set_drvdata ( vdev , usbvision ) ;
}
2010-12-19 20:33:51 -03:00
/* unregister video4linux devices */
2006-12-04 08:31:45 -03:00
static void usbvision_unregister_video ( struct usb_usbvision * usbvision )
{
2010-12-19 20:33:51 -03:00
/* Radio Device: */
2015-03-09 13:34:12 -03:00
if ( video_is_registered ( & usbvision - > rdev ) ) {
2009-11-27 13:57:15 -03:00
PDEBUG ( DBG_PROBE , " unregister %s [v4l2] " ,
2015-03-09 13:34:12 -03:00
video_device_node_name ( & usbvision - > rdev ) ) ;
video_unregister_device ( & usbvision - > rdev ) ;
2006-12-04 08:31:45 -03:00
}
2010-12-19 20:33:51 -03:00
/* Video Device: */
2015-03-09 13:34:12 -03:00
if ( video_is_registered ( & usbvision - > vdev ) ) {
2009-11-27 13:57:15 -03:00
PDEBUG ( DBG_PROBE , " unregister %s [v4l2] " ,
2015-03-09 13:34:12 -03:00
video_device_node_name ( & usbvision - > vdev ) ) ;
video_unregister_device ( & usbvision - > vdev ) ;
2006-12-04 08:31:45 -03:00
}
}
2010-12-19 20:33:51 -03:00
/* register video4linux devices */
2012-12-21 13:17:53 -08:00
static int usbvision_register_video ( struct usb_usbvision * usbvision )
2006-12-04 08:31:45 -03:00
{
2015-07-20 09:59:30 -03:00
int res = - ENOMEM ;
2010-12-19 20:33:51 -03:00
/* Video Device: */
2015-03-09 13:34:12 -03:00
usbvision_vdev_init ( usbvision , & usbvision - > vdev ,
& usbvision_video_template , " USBVision Video " ) ;
if ( video_register_device ( & usbvision - > vdev , VFL_TYPE_GRABBER , video_nr ) < 0 )
2006-12-04 08:31:45 -03:00
goto err_exit ;
2009-11-27 13:57:15 -03:00
printk ( KERN_INFO " USBVision[%d]: registered USBVision Video device %s [v4l2] \n " ,
2015-03-09 13:34:12 -03:00
usbvision - > nr , video_device_node_name ( & usbvision - > vdev ) ) ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:33:51 -03:00
/* Radio Device: */
2010-12-19 20:21:36 -03:00
if ( usbvision_device_data [ usbvision - > dev_model ] . radio ) {
2010-12-19 20:33:51 -03:00
/* usbvision has radio */
2015-03-09 13:34:12 -03:00
usbvision_vdev_init ( usbvision , & usbvision - > rdev ,
& usbvision_radio_template , " USBVision Radio " ) ;
if ( video_register_device ( & usbvision - > rdev , VFL_TYPE_RADIO , radio_nr ) < 0 )
2006-12-04 08:31:45 -03:00
goto err_exit ;
2009-11-27 13:57:15 -03:00
printk ( KERN_INFO " USBVision[%d]: registered USBVision Radio device %s [v4l2] \n " ,
2015-03-09 13:34:12 -03:00
usbvision - > nr , video_device_node_name ( & usbvision - > rdev ) ) ;
2006-12-04 08:31:45 -03:00
}
2010-12-19 20:33:51 -03:00
/* all done */
2006-12-04 08:31:45 -03:00
return 0 ;
err_exit :
2009-01-08 09:13:42 -03:00
dev_err ( & usbvision - > dev - > dev ,
" USBVision[%d]: video_register_device() failed \n " ,
usbvision - > nr ) ;
2006-12-04 08:31:45 -03:00
usbvision_unregister_video ( usbvision ) ;
2015-07-20 09:59:30 -03:00
return res ;
2006-12-04 08:31:45 -03:00
}
/*
* usbvision_alloc ( )
*
2007-05-08 17:22:29 -03:00
* This code allocates the struct usb_usbvision .
* It is filled with default values .
2006-12-04 08:31:45 -03:00
*
* Returns NULL on error , a pointer to usb_usbvision else .
*
*/
2009-04-01 08:46:00 -03:00
static struct usb_usbvision * usbvision_alloc ( struct usb_device * dev ,
struct usb_interface * intf )
2006-12-04 08:31:45 -03:00
{
struct usb_usbvision * usbvision ;
2009-02-21 18:11:31 -03:00
usbvision = kzalloc ( sizeof ( struct usb_usbvision ) , GFP_KERNEL ) ;
if ( usbvision = = NULL )
return NULL ;
2006-12-04 08:31:45 -03:00
usbvision - > dev = dev ;
2009-04-01 08:46:00 -03:00
if ( v4l2_device_register ( & intf - > dev , & usbvision - > v4l2_dev ) )
2009-02-21 18:11:31 -03:00
goto err_free ;
2006-12-04 08:31:45 -03:00
2015-07-20 09:59:29 -03:00
if ( v4l2_ctrl_handler_init ( & usbvision - > hdl , 4 ) )
goto err_unreg ;
usbvision - > v4l2_dev . ctrl_handler = & usbvision - > hdl ;
2010-12-18 11:06:09 -03:00
mutex_init ( & usbvision - > v4l2_lock ) ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:33:51 -03:00
/* prepare control urb for control messages during interrupts */
2010-12-19 20:21:36 -03:00
usbvision - > ctrl_urb = usb_alloc_urb ( USBVISION_URB_FRAMES , GFP_KERNEL ) ;
if ( usbvision - > ctrl_urb = = NULL )
2009-02-21 18:11:31 -03:00
goto err_unreg ;
2010-12-19 20:21:36 -03:00
init_waitqueue_head ( & usbvision - > ctrl_urb_wq ) ;
2006-12-04 08:31:45 -03:00
return usbvision ;
2009-02-21 18:11:31 -03:00
err_unreg :
2015-07-20 09:59:29 -03:00
v4l2_ctrl_handler_free ( & usbvision - > hdl ) ;
2009-02-21 18:11:31 -03:00
v4l2_device_unregister ( & usbvision - > v4l2_dev ) ;
err_free :
kfree ( usbvision ) ;
2006-12-04 08:31:45 -03:00
return NULL ;
}
/*
* usbvision_release ( )
*
* This code does final release of struct usb_usbvision . This happens
* after the device is disconnected - and - all clients closed their files .
*
*/
static void usbvision_release ( struct usb_usbvision * usbvision )
{
PDEBUG ( DBG_PROBE , " " ) ;
usbvision - > initialized = 0 ;
2015-03-09 13:34:12 -03:00
usbvision_remove_sysfs ( & usbvision - > vdev ) ;
2006-12-04 08:31:45 -03:00
usbvision_unregister_video ( usbvision ) ;
2013-06-10 17:32:29 -03:00
kfree ( usbvision - > alt_max_pkt_size ) ;
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
usb_free_urb ( usbvision - > ctrl_urb ) ;
2006-12-04 08:31:45 -03:00
2015-07-20 09:59:29 -03:00
v4l2_ctrl_handler_free ( & usbvision - > hdl ) ;
2009-02-21 18:11:31 -03:00
v4l2_device_unregister ( & usbvision - > v4l2_dev ) ;
2006-12-04 08:31:45 -03:00
kfree ( usbvision ) ;
PDEBUG ( DBG_PROBE , " success " ) ;
}
2007-05-08 17:22:29 -03:00
/*********************** usb interface **********************************/
2006-12-04 08:31:45 -03:00
static void usbvision_configure_video ( struct usb_usbvision * usbvision )
{
2007-05-08 17:22:29 -03:00
int model ;
2006-12-04 08:31:45 -03:00
if ( usbvision = = NULL )
return ;
2010-12-19 20:21:36 -03:00
model = usbvision - > dev_model ;
2010-12-19 20:33:51 -03:00
usbvision - > palette = usbvision_v4l2_format [ 2 ] ; /* V4L2_PIX_FMT_RGB24; */
2006-12-04 08:31:45 -03:00
2010-12-19 20:21:36 -03:00
if ( usbvision_device_data [ usbvision - > dev_model ] . vin_reg2_override ) {
usbvision - > vin_reg2_preset =
usbvision_device_data [ usbvision - > dev_model ] . vin_reg2 ;
2006-12-04 08:31:45 -03:00
} else {
2010-12-19 20:21:36 -03:00
usbvision - > vin_reg2_preset = 0 ;
2006-12-04 08:31:45 -03:00
}
2010-12-19 20:21:36 -03:00
usbvision - > tvnorm_id = usbvision_device_data [ model ] . video_norm ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:21:36 -03:00
usbvision - > video_inputs = usbvision_device_data [ model ] . video_channels ;
2006-12-04 08:31:45 -03:00
usbvision - > ctl_input = 0 ;
/* This should be here to make i2c clients to be able to register */
2007-05-08 17:22:29 -03:00
/* first switch off audio */
2011-04-27 17:36:05 -03:00
if ( usbvision_device_data [ model ] . audio_channels > 0 )
usbvision_audio_off ( usbvision ) ;
2015-07-20 09:59:28 -03:00
/* and then power up the tuner */
usbvision_power_on ( usbvision ) ;
usbvision_i2c_register ( usbvision ) ;
2006-12-04 08:31:45 -03:00
}
/*
* usbvision_probe ( )
*
* This procedure queries device descriptor and accepts the interface
* if it looks like USBVISION video device
*
*/
2012-12-21 13:17:53 -08:00
static int usbvision_probe ( struct usb_interface * intf ,
const struct usb_device_id * devid )
2006-12-04 08:31:45 -03:00
{
2007-02-07 10:14:38 -03:00
struct usb_device * dev = usb_get_dev ( interface_to_usbdev ( intf ) ) ;
struct usb_interface * uif ;
2006-12-04 08:31:45 -03:00
__u8 ifnum = intf - > altsetting - > desc . bInterfaceNumber ;
const struct usb_host_interface * interface ;
struct usb_usbvision * usbvision = NULL ;
const struct usb_endpoint_descriptor * endpoint ;
2015-03-27 19:39:09 -03:00
int model , i , ret ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_PROBE , " VID=%#04x, PID=%#04x, ifnum=%u " ,
2007-04-14 15:09:59 -03:00
dev - > descriptor . idVendor ,
dev - > descriptor . idProduct , ifnum ) ;
2007-02-07 10:14:38 -03:00
2007-04-14 15:09:59 -03:00
model = devid - > driver_info ;
2010-12-29 13:53:21 -03:00
if ( model < 0 | | model > = usbvision_device_data_size ) {
PDEBUG ( DBG_PROBE , " model out of bounds %d " , model ) ;
2015-03-27 19:39:09 -03:00
ret = - ENODEV ;
goto err_usb ;
2007-04-14 15:17:35 -03:00
}
2008-04-04 20:50:07 -03:00
printk ( KERN_INFO " %s: %s found \n " , __func__ ,
2010-12-19 20:21:36 -03:00
usbvision_device_data [ model ] . model_string ) ;
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
if ( usbvision_device_data [ model ] . interface > = 0 )
2010-12-19 20:21:36 -03:00
interface = & dev - > actconfig - > interface [ usbvision_device_data [ model ] . interface ] - > altsetting [ 0 ] ;
2010-12-29 13:53:21 -03:00
else
2006-12-04 08:31:45 -03:00
interface = & dev - > actconfig - > interface [ ifnum ] - > altsetting [ 0 ] ;
endpoint = & interface - > endpoint [ 1 ] . desc ;
2009-01-03 16:53:10 -03:00
if ( ! usb_endpoint_xfer_isoc ( endpoint ) ) {
2009-01-08 09:13:42 -03:00
dev_err ( & intf - > dev , " %s: interface %d. has non-ISO endpoint! \n " ,
2008-04-04 20:50:07 -03:00
__func__ , ifnum ) ;
2009-01-08 09:13:42 -03:00
dev_err ( & intf - > dev , " %s: Endpoint attributes %d " ,
2008-04-04 20:50:07 -03:00
__func__ , endpoint - > bmAttributes ) ;
2015-03-27 19:39:09 -03:00
ret = - ENODEV ;
goto err_usb ;
2006-12-04 08:31:45 -03:00
}
2008-12-29 21:49:22 -03:00
if ( usb_endpoint_dir_out ( endpoint ) ) {
2009-01-08 09:13:42 -03:00
dev_err ( & intf - > dev , " %s: interface %d. has ISO OUT endpoint! \n " ,
2008-04-04 20:50:07 -03:00
__func__ , ifnum ) ;
2015-03-27 19:39:09 -03:00
ret = - ENODEV ;
goto err_usb ;
2006-12-04 08:31:45 -03:00
}
2009-04-01 08:46:00 -03:00
usbvision = usbvision_alloc ( dev , intf ) ;
if ( usbvision = = NULL ) {
2009-01-08 09:13:42 -03:00
dev_err ( & intf - > dev , " %s: couldn't allocate USBVision struct \n " , __func__ ) ;
2015-03-27 19:39:09 -03:00
ret = - ENOMEM ;
goto err_usb ;
2006-12-04 08:31:45 -03:00
}
2007-04-14 15:09:59 -03:00
2010-12-29 13:53:21 -03:00
if ( dev - > descriptor . bNumConfigurations > 1 )
2010-12-19 20:21:36 -03:00
usbvision - > bridge_type = BRIDGE_NT1004 ;
2010-12-29 13:53:21 -03:00
else if ( model = = DAZZLE_DVC_90_REV_1_SECAM )
2010-12-19 20:21:36 -03:00
usbvision - > bridge_type = BRIDGE_NT1005 ;
2010-12-29 13:53:21 -03:00
else
2010-12-19 20:21:36 -03:00
usbvision - > bridge_type = BRIDGE_NT1003 ;
PDEBUG ( DBG_PROBE , " bridge_type %d " , usbvision - > bridge_type ) ;
2006-12-04 08:31:45 -03:00
2007-02-07 10:14:38 -03:00
/* compute alternate max packet sizes */
uif = dev - > actconfig - > interface [ 0 ] ;
2010-12-29 13:53:21 -03:00
usbvision - > num_alt = uif - > num_altsetting ;
PDEBUG ( DBG_PROBE , " Alternate settings: %i " , usbvision - > num_alt ) ;
usbvision - > alt_max_pkt_size = kmalloc ( 32 * usbvision - > num_alt , GFP_KERNEL ) ;
2007-02-07 10:14:38 -03:00
if ( usbvision - > alt_max_pkt_size = = NULL ) {
2009-01-08 09:13:42 -03:00
dev_err ( & intf - > dev , " usbvision: out of memory! \n " ) ;
2015-03-27 19:39:09 -03:00
ret = - ENOMEM ;
goto err_pkt ;
2007-02-07 10:14:38 -03:00
}
2010-12-29 13:53:21 -03:00
for ( i = 0 ; i < usbvision - > num_alt ; i + + ) {
2007-02-07 10:14:38 -03:00
u16 tmp = le16_to_cpu ( uif - > altsetting [ i ] . endpoint [ 1 ] . desc .
wMaxPacketSize ) ;
usbvision - > alt_max_pkt_size [ i ] =
( tmp & 0x07ff ) * ( ( ( tmp & 0x1800 ) > > 11 ) + 1 ) ;
2010-12-29 13:53:21 -03:00
PDEBUG ( DBG_PROBE , " Alternate setting %i, max size= %i " , i ,
2007-02-07 10:14:38 -03:00
usbvision - > alt_max_pkt_size [ i ] ) ;
}
2006-12-04 08:31:45 -03:00
usbvision - > nr = usbvision_nr + + ;
2010-12-19 20:21:36 -03:00
usbvision - > have_tuner = usbvision_device_data [ model ] . tuner ;
2010-12-29 13:53:21 -03:00
if ( usbvision - > have_tuner )
2010-12-19 20:21:36 -03:00
usbvision - > tuner_type = usbvision_device_data [ model ] . tuner_type ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:21:36 -03:00
usbvision - > dev_model = model ;
2006-12-04 08:31:45 -03:00
usbvision - > remove_pending = 0 ;
usbvision - > iface = ifnum ;
2010-12-19 20:21:36 -03:00
usbvision - > iface_alt = 0 ;
2006-12-04 08:31:45 -03:00
usbvision - > video_endp = endpoint - > bEndpointAddress ;
2010-12-19 20:21:36 -03:00
usbvision - > isoc_packet_size = 0 ;
2006-12-04 08:31:45 -03:00
usbvision - > usb_bandwidth = 0 ;
usbvision - > user = 0 ;
2010-12-19 20:21:36 -03:00
usbvision - > streaming = stream_off ;
2006-12-04 08:31:45 -03:00
usbvision_configure_video ( usbvision ) ;
2010-09-17 15:07:28 -03:00
usbvision_register_video ( usbvision ) ;
2006-12-04 08:31:45 -03:00
2015-03-09 13:34:12 -03:00
usbvision_create_sysfs ( & usbvision - > vdev ) ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_PROBE , " success " ) ;
return 0 ;
2015-03-27 19:39:09 -03:00
err_pkt :
usbvision_release ( usbvision ) ;
err_usb :
usb_put_dev ( dev ) ;
return ret ;
2006-12-04 08:31:45 -03:00
}
/*
* usbvision_disconnect ( )
*
* This procedure stops all driver activity , deallocates interface - private
* structure ( pointed by ' ptr ' ) and after that driver should be removable
* with no ill consequences .
*
*/
2012-12-21 13:17:53 -08:00
static void usbvision_disconnect ( struct usb_interface * intf )
2006-12-04 08:31:45 -03:00
{
2010-05-02 09:00:13 -03:00
struct usb_usbvision * usbvision = to_usbvision ( usb_get_intfdata ( intf ) ) ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_PROBE , " " ) ;
if ( usbvision = = NULL ) {
2010-05-27 09:36:45 -03:00
pr_err ( " %s: usb_get_intfdata() failed \n " , __func__ ) ;
2006-12-04 08:31:45 -03:00
return ;
}
2010-12-18 11:06:09 -03:00
mutex_lock ( & usbvision - > v4l2_lock ) ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:33:51 -03:00
/* At this time we ask to cancel outstanding URBs */
2006-12-04 08:31:45 -03:00
usbvision_stop_isoc ( usbvision ) ;
2009-03-14 12:27:01 -03:00
v4l2_device_disconnect ( & usbvision - > v4l2_dev ) ;
2015-07-20 09:59:28 -03:00
usbvision_i2c_unregister ( usbvision ) ;
2010-12-19 20:33:51 -03:00
usbvision - > remove_pending = 1 ; /* Now all ISO data will be ignored */
2006-12-04 08:31:45 -03:00
usb_put_dev ( usbvision - > dev ) ;
2010-12-19 20:33:51 -03:00
usbvision - > dev = NULL ; /* USB device is no more */
2006-12-04 08:31:45 -03:00
2010-12-18 11:06:09 -03:00
mutex_unlock ( & usbvision - > v4l2_lock ) ;
2006-12-04 08:31:45 -03:00
if ( usbvision - > user ) {
2007-05-08 17:22:29 -03:00
printk ( KERN_INFO " %s: In use, disconnect pending \n " ,
2008-04-04 20:50:07 -03:00
__func__ ) ;
2006-12-04 08:31:45 -03:00
wake_up_interruptible ( & usbvision - > wait_frame ) ;
wake_up_interruptible ( & usbvision - > wait_stream ) ;
2007-05-08 17:22:29 -03:00
} else {
2006-12-04 08:31:45 -03:00
usbvision_release ( usbvision ) ;
}
PDEBUG ( DBG_PROBE , " success " ) ;
}
static struct usb_driver usbvision_driver = {
. name = " usbvision " ,
. id_table = usbvision_table ,
. probe = usbvision_probe ,
2012-12-21 13:17:53 -08:00
. disconnect = usbvision_disconnect ,
2006-12-04 08:31:45 -03:00
} ;
/*
* usbvision_init ( )
*
* This code is run to initialize the driver .
*
*/
static int __init usbvision_init ( void )
{
2010-12-19 20:21:36 -03:00
int err_code ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_PROBE , " " ) ;
PDEBUG ( DBG_IO , " IO debugging is enabled [video] " ) ;
PDEBUG ( DBG_PROBE , " PROBE debugging is enabled [video] " ) ;
2006-12-09 16:42:54 -03:00
PDEBUG ( DBG_MMAP , " MMAP debugging is enabled [video] " ) ;
2006-12-04 08:31:45 -03:00
/* disable planar mode support unless compression enabled */
2010-12-29 13:53:21 -03:00
if ( isoc_mode ! = ISOC_MODE_COMPRESS ) {
2010-12-19 20:33:51 -03:00
/* FIXME : not the right way to set supported flag */
usbvision_v4l2_format [ 6 ] . supported = 0 ; /* V4L2_PIX_FMT_YVU420 */
usbvision_v4l2_format [ 7 ] . supported = 0 ; /* V4L2_PIX_FMT_YUV422P */
2006-12-04 08:31:45 -03:00
}
2010-12-19 20:21:36 -03:00
err_code = usb_register ( & usbvision_driver ) ;
2006-12-04 08:31:45 -03:00
2010-12-19 20:21:36 -03:00
if ( err_code = = 0 ) {
2007-01-07 21:13:55 -03:00
printk ( KERN_INFO DRIVER_DESC " : " USBVISION_VERSION_STRING " \n " ) ;
2006-12-04 08:31:45 -03:00
PDEBUG ( DBG_PROBE , " success " ) ;
}
2010-12-19 20:21:36 -03:00
return err_code ;
2006-12-04 08:31:45 -03:00
}
static void __exit usbvision_exit ( void )
{
2010-12-29 13:53:21 -03:00
PDEBUG ( DBG_PROBE , " " ) ;
2006-12-04 08:31:45 -03:00
2010-12-29 13:53:21 -03:00
usb_deregister ( & usbvision_driver ) ;
PDEBUG ( DBG_PROBE , " success " ) ;
2006-12-04 08:31:45 -03:00
}
module_init ( usbvision_init ) ;
module_exit ( usbvision_exit ) ;