--- linux-2.4.15-pre6/kernel/ksyms.c	Mon Nov 19 10:47:15 2001
+++ linux/kernel/ksyms.c	Mon Nov 19 11:41:21 2001
@@ -267,6 +267,7 @@
 EXPORT_SYMBOL(lock_may_read);
 EXPORT_SYMBOL(lock_may_write);
 EXPORT_SYMBOL(dcache_readdir);
+EXPORT_SYMBOL(do_select);
 
 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
 EXPORT_SYMBOL(default_llseek);
--- linux-2.4.15-pre6/include/linux/videodev2.h	Mon Nov 19 11:41:21 2001
+++ linux/include/linux/videodev2.h	Mon Nov 19 11:41:21 2001
@@ -0,0 +1,918 @@
+#ifndef __LINUX_VIDEODEV2_H
+#define __LINUX_VIDEODEV2_H
+/*
+ *	Video for Linux Two
+ *
+ *	Header file for v4l or V4L2 drivers and applications, for
+ *	Linux kernels 2.2.x or 2.4.x.
+ *
+ *	See http://www.thedirks.org/v4l2/ for API specs and other
+ *	v4l2 documentation.
+ *
+ *	Author: Bill Dirks <bdirks@pacbell.net>
+ *		Justin Schoeman
+ *		et al.
+ */
+
+#define V4L2_MAJOR_VERSION	0
+#define V4L2_MINOR_VERSION	20
+
+
+/*
+ *	M I S C E L L A N E O U S
+ */
+
+/*  Four-character-code (FOURCC) */
+#define v4l2_fourcc(a,b,c,d)\
+        (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+
+/*  Open flag for non-capturing opens on capture devices  */
+#define O_NONCAP	O_TRUNC
+#define O_NOIO		O_TRUNC
+
+/*  Timestamp data type, 64-bit signed integer, in nanoseconds  */
+#ifndef STAMP_T
+#define STAMP_T
+typedef __s64 stamp_t;
+#endif
+
+/*
+ *	D R I V E R   C A P A B I L I T I E S
+ */
+struct v4l2_capability
+{
+	char	name[32];	/* Descriptive, and unique */
+	int	type;		/* Device type, see below */
+	int	inputs;		/* Num video inputs */
+	int	outputs;	/* Num video outputs */
+	int	audios;		/* Num audio devices */
+	int	maxwidth;
+	int	maxheight;
+	int	minwidth;
+	int	minheight;
+	int	maxframerate;
+	__u32	flags;		/* Feature flags, see below */
+	__u32	reserved[4];
+};
+/* Values for 'type' field */
+#define V4L2_TYPE_CAPTURE	0	/* Is a video capture device */
+#define V4L2_TYPE_CODEC		1	/* Is a CODEC device */
+#define V4L2_TYPE_OUTPUT	2	/* Is a video output device */
+#define V4L2_TYPE_FX		3	/* Is a video effects device */
+#define V4L2_TYPE_VBI		4	/* Is a VBI capture device */
+#define V4L2_TYPE_VTR		5	/* Is a tape recorder controller */
+#define V4L2_TYPE_VTX		6	/* Is a teletext device */
+#define V4L2_TYPE_RADIO		7	/* Is a radio device */
+#define V4L2_TYPE_VBI_INPUT	4	/* Is a VBI capture device */
+#define V4L2_TYPE_VBI_OUTPUT	9	/* Is a VBI output device */
+#define V4L2_TYPE_PRIVATE	1000	/* Start of driver private types */
+/* Flags for 'flags' field */
+#define V4L2_FLAG_READ		0x00001 /* Can capture via read() call */
+#define V4L2_FLAG_WRITE		0x00002 /* Can accept data via write() */
+#define V4L2_FLAG_STREAMING	0x00004 /* Can capture streaming video */
+#define V4L2_FLAG_PREVIEW	0x00008 /* Can do automatic preview */
+#define V4L2_FLAG_SELECT	0x00010 /* Supports the select() call */
+#define V4L2_FLAG_TUNER		0x00020 /* Can tune */
+#define V4L2_FLAG_MONOCHROME	0x00040 /* Monochrome only */
+#define V4L2_FLAG_DATA_SERVICE	0x00080 /* Has a related data service dev. */
+
+
+/*
+ *	V I D E O   I M A G E   F O R M A T
+ */
+struct v4l2_pix_format
+{
+	__u32	width;
+	__u32	height;
+	__u32	depth;
+	__u32	pixelformat;
+	__u32	flags;
+	__u32	bytesperline;	/* only used when there are pad bytes */
+	__u32	sizeimage;
+	__u32	priv;		/* private data, depends on pixelformat */
+};
+/*           Pixel format    FOURCC                  depth  Description   */
+#define V4L2_PIX_FMT_RGB332  v4l2_fourcc('R','G','B','1') /*  8  RGB-3-3-2     */
+#define V4L2_PIX_FMT_RGB555  v4l2_fourcc('R','G','B','O') /* 16  RGB-5-5-5     */
+#define V4L2_PIX_FMT_RGB565  v4l2_fourcc('R','G','B','P') /* 16  RGB-5-6-5     */
+#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16  RGB-5-5-5 BE  */
+#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16  RGB-5-6-5 BE  */
+#define V4L2_PIX_FMT_BGR24   v4l2_fourcc('B','G','R','3') /* 24  BGR-8-8-8     */
+#define V4L2_PIX_FMT_RGB24   v4l2_fourcc('R','G','B','3') /* 24  RGB-8-8-8     */
+#define V4L2_PIX_FMT_BGR32   v4l2_fourcc('B','G','R','4') /* 32  BGR-8-8-8-8   */
+#define V4L2_PIX_FMT_RGB32   v4l2_fourcc('R','G','B','4') /* 32  RGB-8-8-8-8   */
+#define V4L2_PIX_FMT_GREY    v4l2_fourcc('G','R','E','Y') /*  8  Greyscale     */
+#define V4L2_PIX_FMT_YVU410  v4l2_fourcc('Y','V','U','9') /*  9  YVU 4:1:0     */
+#define V4L2_PIX_FMT_YVU420  v4l2_fourcc('Y','V','1','2') /* 12  YVU 4:2:0     */
+#define V4L2_PIX_FMT_YUYV    v4l2_fourcc('Y','U','Y','V') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_UYVY    v4l2_fourcc('U','Y','V','Y') /* 16  YUV 4:2:2     */
+#if 0
+#define V4L2_PIX_FMT_YVU422P v4l2_fourcc('4','2','2','P') /* 16  YVU422 planar */
+#define V4L2_PIX_FMT_YVU411P v4l2_fourcc('4','1','1','P') /* 16  YVU411 planar */
+#endif
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16  YVU422 planar */
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16  YVU411 planar */
+#define V4L2_PIX_FMT_Y41P    v4l2_fourcc('Y','4','1','P') /* 12  YUV 4:1:1     */
+
+/* two planes -- one Y, one Cr + Cb interleaved  */
+#define V4L2_PIX_FMT_NV12    v4l2_fourcc('N','V','1','2') /* 12  Y/CbCr 4:2:0  */
+#define V4L2_PIX_FMT_NV21    v4l2_fourcc('N','V','2','1') /* 12  Y/CrCb 4:2:0  */
+
+/*  The following formats are not defined in the V4L2 specification */
+#define V4L2_PIX_FMT_YUV410  v4l2_fourcc('Y','U','V','9') /*  9  YUV 4:1:0     */
+#define V4L2_PIX_FMT_YUV420  v4l2_fourcc('Y','U','1','2') /* 12  YUV 4:2:0     */
+#define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y','Y','U','V') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_HI240   v4l2_fourcc('H','I','2','4') /*  8  8-bit color   */
+
+/*  Vendor-specific formats   */
+#define V4L2_PIX_FMT_WNVA    v4l2_fourcc('W','N','V','A') /* Winnov hw compres */
+
+
+/*  Flags */
+#define V4L2_FMT_FLAG_COMPRESSED	0x0001	/* Compressed format */
+#define V4L2_FMT_FLAG_BYTESPERLINE	0x0002	/* bytesperline field valid */
+#define V4L2_FMT_FLAG_NOT_INTERLACED	0x0000
+#define V4L2_FMT_FLAG_INTERLACED	0x0004	/* Image is interlaced */
+#define V4L2_FMT_FLAG_TOPFIELD		0x0008	/* is a top field only */
+#define V4L2_FMT_FLAG_BOTFIELD		0x0010	/* is a bottom field only */
+#define V4L2_FMT_FLAG_ODDFIELD		V4L2_FMT_FLAG_TOPFIELD
+#define V4L2_FMT_FLAG_EVENFIELD		V4L2_FMT_FLAG_BOTFIELD
+#define V4L2_FMT_FLAG_COMBINED		V4L2_FMT_FLAG_INTERLACED
+#define V4L2_FMT_FLAG_FIELD_field	0x001C
+#define V4L2_FMT_CS_field		0xF000	/* Color space field mask */
+#define V4L2_FMT_CS_601YUV		0x1000	/* ITU YCrCb color space */
+#define V4L2_FMT_FLAG_SWCONVERSION	0x0800	/* used only in format enum. */
+/*  SWCONVERSION indicates the format is not natively supported by the  */
+/*  driver and the driver uses software conversion to support it  */
+
+
+/*
+ *	F O R M A T   E N U M E R A T I O N
+ */
+struct v4l2_fmtdesc
+{
+	int	index;			/* Format number */
+	char	description[32];	/* Description string */
+	__u32	pixelformat;		/* Format fourcc */
+	__u32	flags;			/* Format flags */
+	__u32	depth;			/* Bits per pixel */
+	__u32	reserved[2];
+};
+
+struct v4l2_cvtdesc
+{
+	int	index;
+	struct
+	{
+		__u32	pixelformat;
+		__u32	flags;
+		__u32	depth;
+		__u32	reserved[2];
+	}	in, out;
+};
+
+struct v4l2_fxdesc
+{
+	int	index;
+	char 	name[32];
+	__u32	flags;
+	__u32	inputs;
+	__u32	controls;
+	__u32	reserved[2];
+};
+
+
+/*
+ *	T I M E C O D E
+ */
+struct v4l2_timecode
+{
+	__u8	frames;
+	__u8	seconds;
+	__u8	minutes;
+	__u8	hours;
+	__u8	userbits[4];
+	__u32	flags;
+	__u32	type;
+};
+/*  Type  */
+#define V4L2_TC_TYPE_24FPS		1
+#define V4L2_TC_TYPE_25FPS		2
+#define V4L2_TC_TYPE_30FPS		3
+#define V4L2_TC_TYPE_50FPS		4
+#define V4L2_TC_TYPE_60FPS		5
+
+
+/*  Flags  */
+#define V4L2_TC_FLAG_DROPFRAME		0x0001 /* "drop-frame" mode */
+#define V4L2_TC_FLAG_COLORFRAME		0x0002
+#define V4L2_TC_USERBITS_field		0x000C
+#define V4L2_TC_USERBITS_USERDEFINED	0x0000
+#define V4L2_TC_USERBITS_8BITCHARS	0x0008
+/* The above is based on SMPTE timecodes */
+
+
+/*
+ *	C O M P R E S S I O N   P A R A M E T E R S
+ */
+struct v4l2_compression
+{
+	int	quality;
+	int	keyframerate;
+	int	pframerate;
+	__u32	reserved[5];
+};
+
+
+/*
+ *	M E M O R Y - M A P P I N G   B U F F E R S
+ */
+struct v4l2_requestbuffers
+{
+	int	count;
+	__u32	type;
+	__u32	reserved[2];
+};
+struct v4l2_buffer
+{
+	int			index;
+	__u32			type;
+	__u32			offset;
+	__u32			length;
+	__u32			bytesused;
+	__u32			flags;
+	stamp_t			timestamp;
+	struct v4l2_timecode	timecode;
+	__u32			sequence;
+	__u32			reserved[3];
+};
+/*  Buffer type codes and flags for 'type' field */
+#define V4L2_BUF_TYPE_field		0x00001FFF  /* Type field mask  */
+#define V4L2_BUF_TYPE_CAPTURE		0x00000001
+#define V4L2_BUF_TYPE_CODECIN		0x00000002
+#define V4L2_BUF_TYPE_CODECOUT		0x00000003
+#define V4L2_BUF_TYPE_EFFECTSIN		0x00000004
+#define V4L2_BUF_TYPE_EFFECTSIN2	0x00000005
+#define V4L2_BUF_TYPE_EFFECTSOUT	0x00000006
+#define V4L2_BUF_TYPE_VIDEOOUT		0x00000007
+#define V4L2_BUF_TYPE_FXCONTROL		0x00000008
+#define V4L2_BUF_TYPE_VBI		0x00000009
+
+/*  Starting value of driver private buffer types  */
+#define V4L2_BUF_TYPE_PRIVATE		0x00001000
+
+#define V4L2_BUF_ATTR_DEVICEMEM	0x00010000  /* Buffer is on device (flag) */
+
+/*  Flags used only in VIDIOC_REQBUFS  */
+#define V4L2_BUF_REQ_field	0xF0000000
+#define V4L2_BUF_REQ_CONTIG	0x10000000  /* Map all buffers in one
+					       contiguous mmap(). This flag
+					       only used in VIDIOC_REQBUFS */
+
+/*  Flags for 'flags' field */
+#define V4L2_BUF_FLAG_MAPPED	0x0001  /* Buffer is mapped (flag) */
+#define V4L2_BUF_FLAG_QUEUED	0x0002	/* Buffer is queued for processing */
+#define V4L2_BUF_FLAG_DONE	0x0004	/* Buffer is ready */
+#define V4L2_BUF_FLAG_KEYFRAME	0x0008	/* Image is a keyframe (I-frame) */
+#define V4L2_BUF_FLAG_PFRAME	0x0010	/* Image is a P-frame */
+#define V4L2_BUF_FLAG_BFRAME	0x0020	/* Image is a B-frame */
+#define V4L2_BUF_FLAG_TOPFIELD	0x0040	/* Image is a top field only */
+#define V4L2_BUF_FLAG_BOTFIELD	0x0080	/* Image is a bottom field only */
+#define V4L2_BUF_FLAG_ODDFIELD	V4L2_BUF_FLAG_TOPFIELD
+#define V4L2_BUF_FLAG_EVENFIELD	V4L2_BUF_FLAG_BOTFIELD
+#define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
+
+/*
+ *	O V E R L A Y   P R E V I E W
+ */
+struct v4l2_framebuffer
+{
+	__u32			capability;
+	__u32			flags;
+	void			*base[3];
+	struct v4l2_pix_format	fmt;
+};
+/*  Flags for the 'capability' field. Read only */
+#define V4L2_FBUF_CAP_EXTERNOVERLAY	0x0001
+#define V4L2_FBUF_CAP_CHROMAKEY		0x0002
+#define V4L2_FBUF_CAP_CLIPPING		0x0004
+#define V4L2_FBUF_CAP_SCALEUP		0x0008
+#define V4L2_FBUF_CAP_SCALEDOWN		0x0010
+#define V4L2_FBUF_CAP_BITMAP_CLIPPING	0x0020
+/*  Flags for the 'flags' field. */
+#define V4L2_FBUF_FLAG_PRIMARY		0x0001
+#define V4L2_FBUF_FLAG_OVERLAY		0x0002
+#define V4L2_FBUF_FLAG_CHROMAKEY	0x0004
+
+struct v4l2_clip
+{
+	int			x;
+	int			y;
+	int			width;
+	int			height;
+	struct v4l2_clip	*next;
+};
+struct v4l2_window
+{
+	int			x;
+	int			y;
+	int			width;
+	int			height;
+	__u32			chromakey;
+	struct v4l2_clip	*clips;
+	int			clipcount;
+	void			*bitmap;
+};
+
+
+/*
+ *	D E V I C E   P E R F O R M A N C E
+ */
+struct v4l2_performance
+{
+	int	frames;
+	int	framesdropped;
+	__u64	bytesin;
+	__u64	bytesout;
+	__u32	reserved[4];
+};
+
+/*
+ *	C A P T U R E   P A R A M E T E R S
+ */
+struct v4l2_captureparm
+{
+	__u32		capability;	/*  Supported modes */
+	__u32		capturemode;	/*  Current mode */
+	unsigned long	timeperframe;	/*  Time per frame in .1us units */
+	__u32		extendedmode;	/*  Driver-specific extensions */
+	__u32		reserved[4];
+};
+/*  Flags for 'capability' and 'capturemode' fields */
+#define V4L2_MODE_HIGHQUALITY	0x0001	/*  High quality imaging mode */
+//#define V4L2_MODE_VFLIP		0x0002	/*  Flip image vertically */
+//#define V4L2_MODE_HFLIP		0x0004	/*  Flip image horizontally */
+#define V4L2_CAP_TIMEPERFRAME	0x1000	/*  timeperframe field is supported */
+
+struct v4l2_outputparm
+{
+	__u32		capability;	/*  Supported modes */
+	__u32		outputmode;	/*  Current mode */
+	unsigned long	timeperframe;	/*  Time per frame in .1us units */
+	__u32		extendedmode;	/*  Driver-specific extensions */
+	__u32		reserved[4];
+};
+
+/*
+ *	I N P U T   I M A G E   C R O P P I N G
+ */
+struct v4l2_cropcap
+{
+	__u32	capability;
+	int	min_x;
+	int	min_y;
+	int	max_x;
+	int	max_y;
+	int	default_left;
+	int	default_top;
+	int	default_right;
+	int	default_bottom;
+	__u32	reserved[2];
+};
+struct v4l2_crop
+{
+	int	left;
+	int	top;
+	int	right;
+	int	bottom;
+	__u32	reserved;
+};
+
+/*
+ *	D I G I T A L   Z O O M
+ */
+struct v4l2_zoomcap
+{
+	__u32	capability;
+	__u32	maxwidth;
+	__u32	maxheight;
+	__u32	minwidth;
+	__u32	minheight;
+	__u32	reserved[2];
+};
+/*  Flags for the capability field  */
+#define V4L2_ZOOM_NONCAP		0x0001
+#define V4L2_ZOOM_WHILESTREAMING	0x0002
+
+struct v4l2_zoom
+{
+	__u32	x;
+	__u32	y;
+	__u32	width;
+	__u32	height;
+	__u32	reserved;
+};
+
+
+/*
+ *      A N A L O G   V I D E O   S T A N D A R D
+ */
+struct v4l2_standard
+{
+	__u8		name[24];
+	struct {
+		__u32	numerator;
+		__u32	denominator;	/* >= 1 */
+	} framerate;			/* Frames, not fields */
+	__u32		framelines;
+	__u32		reserved1;
+	__u32		colorstandard;
+	union {				
+		struct {
+			__u32		colorsubcarrier; /* Hz */
+		} 		pal;
+		struct {					
+			__u32		colorsubcarrier; /* Hz */
+		} 		ntsc;
+		struct {
+			__u32		f0b;	/* Hz (blue) */
+			__u32		f0r;	/* Hz (red)  */
+		} 		secam;
+		__u8		reserved[12];
+	} colorstandard_data;
+	__u32		transmission;	/* Bit field. Must be zero for
+					   non-modulators/demodulators. */
+	__u32		reserved2;	/* Must be set to zero */
+};
+
+/*  Values for the 'colorstandard' field  */
+#define V4L2_COLOR_STD_PAL		1
+#define V4L2_COLOR_STD_NTSC		2
+#define V4L2_COLOR_STD_SECAM		3
+
+/*  Values for the color subcarrier fields  */
+#define V4L2_COLOR_SUBC_PAL	4433619		/* PAL BGHI, NTSC-44 */
+#define V4L2_COLOR_SUBC_PAL_M	3575611		/* PAL M (Brazil) */
+#define V4L2_COLOR_SUBC_PAL_N	3582056		/* PAL N */
+#define V4L2_COLOR_SUBC_NTSC	3579545		/* NTSC M, NTSC-Japan */
+#define V4L2_COLOR_SUBC_SECAMB	4250000		/* SECAM B - Y carrier */
+#define V4L2_COLOR_SUBC_SECAMR	4406250		/* SECAM R - Y carrier */
+
+/*  Flags for the 'transmission' field  */
+#define V4L2_TRANSM_STD_B		(1<<1)
+#define V4L2_TRANSM_STD_D		(1<<3)
+#define V4L2_TRANSM_STD_G		(1<<6)
+#define V4L2_TRANSM_STD_H		(1<<7)
+#define V4L2_TRANSM_STD_I		(1<<8)
+#define V4L2_TRANSM_STD_K		(1<<10)
+#define V4L2_TRANSM_STD_K1		(1<<11)
+#define V4L2_TRANSM_STD_L		(1<<12)
+#define V4L2_TRANSM_STD_M		(1<<13)
+#define V4L2_TRANSM_STD_N		(1<<14)
+
+
+/*  Used in the VIDIOC_ENUMSTD ioctl for querying supported standards  */
+struct v4l2_enumstd
+{
+	int			index;
+	struct v4l2_standard	std;
+	__u32			inputs;  /* set of inputs that */
+					 /* support this standard */
+	__u32			outputs; /* set of outputs that */
+					 /* support this standard */
+	__u32			reserved[2];
+};
+
+
+/*
+ *	V I D E O   I N P U T S
+ */
+struct v4l2_input
+{
+	int	index;		/*  Which input */
+	char	name[32];	/*  Label */
+	int	type;		/*  Type of input */
+	__u32	capability;	/*  Capability flags */
+	int	assoc_audio;	/*  Associated audio input */
+	__u32	reserved[4];
+};
+/*  Values for the 'type' field */
+#define V4L2_INPUT_TYPE_TUNER		1
+#define V4L2_INPUT_TYPE_CAMERA		2
+
+/*  Flags for the 'capability' field */
+#define V4L2_INPUT_CAP_AUDIO		0x0001	/* assoc_audio */
+
+
+/*
+ *	V I D E O   O U T P U T S
+ */
+struct v4l2_output
+{
+	int	index;		/*  Which output */
+	char	name[32];	/*  Label */
+	int	type;		/*  Type of output */
+	__u32	capability;	/*  Capability flags */
+	int	assoc_audio;	/*  Associated audio */
+	__u32	reserved[4];
+};
+/*  Values for the 'type' field */
+#define V4L2_OUTPUT_TYPE_MODULATOR		1
+#define V4L2_OUTPUT_TYPE_ANALOG			2
+#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY	3
+
+/*  Flags for the 'capability' field */
+#define V4L2_OUTPUT_CAP_AUDIO		0x0001	/* assoc_audio */
+
+
+/*
+ *	C O N T R O L S
+ */
+struct v4l2_control
+{
+	__u32		id;
+	int		value;
+};
+
+/*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
+struct v4l2_queryctrl
+{
+	__u32		id;
+	__u8		name[32];	/* Whatever */
+	int		minimum;	/* Note signedness */
+	int		maximum;
+	unsigned int	step;
+	int		default_value;
+	__u32		type;
+	__u32		flags;
+	__u32		category;	/* Automatically filled in by V4L2 */
+	__u8		group[32];	/*   for pre-defined controls      */
+	__u32		reserved[2];
+};
+
+/*  Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
+struct v4l2_querymenu
+{
+	__u32		id;
+	int		index;
+	__u8		name[32];	/* Whatever */
+	int		reserved;
+};
+
+/*  Used in V4L2_BUF_TYPE_FXCONTROL buffers  */
+struct v4l2_fxcontrol
+{
+	__u32	id;
+	__u32	value;
+};
+
+/*  Control types  */
+#define V4L2_CTRL_TYPE_INTEGER		0
+#define V4L2_CTRL_TYPE_BOOLEAN		1
+#define V4L2_CTRL_TYPE_MENU		2
+#define V4L2_CTRL_TYPE_BUTTON		3
+
+/*  Control flags  */
+#define V4L2_CTRL_FLAG_DISABLED		0x0001
+#define V4L2_CTRL_FLAG_GRABBED		0x0002
+
+/*  Control categories	*/
+#define V4L2_CTRL_CAT_VIDEO		1  /*  "Video"   */
+#define V4L2_CTRL_CAT_AUDIO		2  /*  "Audio"   */
+#define V4L2_CTRL_CAT_EFFECT		3  /*  "Effect"  */
+
+/*  Control IDs defined by V4L2 */
+#define V4L2_CID_BASE			0x00980900
+/*  IDs reserved for driver specific controls */
+#define V4L2_CID_PRIVATE_BASE		0x08000000
+/*  IDs reserved for effect-specific controls on effects devices  */
+#define V4L2_CID_EFFECT_BASE		0x0A00B000
+
+#define V4L2_CID_BRIGHTNESS		(V4L2_CID_BASE+0)
+#define V4L2_CID_CONTRAST		(V4L2_CID_BASE+1)
+#define V4L2_CID_SATURATION		(V4L2_CID_BASE+2)
+#define V4L2_CID_HUE			(V4L2_CID_BASE+3)
+#define V4L2_CID_AUDIO_VOLUME		(V4L2_CID_BASE+5)
+#define V4L2_CID_AUDIO_BALANCE		(V4L2_CID_BASE+6)
+#define V4L2_CID_AUDIO_BASS		(V4L2_CID_BASE+7)
+#define V4L2_CID_AUDIO_TREBLE		(V4L2_CID_BASE+8)
+#define V4L2_CID_AUDIO_MUTE		(V4L2_CID_BASE+9)
+#define V4L2_CID_AUDIO_LOUDNESS		(V4L2_CID_BASE+10)
+#define V4L2_CID_BLACK_LEVEL		(V4L2_CID_BASE+11)
+#define V4L2_CID_AUTO_WHITE_BALANCE	(V4L2_CID_BASE+12)
+#define V4L2_CID_DO_WHITE_BALANCE	(V4L2_CID_BASE+13)
+#define V4L2_CID_RED_BALANCE		(V4L2_CID_BASE+14)
+#define V4L2_CID_BLUE_BALANCE		(V4L2_CID_BASE+15)
+#define V4L2_CID_GAMMA			(V4L2_CID_BASE+16)
+#define V4L2_CID_WHITENESS		(V4L2_CID_GAMMA) /* ? Not sure */
+#define V4L2_CID_EXPOSURE		(V4L2_CID_BASE+17)
+#define V4L2_CID_AUTOGAIN		(V4L2_CID_BASE+18)
+#define V4L2_CID_GAIN			(V4L2_CID_BASE+19)
+#define V4L2_CID_HFLIP			(V4L2_CID_BASE+20)
+#define V4L2_CID_VFLIP			(V4L2_CID_BASE+21)
+#define V4L2_CID_HCENTER		(V4L2_CID_BASE+22)
+#define V4L2_CID_VCENTER		(V4L2_CID_BASE+23)
+#define V4L2_CID_LASTP1			(V4L2_CID_BASE+24) /* last CID + 1 */
+/*  Remember to change fill_ctrl_category() in videodev.c  */
+
+/*
+ *	T U N I N G
+ */
+struct v4l2_tuner
+{
+	int			input;
+	char			name[32];
+	struct v4l2_standard	std;
+	__u32			capability;
+	__u32			rangelow;
+	__u32			rangehigh;
+	__u32			rxsubchans;
+	__u32			audmode;
+	int			signal;
+	int			afc;
+	__u32			reserved[4];
+};
+struct v4l2_modulator
+{
+	int			output;
+	char			name[32];
+	struct v4l2_standard	std;
+	__u32			capability;
+	__u32			rangelow;
+	__u32			rangehigh;
+	__u32			txsubchans;
+	__u32			reserved[4];
+};
+/*  Flags for the 'capability' field */
+#define V4L2_TUNER_CAP_LOW		0x0001
+#define V4L2_TUNER_CAP_NORM		0x0002
+#define V4L2_TUNER_CAP_STEREO		0x0010
+#define V4L2_TUNER_CAP_LANG2		0x0020
+#define V4L2_TUNER_CAP_SAP		0x0020
+#define V4L2_TUNER_CAP_LANG1		0x0040
+
+/*  Flags for the 'rxsubchans' field */
+#define V4L2_TUNER_SUB_MONO		0x0001
+#define V4L2_TUNER_SUB_STEREO		0x0002
+#define V4L2_TUNER_SUB_LANG2		0x0004
+#define V4L2_TUNER_SUB_SAP		0x0004
+#define V4L2_TUNER_SUB_LANG1		0x0008
+
+/*  Values for the 'audmode' field */
+#define V4L2_TUNER_MODE_MONO		0x0000
+#define V4L2_TUNER_MODE_STEREO		0x0001
+#define V4L2_TUNER_MODE_LANG2		0x0002
+#define V4L2_TUNER_MODE_SAP		0x0002
+#define V4L2_TUNER_MODE_LANG1		0x0003
+
+struct v4l2_frequency
+{
+	int	input;
+	__u32	frequency;
+	__u32	reserved[2];
+};
+
+/*
+ *	A U D I O
+ */
+struct v4l2_audio
+{
+	int	audio;
+	char	name[32];
+	__u32	capability;
+	__u32	mode;
+	__u32	reserved[2];
+};
+/*  Flags for the 'capability' field */
+#define V4L2_AUDCAP_EFFECTS		0x0020
+#define V4L2_AUDCAP_LOUDNESS		0x0040
+#define V4L2_AUDCAP_AVL			0x0080
+
+/*  Flags for the 'mode' field */
+#define V4L2_AUDMODE_LOUDNESS		0x00002
+#define V4L2_AUDMODE_AVL		0x00004
+#define V4L2_AUDMODE_STEREO_field	0x0FF00
+#define V4L2_AUDMODE_STEREO_LINEAR	0x00100
+#define V4L2_AUDMODE_STEREO_PSEUDO	0x00200
+#define V4L2_AUDMODE_STEREO_SPATIAL30	0x00300
+#define V4L2_AUDMODE_STEREO_SPATIAL50	0x00400
+
+struct v4l2_audioout
+{
+	int	audio;
+	char	name[32];
+	__u32	capability;
+	__u32	mode;
+	__u32	reserved[2];
+};
+
+/*
+ *	D A T A   S E R V I C E S   ( V B I )
+ *
+ *	Data services API by Michael Schimek
+ */
+
+struct v4l2_vbi_format
+{
+	__u32	sampling_rate;		/* in 1 Hz */
+	__u32	offset;
+	__u32	samples_per_line;
+	__u32	sample_format;		/* V4L2_VBI_SF_* */
+	__s32	start[2];
+	__u32	count[2];
+	__u32	flags;			/* V4L2_VBI_* */
+	__u32	reserved2;		/* must be zero */
+};
+
+/*  VBI sampling formats */
+#define V4L2_VBI_SF_UBYTE	1
+
+/*  VBI flags  */
+#define V4L2_VBI_UNSYNC		(1<< 0)
+#define V4L2_VBI_INTERLACED	(1<< 1)
+
+
+/*
+ *	A G G R E G A T E   S T R U C T U R E S
+ */
+
+/*	Stream data format
+ */
+struct v4l2_format
+{
+	__u32	type;
+	union
+	{
+		struct v4l2_pix_format	pix;	/*  image format  */
+		struct v4l2_vbi_format	vbi;	/*  VBI data  */
+		/*  add more  */
+		__u8	raw_data[200];  /* user-defined */
+	} fmt;
+};
+
+
+/*	Stream type-dependent parameters
+ */
+struct v4l2_streamparm
+{
+	__u32	type;
+	union
+	{
+		struct v4l2_captureparm	capture;
+		struct v4l2_outputparm	output;
+		/*  add more  */
+		__u8	raw_data[200];  /* user-defined */
+	} parm;
+};
+
+
+
+/*
+ *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
+ *
+ */
+#define VIDIOC_QUERYCAP		_IOR  ('V',  0, struct v4l2_capability)
+#define VIDIOC_RESERVED		_IO   ('V',  1)
+#define VIDIOC_ENUM_PIXFMT	_IOWR ('V',  2, struct v4l2_fmtdesc)
+#define VIDIOC_ENUM_FBUFFMT	_IOWR ('V',  3, struct v4l2_fmtdesc)
+#define VIDIOC_G_FMT		_IOWR ('V',  4, struct v4l2_format)
+#define VIDIOC_S_FMT		_IOWR ('V',  5, struct v4l2_format)
+#define VIDIOC_G_COMP		_IOR  ('V',  6, struct v4l2_compression)
+#define VIDIOC_S_COMP		_IOW  ('V',  7, struct v4l2_compression)
+#define VIDIOC_REQBUFS		_IOWR ('V',  8, struct v4l2_requestbuffers)
+#define VIDIOC_QUERYBUF		_IOWR ('V',  9, struct v4l2_buffer)
+#define VIDIOC_G_FBUF		_IOR  ('V', 10, struct v4l2_framebuffer)
+#define VIDIOC_S_FBUF		_IOW  ('V', 11, struct v4l2_framebuffer)
+#define VIDIOC_G_WIN		_IOR  ('V', 12, struct v4l2_window)
+#define VIDIOC_S_WIN		_IOW  ('V', 13, struct v4l2_window)
+#define VIDIOC_PREVIEW		_IOWR ('V', 14, int)
+#define VIDIOC_QBUF		_IOWR ('V', 15, struct v4l2_buffer)
+#define VIDIOC_DQBUF		_IOWR ('V', 17, struct v4l2_buffer)
+#define VIDIOC_STREAMON		_IOW  ('V', 18, int)
+#define VIDIOC_STREAMOFF	_IOW  ('V', 19, int)
+#define VIDIOC_G_PERF		_IOR  ('V', 20, struct v4l2_performance)
+#define VIDIOC_G_PARM		_IOWR ('V', 21, struct v4l2_streamparm)
+#define VIDIOC_S_PARM		_IOW  ('V', 22, struct v4l2_streamparm)
+#define VIDIOC_G_STD		_IOR  ('V', 23, struct v4l2_standard)
+#define VIDIOC_S_STD		_IOW  ('V', 24, struct v4l2_standard)
+#define VIDIOC_ENUMSTD		_IOWR ('V', 25, struct v4l2_enumstd)
+#define VIDIOC_ENUMINPUT	_IOWR ('V', 26, struct v4l2_input)
+#define VIDIOC_G_CTRL		_IOWR ('V', 27, struct v4l2_control)
+#define VIDIOC_S_CTRL		_IOW  ('V', 28, struct v4l2_control)
+#define VIDIOC_G_TUNER		_IOWR ('V', 29, struct v4l2_tuner)
+#define VIDIOC_S_TUNER		_IOW  ('V', 30, struct v4l2_tuner)
+#define VIDIOC_G_FREQ		_IOR  ('V', 31, int)
+#define VIDIOC_S_FREQ		_IOWR ('V', 32, int)
+#define VIDIOC_G_AUDIO		_IOWR ('V', 33, struct v4l2_audio)
+#define VIDIOC_S_AUDIO		_IOW  ('V', 34, struct v4l2_audio)
+#define VIDIOC_QUERYCTRL	_IOWR ('V', 36, struct v4l2_queryctrl)
+#define VIDIOC_QUERYMENU	_IOWR ('V', 37, struct v4l2_querymenu)
+#define VIDIOC_G_INPUT		_IOR  ('V', 38, int)
+#define VIDIOC_S_INPUT		_IOWR ('V', 39, int)
+#define VIDIOC_ENUMCVT		_IOWR ('V', 40, struct v4l2_cvtdesc)
+#define VIDIOC_G_OUTPUT		_IOR  ('V', 46, int)
+#define VIDIOC_S_OUTPUT		_IOWR ('V', 47, int)
+#define VIDIOC_ENUMOUTPUT	_IOWR ('V', 48, struct v4l2_output)
+#define VIDIOC_G_AUDOUT		_IOWR ('V', 49, struct v4l2_audioout)
+#define VIDIOC_S_AUDOUT		_IOW  ('V', 50, struct v4l2_audioout)
+#define VIDIOC_ENUMFX		_IOWR ('V', 51, struct v4l2_fxdesc)
+#define VIDIOC_G_EFFECT		_IOR  ('V', 52, int)
+#define VIDIOC_S_EFFECT		_IOWR ('V', 53, int)
+#define VIDIOC_G_MODULATOR	_IOWR ('V', 54, struct v4l2_modulator)
+#define VIDIOC_S_MODULATOR	_IOW  ('V', 55, struct v4l2_modulator)
+#define VIDIOC_G_FREQUENCY	_IOWR ('V', 56, struct v4l2_frequency)
+#define VIDIOC_S_FREQUENCY	_IOW  ('V', 57, struct v4l2_frequency)
+
+#define VIDIOC_ENUM_CAPFMT	VIDIOC_ENUM_PIXFMT
+#define VIDIOC_ENUM_OUTFMT	VIDIOC_ENUM_PIXFMT
+#define VIDIOC_ENUM_SRCFMT	VIDIOC_ENUM_PIXFMT
+#define VIDIOC_ENUMFMT		VIDIOC_ENUM_PIXFMT
+
+#define BASE_VIDIOC_PRIVATE	192		/* 192-255 are private */
+
+
+#ifdef __KERNEL__
+/*
+ *
+ *	V 4 L 2   D R I V E R   H E L P E R   A P I
+ *
+ *	Some commonly needed functions for drivers.
+ */
+
+extern void v4l2_version(int *major, int *minor);
+extern int v4l2_major_number(void);
+extern void v4l2_fill_ctrl_category(struct v4l2_queryctrl *qc);
+
+/*  Memory management  */
+extern unsigned long v4l2_vmalloc_to_bus(void *virt);
+extern struct page *v4l2_vmalloc_to_page(void *virt);
+
+/*  Simple queue management  */
+struct v4l2_q_node
+{
+	struct v4l2_q_node 	*forw, *back;
+};
+struct v4l2_queue
+{
+	struct v4l2_q_node	*forw, *back;
+	rwlock_t		qlock;
+};
+extern void  v4l2_q_init(struct v4l2_queue *q);
+extern void  v4l2_q_add_head(struct v4l2_queue *q, struct v4l2_q_node *node);
+extern void  v4l2_q_add_tail(struct v4l2_queue *q, struct v4l2_q_node *node);
+extern void *v4l2_q_del_head(struct v4l2_queue *q);
+extern void *v4l2_q_del_tail(struct v4l2_queue *q);
+extern void *v4l2_q_peek_head(struct v4l2_queue *q);
+extern void *v4l2_q_peek_tail(struct v4l2_queue *q);
+extern void *v4l2_q_yank_node(struct v4l2_queue *q, struct v4l2_q_node *node);
+extern int   v4l2_q_last(struct v4l2_queue *q);
+
+/*  Math functions  */
+extern u32 v4l2_math_div6432(u64 a, u32 d, u32 *r);
+
+/*  Time functions  */
+extern unsigned long v4l2_timestamp_divide(stamp_t t,
+					   unsigned long p_100ns);
+extern unsigned long v4l2_timestamp_correct(stamp_t *t,
+					    unsigned long p_100ns);
+
+/*  Master Clock functions  */
+struct v4l2_clock
+{
+	void	(*gettime)(stamp_t *);
+};
+extern int  v4l2_masterclock_register(struct v4l2_clock *clock);
+extern void v4l2_masterclock_unregister(struct v4l2_clock *clock);
+extern void v4l2_masterclock_gettime(stamp_t *curr);
+
+/*  Video standard functions  */
+extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
+extern unsigned long v4l2_video_std_tpf(struct v4l2_standard *vs);
+extern int v4l2_video_std_confirm(struct v4l2_standard *vs);
+extern int v4l2_video_std_construct(struct v4l2_standard *vs,
+				    int id, __u32 transmission);
+
+#define V4L2_STD_PAL		1	/* PAL B, G, H, I (...) */
+#define V4L2_STD_PAL_M		5	/* (Brazil) */
+#define V4L2_STD_PAL_N		6	/* (Argentina, Paraguay, Uruguay) */
+#define V4L2_STD_PAL_60		10	/* PAL/NTSC hybrid */
+#define V4L2_STD_NTSC		11	/* NTSC M (USA, ...) */
+#define V4L2_STD_NTSC_N		12	/* (Barbados, Bolivia, Colombia, 
+					   S. Korea) */
+#define V4L2_STD_NTSC_44	15	/* PAL/NTSC hybrid */
+#define V4L2_STD_SECAM		21	/* SECAM B, D, G, K, K1 (...) */
+//#define V4L2_STD_SECAM_H	27	/* (Greece, Iran, Morocco) */ 
+//#define V4L2_STD_SECAM_L	28	/* (France, Luxembourg, Monaco) */
+//#define V4L2_STD_SECAM_M	29	/* (Jamaica) */
+
+/*  Size of kernel ioctl arg buffer used in ioctl handler  */
+#define V4L2_MAX_IOCTL_SIZE		256
+
+/*  Compatibility layer interface  */
+typedef int (*v4l2_ioctl_compat)(struct inode *inode, struct file *file,
+				 int cmd, void *arg);
+int v4l2_compat_register(v4l2_ioctl_compat hook);
+void v4l2_compat_unregister(v4l2_ioctl_compat hook);
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_VIDEODEV2_H */
--- linux-2.4.15-pre6/include/linux/videodev.h	Mon Nov 19 11:41:10 2001
+++ linux/include/linux/videodev.h	Mon Nov 19 11:51:29 2001
@@ -4,7 +4,7 @@
 #include <linux/types.h>
 #include <linux/version.h>
 
-#if 0
+#if 1
 /*
  * v4l2 is still work-in-progress, integration planed for 2.5.x
  * project homepage: http://www.thedirks.org/v4l2/
--- linux-2.4.15-pre6/drivers/media/video/Config.in	Mon Nov 19 11:41:10 2001
+++ linux/drivers/media/video/Config.in	Mon Nov 19 11:41:21 2001
@@ -6,6 +6,7 @@
 
 bool '  V4L information in proc filesystem' CONFIG_VIDEO_PROC_FS
 dep_tristate '  I2C on parallel port' CONFIG_I2C_PARPORT $CONFIG_PARPORT $CONFIG_I2C
+dep_tristate '  Backward compatibility for V4L2 drivers' CONFIG_VIDEO_V4LCOMPAT $CONFIG_VIDEO_DEV
 
 comment 'Video Adapters'
 dep_tristate '  Skeleton Driver Video For Linux' CONFIG_VIDEO_SKELETON $CONFIG_VIDEO_DEV
--- linux-2.4.15-pre6/drivers/media/video/Makefile	Mon Nov 19 11:41:10 2001
+++ linux/drivers/media/video/Makefile	Mon Nov 19 11:41:21 2001
@@ -25,13 +25,14 @@
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
-export-objs     :=	i2c-old.o videodev.o bttv-if.o cpia.o
+export-objs     :=	i2c-old.o videodev.o v4l2-common.o bttv-if.o cpia.o
 
 list-multi	:=	bttv.o zoran.o
 bttv-objs	:=	bttv-driver.o bttv-cards.o bttv-if.o
 zoran-objs      :=	zr36120.o zr36120_i2c.o zr36120_mem.o
 
-obj-$(CONFIG_VIDEO_DEV) += videodev.o
+obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o
+obj-$(CONFIG_VIDEO_V4LCOMPAT) += v4l1-compat.o
 
 obj-$(CONFIG_VIDEO_SKELETON) += skeleton.o
 obj-$(CONFIG_BUS_I2C) += i2c-old.o
--- linux-2.4.15-pre6/drivers/media/video/v4l1-compat.c	Mon Nov 19 11:41:21 2001
+++ linux/drivers/media/video/v4l1-compat.c	Mon Nov 19 18:10:10 2001
@@ -0,0 +1,1030 @@
+/*
+ *	Video for Linux Two
+ *	Backward Compatibility Layer
+ *
+ *	Support subroutines for providing V4L2 drivers with backward
+ *	compatibility with applications using the old API.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ * Author:	Bill Dirks <bdirks@pacbell.net>
+ *		et al.
+ *
+ */
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
+#include <linux/config.h>
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/videodev.h>
+#include <linux/videodev2.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
+static unsigned int debug  = 0;
+MODULE_PARM(debug,"i");
+MODULE_PARM_DESC(debug,"enable debug messages");
+MODULE_AUTHOR("Bill Dirks");
+MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
+MODULE_LICENSE("GPL");
+
+#define dprintk(fmt, arg...)	if (debug) \
+	printk(KERN_DEBUG "v4l1-compat: " fmt, ## arg)
+
+/*
+ *	I O C T L   T R A N S L A T I O N
+ *
+ *	From here on down is the code for translating the numerous
+ *	ioctl commands from the old API to the new API.
+ */
+
+static int
+get_v4l_control(struct video_device	*vfl,
+		struct inode            *inode,
+		struct file             *file,
+		int			cid)
+{
+	struct v4l2_queryctrl	qctrl2;
+	struct v4l2_control	ctrl2;
+	int			err;
+
+	qctrl2.id = cid;
+	err = vfl->kernel_ioctl(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
+	if (err < 0)
+		dprintk("VIDIOC_QUERYCTRL: %d\n",err);
+	if (err == 0 &&
+	    !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
+	{
+		ctrl2.id = qctrl2.id;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_CTRL, &ctrl2);
+		if (err < 0)
+			dprintk("VIDIOC_G_CTRL: %d\n",err);
+		return ((ctrl2.value - qctrl2.minimum) * 65535
+			 + (qctrl2.maximum - qctrl2.minimum) / 2)
+			/ (qctrl2.maximum - qctrl2.minimum);
+	}
+	return 0;
+}
+
+static int
+set_v4l_control(struct video_device	*vfl,
+		struct inode            *inode,
+		struct file             *file,
+		int			cid,
+		int			value)
+{
+	struct v4l2_queryctrl	qctrl2;
+	struct v4l2_control	ctrl2;
+	int			err;
+
+	qctrl2.id = cid;
+	err = vfl->kernel_ioctl(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
+	if (err < 0)
+		dprintk("VIDIOC_QUERYCTRL: %d\n",err);
+	if (err == 0 &&
+	    !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
+	    !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED))
+	{
+		if (value < 0)
+			value = 0;
+		if (value > 65535)
+			value = 65535;
+		if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
+			value = 65535;
+		ctrl2.id = qctrl2.id;
+		ctrl2.value = 
+			(value * (qctrl2.maximum - qctrl2.minimum)
+			 + 32767)
+			/ 65535;
+		ctrl2.value += qctrl2.minimum;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_S_CTRL, &ctrl2);
+		if (err < 0)
+			dprintk("VIDIOC_S_CTRL: %d\n",err);
+	}
+	return 0;
+}
+
+static int
+find_tuner(struct video_device	*vfl,
+	   struct inode         *inode,
+	   struct file          *file,
+	   int			n)
+{
+	struct v4l2_input	inp2;
+	int	i;
+	int	err=0;
+
+	/*  Find the input number of the n'th tuner  */
+	for (i = 0; i < 100/*arbitrary*/; ++i)
+	{
+		inp2.index = i;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_ENUMINPUT, &inp2);
+		if (err < 0) {
+			dprintk("VIDIOC_ENUMINPUT: %d\n",err);
+			break;
+		}
+		if (inp2.type != V4L2_INPUT_TYPE_TUNER)
+			continue;
+		if (n == 0)
+			break;
+		--n;
+	}
+	if (err < 0)
+		return err;
+	return i;
+}
+
+static int
+palette_to_pixelformat(int palette)
+{
+	int	pixelformat = 0;
+	switch (palette)
+	{
+	case VIDEO_PALETTE_GREY:
+		pixelformat = V4L2_PIX_FMT_GREY;
+		break;
+	case VIDEO_PALETTE_RGB555:
+		pixelformat = V4L2_PIX_FMT_RGB555;
+		break;
+	case VIDEO_PALETTE_RGB565:
+		pixelformat = V4L2_PIX_FMT_RGB565;
+		break;
+	case VIDEO_PALETTE_RGB24:
+		pixelformat = V4L2_PIX_FMT_BGR24;
+		break;
+	case VIDEO_PALETTE_RGB32:
+		pixelformat = V4L2_PIX_FMT_BGR32;
+		break;
+	/* yuv packed pixel */
+	case VIDEO_PALETTE_YUYV:
+	case VIDEO_PALETTE_YUV422:
+		pixelformat = V4L2_PIX_FMT_YUYV;
+		break;
+	case VIDEO_PALETTE_UYVY:
+		pixelformat = V4L2_PIX_FMT_UYVY;
+		break;
+	/* yuv planar */
+	case VIDEO_PALETTE_YUV410P:
+		pixelformat = V4L2_PIX_FMT_YUV410;
+		break;
+	case VIDEO_PALETTE_YUV420: /* ??? */
+	case VIDEO_PALETTE_YUV420P:
+		pixelformat = V4L2_PIX_FMT_YUV420;
+		break;
+	case VIDEO_PALETTE_YUV411P:
+		pixelformat = V4L2_PIX_FMT_YUV411P;
+		break;
+	case VIDEO_PALETTE_YUV422P:
+		pixelformat = V4L2_PIX_FMT_YUV422P;
+		break;
+	}
+	return pixelformat;
+}
+
+static int
+pixelformat_to_palette(int pixelformat)
+{
+	int	palette = 0;
+	switch (pixelformat)
+	{
+	case V4L2_PIX_FMT_GREY:
+		palette = VIDEO_PALETTE_GREY;
+		break;
+	case V4L2_PIX_FMT_RGB555:
+		palette = VIDEO_PALETTE_RGB555;
+		break;
+	case V4L2_PIX_FMT_RGB565:
+		palette = VIDEO_PALETTE_RGB565;
+		break;
+	case V4L2_PIX_FMT_BGR24:
+		palette = VIDEO_PALETTE_RGB24;
+		break;
+	case V4L2_PIX_FMT_BGR32:
+		palette = VIDEO_PALETTE_RGB32;
+		break;
+	/* yuv packed pixel */
+	case V4L2_PIX_FMT_YUYV:
+		palette = VIDEO_PALETTE_YUYV;
+		break;
+	case V4L2_PIX_FMT_UYVY:
+		palette = VIDEO_PALETTE_UYVY;
+		break;
+	/* yuv planar */
+	case V4L2_PIX_FMT_YUV410:
+		palette = VIDEO_PALETTE_YUV420;
+		break;
+	case V4L2_PIX_FMT_YUV420:
+		palette = VIDEO_PALETTE_YUV420;
+		break;
+	case V4L2_PIX_FMT_YUV411P:
+		palette = VIDEO_PALETTE_YUV411P;
+		break;
+	case V4L2_PIX_FMT_YUV422P:
+		palette = VIDEO_PALETTE_YUV422P;
+		break;
+	}
+	return palette;
+}
+
+/*  Do an 'in' (wait for input) select on a single file descriptor  */
+/*  This stuff plaigarized from linux/fs/select.c     */
+#define __FD_IN(fds, n)	(fds->in + n)
+#define BIT(i)		(1UL << ((i)&(__NFDBITS-1)))
+#define SET(i,m)	(*(m) |= (i))
+extern int do_select(int n, fd_set_bits *fds, long *timeout);
+
+
+static int
+simple_select(struct file *file)
+{
+	fd_set_bits fds;
+	char *bits;
+	long timeout;
+	int i, fd, n, ret, size;
+
+	for (i = 0; i < current->files->max_fds; ++i)
+		if (file == current->files->fd[i])
+			break;
+	if (i == current->files->max_fds)
+		return -EINVAL;
+	fd = i;
+	n = fd + 1;
+
+	timeout = MAX_SCHEDULE_TIMEOUT;
+	/*
+	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
+	 * since we used fdset we need to allocate memory in units of
+	 * long-words. 
+	 */
+	ret = -ENOMEM;
+	size = FDS_BYTES(n);
+	bits = kmalloc(6 * size, GFP_KERNEL);
+	if (!bits)
+		goto out_nofds;
+	fds.in      = (unsigned long *)  bits;
+	fds.out     = (unsigned long *) (bits +   size);
+	fds.ex      = (unsigned long *) (bits + 2*size);
+	fds.res_in  = (unsigned long *) (bits + 3*size);
+	fds.res_out = (unsigned long *) (bits + 4*size);
+	fds.res_ex  = (unsigned long *) (bits + 5*size);
+
+	/*  All zero except our one file descriptor bit, for input  */
+	memset(bits, 0, 6 * size);
+	SET(BIT(fd), __FD_IN((&fds), fd / __NFDBITS));
+
+	ret = do_select(n, &fds, &timeout);
+
+	if (ret < 0)
+		goto out;
+	if (!ret) {
+		ret = -ERESTARTNOHAND;
+		if (signal_pending(current))
+			goto out;
+		ret = 0;
+	}
+out:
+	kfree(bits);
+out_nofds:
+	return ret;
+}
+
+
+/*
+ *	This function is exported.
+ */
+static int
+v4l_compat_translate_ioctl(struct inode         *inode,
+			   struct file		*file,
+			   int			cmd,
+			   void			*arg)
+{
+	struct video_device *vfl = video_devdata(file);
+	int	             err = -ENOIOCTLCMD;
+
+	switch (cmd)
+	{
+	case VIDIOCGCAP:	/* capability */
+	{
+		struct video_capability *cap = arg;
+		struct v4l2_capability cap2;
+		struct v4l2_framebuffer fbuf2;
+
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_QUERYCAP, &cap2);
+		if (err < 0) {
+			dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n",err);
+			break;
+		}
+		if (cap2.flags & V4L2_FLAG_PREVIEW)
+		{
+			err = vfl->kernel_ioctl(inode, file, VIDIOC_G_FBUF, &fbuf2);
+			if (err < 0) {
+				dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n",err);
+				memset(&fbuf2, 0, sizeof(fbuf2));
+			}
+			err = 0;
+		}
+		memset(cap, 0, sizeof(cap));
+		memcpy(cap->name, cap2.name, 
+		       min(sizeof(cap->name), sizeof(cap2.name)));
+		cap->name[sizeof(cap->name) - 1] = 0;
+		if (cap2.type == V4L2_TYPE_CAPTURE)
+			cap->type = VID_TYPE_CAPTURE;
+		if (cap2.flags & V4L2_FLAG_TUNER)
+			cap->type |= VID_TYPE_TUNER;
+		if (cap2.flags & V4L2_FLAG_DATA_SERVICE)
+			cap->type |= VID_TYPE_TELETEXT;
+		if (cap2.flags & V4L2_FLAG_PREVIEW)
+			cap->type |= VID_TYPE_OVERLAY;
+		if (cap2.flags & V4L2_FLAG_MONOCHROME)
+			cap->type |= VID_TYPE_MONOCHROME;
+		if (fbuf2.flags & V4L2_FBUF_FLAG_PRIMARY)
+			cap->type |= VID_TYPE_FRAMERAM;
+		if (fbuf2.capability & V4L2_FBUF_CAP_CHROMAKEY)
+			cap->type |= VID_TYPE_CHROMAKEY;
+		if (fbuf2.capability & V4L2_FBUF_CAP_CLIPPING)
+			cap->type |= VID_TYPE_CLIPPING;
+		if (fbuf2.capability & V4L2_FBUF_CAP_SCALEUP ||
+		    fbuf2.capability & V4L2_FBUF_CAP_SCALEDOWN)
+			cap->type |= VID_TYPE_SCALES;
+		cap->channels  = cap2.inputs;
+		cap->audios    = cap2.audios;
+		cap->maxwidth  = cap2.maxwidth;
+		cap->maxheight = cap2.maxheight;
+		cap->minwidth  = cap2.minwidth;
+		cap->minheight = cap2.minheight;
+		break;
+	}
+	case VIDIOCGFBUF: /*  get frame buffer  */
+	{
+		struct video_buffer	*buffer = arg;
+		struct v4l2_framebuffer	fbuf2;
+
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_FBUF, &fbuf2);
+		if (err < 0) {
+			dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n",err);
+			break;
+		}
+		buffer->base = fbuf2.base[0];
+		buffer->height = fbuf2.fmt.height;
+		buffer->width = fbuf2.fmt.width;
+		buffer->depth = fbuf2.fmt.depth;
+		if (fbuf2.fmt.flags & V4L2_FMT_FLAG_BYTESPERLINE)
+			buffer->bytesperline = fbuf2.fmt.bytesperline;
+		else
+		{
+			buffer->bytesperline = 
+				(fbuf2.fmt.width * fbuf2.fmt.depth + 7) & 7;
+			buffer->bytesperline >>= 3;
+		}
+		if (fbuf2.fmt.pixelformat == V4L2_PIX_FMT_RGB555)
+			buffer->depth = 15;
+		break;
+	}
+	case VIDIOCSFBUF: /*  set frame buffer  */
+	{
+		struct video_buffer	*buffer = arg;
+		struct v4l2_framebuffer	fbuf2;
+
+		memset(&fbuf2, 0, sizeof(fbuf2));
+		fbuf2.base[0] = buffer->base;
+		fbuf2.fmt.height = buffer->height;
+		fbuf2.fmt.width = buffer->width;
+		fbuf2.fmt.depth = buffer->depth;
+		switch (fbuf2.fmt.depth)
+		{
+		case 8:
+			fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB332;
+			break;
+		case 15:
+			fbuf2.fmt.depth = 16;
+			fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB555;
+			break;
+		case 16:
+			fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
+			break;
+		case 24:
+			fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR24;
+			break;
+		case 32:
+			fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR32;
+			break;
+		}
+		fbuf2.fmt.flags |= V4L2_FMT_FLAG_BYTESPERLINE;
+		fbuf2.fmt.bytesperline = buffer->bytesperline;
+		fbuf2.flags = V4L2_FBUF_FLAG_PRIMARY;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_S_FBUF, &fbuf2);
+		if (err < 0)
+			dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n",err);
+		break;
+	}
+	case VIDIOCGWIN: /*  get window or capture dimensions  */
+	{
+		struct video_window	*win = arg;
+		struct v4l2_window	win2;
+		struct v4l2_format	fmt2;
+
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_WIN, &win2);
+		if (err < 0)
+			dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n",err);
+		if (err == 0)
+		{
+			win->x = win2.x;
+			win->y = win2.y;
+			win->width = win2.width;
+			win->height = win2.height;
+			win->chromakey = win2.chromakey;
+			win->clips = NULL;
+			win->clipcount = 0;
+			break;
+		}
+		fmt2.type = V4L2_BUF_TYPE_CAPTURE;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_FMT, &fmt2);
+		if (err < 0) {
+			dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n",err);
+			break;
+		}
+		win->x = 0;
+		win->y = 0;
+		win->width = fmt2.fmt.pix.width;
+		win->height = fmt2.fmt.pix.height;
+		win->chromakey = 0;
+		win->clips = NULL;
+		win->clipcount = 0;
+		break;
+	}
+	case VIDIOCSWIN: /*  set window and/or capture dimensions  */
+	{
+		struct video_window	*win = arg;
+		struct v4l2_window	win2;
+		struct v4l2_format	fmt2;
+
+		fmt2.type = V4L2_BUF_TYPE_CAPTURE;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_FMT, &fmt2);
+		if (err < 0)
+			dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n",err);
+		if (err == 0)
+		{
+			fmt2.fmt.pix.width = win->width;
+			fmt2.fmt.pix.height = win->height;
+			fmt2.fmt.pix.flags |= V4L2_FMT_FLAG_INTERLACED;
+			err = vfl->kernel_ioctl(inode, file, VIDIOC_S_FMT, &fmt2);
+			if (err < 0)
+				dprintk("VIDIOCSWIN / VIDIOC_S_FMT: %d\n",err);
+			win->width = fmt2.fmt.pix.width;
+			win->height = fmt2.fmt.pix.height;
+		}
+		win2.x = win->x;
+		win2.y = win->y;
+		win2.width = win->width;
+		win2.height = win->height;
+		win2.chromakey = win->chromakey;
+		win2.clips = (void *)win->clips;
+		win2.clipcount = win->clipcount;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_S_WIN, &win2);
+		if (err < 0)
+			dprintk("VIDIOCSWIN / VIDIOC_S_WIN: %d\n",err);
+		break;
+	}
+	case VIDIOCCAPTURE: /*  turn on/off preview  */
+	{
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_PREVIEW, arg);
+		if (err < 0)
+			dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n",err);
+		break;
+	}
+	case VIDIOCGCHAN: /*  get input information  */
+	{
+		struct video_channel	*chan = arg;
+		struct v4l2_input	input2;
+		struct v4l2_standard	std2;
+		int			sid;
+
+		input2.index = chan->channel;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_ENUMINPUT, &input2);
+		if (err < 0) {
+			dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: %d\n",err);
+			break;
+		}
+		chan->channel = input2.index;
+		memcpy(chan->name, input2.name,
+		       min(sizeof(chan->name), sizeof(input2.name)));
+		chan->name[sizeof(chan->name) - 1] = 0;
+		chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0;
+		chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0;
+		if (input2.capability & V4L2_INPUT_CAP_AUDIO)
+			chan->flags |= VIDEO_VC_AUDIO;
+		switch (input2.type)
+		{
+		case V4L2_INPUT_TYPE_TUNER:
+			chan->type = VIDEO_TYPE_TV;
+			break;
+		default:
+		case V4L2_INPUT_TYPE_CAMERA:
+			chan->type = VIDEO_TYPE_CAMERA;
+			break;
+		}
+		chan->norm = 0;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_STD, &std2);
+		if (err < 0)
+			dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n",err);
+		if (err == 0)
+		{
+			sid = v4l2_video_std_confirm(&std2);
+			switch (sid)
+			{
+			case V4L2_STD_NTSC:
+				chan->norm = VIDEO_MODE_NTSC;
+				break;
+			case V4L2_STD_PAL:
+				chan->norm = VIDEO_MODE_PAL;
+				break;
+			case V4L2_STD_SECAM:
+				chan->norm = VIDEO_MODE_SECAM;
+				break;
+			}
+		}
+		break;
+	}
+	case VIDIOCSCHAN: /*  set input  */
+	{
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_S_INPUT, arg);
+		if (err < 0)
+			dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n",err);
+		break;
+	}
+	case VIDIOCGPICT: /*  get tone controls & partial capture format  */
+	{
+		struct video_picture	*pict = arg;
+		struct v4l2_format	fmt2;
+
+		pict->brightness = get_v4l_control(vfl, inode, file,
+						   V4L2_CID_BRIGHTNESS);
+		pict->hue = get_v4l_control(vfl, inode, file,
+					    V4L2_CID_HUE);
+		pict->contrast = get_v4l_control(vfl, inode, file,
+						 V4L2_CID_CONTRAST);
+		pict->colour = get_v4l_control(vfl, inode, file,
+					       V4L2_CID_SATURATION);
+		pict->whiteness = get_v4l_control(vfl, inode, file,
+						  V4L2_CID_WHITENESS);
+		fmt2.type = V4L2_BUF_TYPE_CAPTURE;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_FMT, &fmt2);
+		if (err < 0) {
+			dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
+			break;
+		}
+		pict->depth = fmt2.fmt.pix.depth;
+		pict->palette = pixelformat_to_palette(
+			fmt2.fmt.pix.pixelformat);
+		if (pict->palette == VIDEO_PALETTE_RGB555)
+			pict->depth = 15;
+		break;
+	}
+	case VIDIOCSPICT: /*  set tone controls & partial capture format  */
+	{
+		struct video_picture	*pict = arg;
+		struct v4l2_format	fmt2;
+		struct v4l2_framebuffer	fbuf2;
+
+		set_v4l_control(vfl, inode, file,
+				V4L2_CID_BRIGHTNESS, pict->brightness);
+		set_v4l_control(vfl, inode, file,
+				V4L2_CID_HUE, pict->hue);
+		set_v4l_control(vfl, inode, file,
+				V4L2_CID_CONTRAST, pict->contrast);
+		set_v4l_control(vfl, inode, file,
+				V4L2_CID_SATURATION, pict->colour);
+		set_v4l_control(vfl, inode, file,
+				V4L2_CID_WHITENESS, pict->whiteness);
+		err = 0;
+		fmt2.type = V4L2_BUF_TYPE_CAPTURE;
+		vfl->kernel_ioctl(inode, file, VIDIOC_G_FMT, &fmt2);
+		if (err < 0)
+			dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
+		if (fmt2.fmt.pix.pixelformat != 
+		    palette_to_pixelformat(pict->palette))
+		{
+			fmt2.fmt.pix.pixelformat = palette_to_pixelformat(
+				pict->palette);
+			fmt2.fmt.pix.flags |= V4L2_FMT_FLAG_INTERLACED;
+			err = vfl->kernel_ioctl(inode, file, VIDIOC_S_FMT, &fmt2);
+			if (err < 0)
+				dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
+		}
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_FBUF, &fbuf2);
+		if (err < 0)
+			dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
+		if (fbuf2.fmt.pixelformat !=
+		    palette_to_pixelformat(pict->palette)) {
+			fbuf2.fmt.pixelformat = palette_to_pixelformat(
+				pict->palette);
+			fbuf2.fmt.flags |= V4L2_FMT_FLAG_INTERLACED;
+			err = vfl->kernel_ioctl(inode, file, VIDIOC_S_FBUF, &fbuf2);
+			if (err < 0)
+				dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err);
+		}
+		break;
+	}
+	case VIDIOCGTUNER: /*  get tuner information  */
+	{
+		struct video_tuner	*tun = arg;
+		struct v4l2_tuner	tun2;
+		int			i;
+		int			sid;
+
+		i = find_tuner(vfl, inode, file, tun->tuner);
+		if (i < 0)
+		{
+			err = i;
+			break;
+		}
+		tun2.input = i;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_TUNER, &tun2);
+		if (err < 0) {
+			dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n",err);
+			break;
+		}
+		memcpy(tun->name, tun2.name,
+		       min(sizeof(tun->name), sizeof(tun2.name)));
+		tun->name[sizeof(tun->name) - 1] = 0;
+		tun->rangelow = tun2.rangelow;
+		tun->rangehigh = tun2.rangehigh;
+		tun->flags = 0;
+		tun->mode = VIDEO_MODE_AUTO;
+		sid = v4l2_video_std_confirm(&tun2.std);
+		switch (sid)
+		{
+		case V4L2_STD_NTSC:
+			tun->flags = VIDEO_TUNER_NTSC;
+			tun->mode = VIDEO_MODE_NTSC;
+			break;
+		case V4L2_STD_PAL:
+			tun->flags = VIDEO_TUNER_PAL;
+			tun->mode = VIDEO_MODE_PAL;
+			break;
+		case V4L2_STD_SECAM:
+			tun->flags = VIDEO_TUNER_SECAM;
+			tun->mode = VIDEO_MODE_SECAM;
+			break;
+		}
+		if (tun2.capability & V4L2_TUNER_CAP_LOW)
+			tun->flags |= VIDEO_TUNER_LOW;
+		if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
+			tun->flags |= VIDEO_TUNER_STEREO_ON;
+		tun->signal = tun2.signal;
+		break;
+	}
+	case VIDIOCSTUNER: /*  select a tuner input  */
+	{
+		int	i;
+
+		i = find_tuner(vfl, inode, file, (int)arg);
+		if (i < 0)
+		{
+			err = i;
+			break;
+		}
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_S_INPUT, &i);
+		if (err < 0)
+			dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
+		break;
+	}
+	case VIDIOCGFREQ: /*  get frequency  */
+	{
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_FREQ, arg);
+		if (err < 0)
+			dprintk("VIDIOCGFREQ / VIDIOC_G_FREQ: %d\n",err);
+		break;
+	}
+	case VIDIOCSFREQ: /*  set frequency  */
+	{
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_S_FREQ, arg);
+		if (err < 0)
+			dprintk("VIDIOCGFREQ / VIDIOC_S_FREQ: %d\n",err);
+		break;
+	}
+	case VIDIOCGAUDIO: /*  get audio properties/controls  */
+	{
+		struct video_audio	*aud = arg;
+		struct v4l2_audio	aud2;
+		struct v4l2_queryctrl	qctrl2;
+		struct v4l2_tuner	tun2;
+		int			v;
+
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_AUDIO, &aud2);
+		if (err < 0) {
+			dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n",err);
+			break;
+		}
+		memcpy(aud->name, aud2.name,
+		       min(sizeof(aud->name), sizeof(aud2.name)));
+		aud->name[sizeof(aud->name) - 1] = 0;
+		aud->audio = aud2.audio;
+		aud->flags = 0;
+		v = get_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_VOLUME);
+		if (v >= 0)
+		{
+			aud->volume = v;
+			aud->flags |= VIDEO_AUDIO_VOLUME;
+		}
+		v = get_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_BASS);
+		if (v >= 0)
+		{
+			aud->bass = v;
+			aud->flags |= VIDEO_AUDIO_BASS;
+		}
+		v = get_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_TREBLE);
+		if (v >= 0)
+		{
+			aud->treble = v;
+			aud->flags |= VIDEO_AUDIO_TREBLE;
+		}
+		v = get_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_BALANCE);
+		if (v >= 0)
+		{
+			aud->balance = v;
+			aud->flags |= VIDEO_AUDIO_BALANCE;
+		}
+		v = get_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_MUTE);
+		if (v >= 0)
+		{
+			if (v)
+				aud->flags |= VIDEO_AUDIO_MUTE;
+			aud->flags |= VIDEO_AUDIO_MUTABLE;
+		}
+		aud->step = 1;
+		qctrl2.id = V4L2_CID_AUDIO_VOLUME;
+		if (vfl->kernel_ioctl(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
+		    !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
+			aud->step = qctrl2.step;
+		aud->mode = 0;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_TUNER, &tun2);
+		if (err < 0) {
+			dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err);
+			err = 0;
+			break;
+		}
+		if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
+			aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+		else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
+			aud->mode = VIDEO_SOUND_STEREO;
+		else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
+			aud->mode = VIDEO_SOUND_MONO;
+		break;
+	}
+	case VIDIOCSAUDIO: /*  set audio controls  */
+	{
+		struct video_audio	*aud = arg;
+		struct v4l2_audio	aud2;
+		struct v4l2_tuner	tun2;
+		int			i;
+
+		aud2.audio = aud->audio;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_S_AUDIO, &aud2);
+		if (err < 0) {
+			dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n",err);
+			break;
+		}
+
+		set_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_VOLUME, 
+				aud->volume);
+		set_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_BASS,
+				aud->bass);
+		set_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_TREBLE,
+				aud->treble);
+		set_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_BALANCE,
+				aud->balance);
+		set_v4l_control(vfl, inode, file, V4L2_CID_AUDIO_MUTE,
+				!!(aud->flags & VIDEO_AUDIO_MUTE));
+
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_INPUT, &i);
+		if (err < 0) {
+			dprintk("VIDIOCSAUDIO / VIDIOC_G_INPUT: %d\n",err);
+			err = 0;
+			break;
+		}
+		tun2.input = i;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_TUNER, &tun2);
+		if (err < 0)
+			dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n",err);
+		if (err == 0)
+		{
+			switch (aud->mode)
+			{
+			default:
+			case VIDEO_SOUND_MONO:
+			case VIDEO_SOUND_LANG1:
+				tun2.audmode = V4L2_TUNER_MODE_MONO;
+				break;
+			case VIDEO_SOUND_STEREO:
+				tun2.audmode = V4L2_TUNER_MODE_STEREO;
+				break;
+			case VIDEO_SOUND_LANG2:
+				tun2.audmode = V4L2_TUNER_MODE_LANG2;
+				break;
+			}
+			err = vfl->kernel_ioctl(inode, file, VIDIOC_S_TUNER, &tun2);
+			if (err < 0)
+				dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n",err);
+		}
+		err = 0;
+		break;
+	}
+#if 0
+	case VIDIOCGMBUF: /*  get mmap parameters  */
+	{
+		struct video_mbuf		*mbuf = arg;
+		struct v4l2_requestbuffers	reqbuf2;
+		struct v4l2_buffer		buf2;
+		struct v4l2_format		fmt2, fmt2o;
+		struct v4l2_capability		cap2;
+		int				i;
+
+		/*  Set the format to maximum dimensions  */
+		if ((err = vfl->kernel_ioctl(inode, file, VIDIOC_QUERYCAP, &cap2)) < 0)
+			break;
+		fmt2o.type = V4L2_BUF_TYPE_CAPTURE;
+		if ((err = vfl->kernel_ioctl(inode, file, VIDIOC_G_FMT, &fmt2o)) < 0)
+			break;
+		fmt2 = fmt2o;
+		fmt2.fmt.pix.width = cap2.maxwidth;
+		fmt2.fmt.pix.height = cap2.maxheight;
+		fmt2.fmt.pix.flags |= V4L2_FMT_FLAG_INTERLACED;
+		if ((err = vfl->kernel_ioctl(inode, file, VIDIOC_S_FMT, &fmt2)) < 0)
+			break;
+		reqbuf2.count = 2; /* v4l always used two buffers */
+		reqbuf2.type = V4L2_BUF_TYPE_CAPTURE | V4L2_BUF_REQ_CONTIG;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_REQBUFS, &reqbuf2);
+		if (err < 0 || reqbuf2.count < 2 || reqbuf2.type
+		    != (V4L2_BUF_TYPE_CAPTURE | V4L2_BUF_REQ_CONTIG))
+		{/*	Driver doesn't support v4l back-compatibility  */
+			fmt2o.fmt.pix.flags |= V4L2_FMT_FLAG_INTERLACED;
+			vfl->kernel_ioctl(inode, file, VIDIOC_S_FMT, &fmt2o);
+			reqbuf2.count = 1;
+			reqbuf2.type = V4L2_BUF_TYPE_CAPTURE;
+			err = vfl->kernel_ioctl(inode, file, VIDIOC_REQBUFS, &reqbuf2);
+			if (err < 0)
+			{
+				err = -EINVAL;
+				break;
+			}
+			printk(KERN_INFO"V4L2: Device \"%s\" doesn't support"
+			       " v4l memory mapping\n", vfl->name);
+		}
+		buf2.index = 0;
+		buf2.type = V4L2_BUF_TYPE_CAPTURE;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_QUERYBUF, &buf2);
+		mbuf->size = buf2.length * reqbuf2.count;
+		mbuf->frames = reqbuf2.count;
+		memset(mbuf->offsets, 0, sizeof(mbuf->offsets));
+		for (i = 0; i < mbuf->frames; ++i)
+			mbuf->offsets[i] = i * buf2.length;
+		break;
+	}
+#endif
+	case VIDIOCMCAPTURE: /*  capture a frame  */
+	{
+		struct video_mmap	*mm = arg;
+		struct v4l2_buffer	buf2;
+		struct v4l2_format	fmt2;
+
+		fmt2.type = V4L2_BUF_TYPE_CAPTURE;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_G_FMT, &fmt2);
+		if (err < 0) {
+			dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err);
+			break;
+		}
+		if (mm->width != fmt2.fmt.pix.width || 
+		    mm->height != fmt2.fmt.pix.height ||
+		    palette_to_pixelformat(mm->format) != 
+		    fmt2.fmt.pix.pixelformat)
+		{/*	New capture format...  */
+			fmt2.fmt.pix.width = mm->width;
+			fmt2.fmt.pix.height = mm->height;
+			fmt2.fmt.pix.pixelformat =
+				palette_to_pixelformat(mm->format);
+			fmt2.fmt.pix.flags |= V4L2_FMT_FLAG_INTERLACED;
+			err = vfl->kernel_ioctl(inode, file, VIDIOC_S_FMT, &fmt2);
+			if (err < 0) {
+				dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err);
+				break;
+			}
+		}
+		buf2.index = mm->frame;
+		buf2.type = V4L2_BUF_TYPE_CAPTURE;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_QUERYBUF, &buf2);
+		if (err < 0) {
+			dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n",err);
+			break;
+		}
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_QBUF, &buf2);
+		if (err < 0) {
+			dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err);
+			break;
+		}
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_STREAMON, &buf2.type);
+		if (err < 0)
+			dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n",err);
+		break;
+	}
+	case VIDIOCSYNC: /*  wait for a frame  */
+	{
+		int			*i = arg;
+		struct v4l2_buffer	buf2;
+
+		buf2.index = *i;
+		buf2.type = V4L2_BUF_TYPE_CAPTURE;
+		err = vfl->kernel_ioctl(inode, file, VIDIOC_QUERYBUF, &buf2);
+		if (err < 0) {
+			/*  No such buffer */
+			dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
+			break;
+		}
+		if (!(buf2.flags & V4L2_BUF_FLAG_MAPPED)) {
+			/* Buffer is not mapped  */
+			err = -EINVAL;
+			break;
+		}
+
+		/*  Loop as long as the buffer is queued, but not done  */
+		while ((buf2.flags &
+			(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
+		       == V4L2_BUF_FLAG_QUEUED)
+		{
+			err = simple_select(file);
+			if (err < 0 ||	/* error or sleep was interrupted  */
+			    err == 0)	/* timeout? Shouldn't occur.  */
+				break;
+			err = vfl->kernel_ioctl(inode, file, VIDIOC_QUERYBUF, &buf2);
+			if (err < 0)
+				dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
+		}
+		if (!(buf2.flags & V4L2_BUF_FLAG_DONE)) /* not done */
+			break;
+		do {
+			err = vfl->kernel_ioctl(inode, file, VIDIOC_DQBUF, &buf2);
+			if (err < 0)
+				dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n",err);
+		} while (err == 0 && buf2.index != *i);
+		break;
+	}
+	case VIDIOCGUNIT: /*  get related device minors  */
+		/*  No translation  */
+		break;
+	case VIDIOCGCAPTURE: /*    */
+		/*  No translation, yet...  */
+		printk(KERN_INFO"v4l1-compat: VIDIOCGCAPTURE not implemented."
+		       " Send patches to bdirks@pacbell.net :-)\n");
+		break;
+	case VIDIOCSCAPTURE: /*    */
+		/*  No translation, yet...  */
+		printk(KERN_INFO"v4l1-compat: VIDIOCSCAPTURE not implemented."
+		       " Send patches to bdirks@pacbell.net :-)\n");
+		break;
+	}
+	return err;
+}
+
+/*
+ *	Module init and cleanup
+ */
+int v4l1_compat_init(void)
+{
+	return v4l2_compat_register(v4l_compat_translate_ioctl);
+}
+
+void v4l1_compat_fini(void)
+{
+	v4l2_compat_unregister(v4l_compat_translate_ioctl);
+}
+
+module_init(v4l1_compat_init);
+module_exit(v4l1_compat_fini);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
--- linux-2.4.15-pre6/drivers/media/video/v4l2-common.c	Mon Nov 19 11:41:21 2001
+++ linux/drivers/media/video/v4l2-common.c	Mon Nov 19 11:41:21 2001
@@ -0,0 +1,751 @@
+/*
+ *	Video for Linux Two
+ *
+ *	A generic video device interface for the LINUX operating system
+ *	using a set of device structures/vectors for low level operations.
+ *
+ *	This file replaces the videodev.c file that comes with the
+ *	regular kernel distribution.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ * Author:	Bill Dirks <bdirks@pacbell.net>
+ *		based on code by Alan Cox, <alan@cymru.net>
+ *
+ */
+
+/*
+ * Video capture interface for Linux
+ *
+ *	A generic video device interface for the LINUX operating system
+ *	using a set of device structures/vectors for low level operations.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * Author:	Alan Cox, <alan@redhat.com>
+ *
+ * Fixes:
+ */
+
+/*
+ * Video4linux 1/2 integration by Justin Schoeman
+ * <justin@suntiger.ee.up.ac.za>
+ * 2.4 PROCFS support ported from 2.4 kernels by 
+ *  Iñaki García Etxebarria <garetxe@euskalnet.net>
+ * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
+ * 2.4 devfs support ported from 2.4 kernels by
+ *  Dan Merillat <dan@merillat.org>
+ * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/div64.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
+#if defined(CONFIG_UST) || defined(CONFIG_UST_MODULE)
+#include <linux/ust.h>
+#endif
+
+#include <linux/videodev.h>
+#include <linux/videodev2.h>
+
+MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Justin Schoeman, Gerd Knorr");
+MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
+MODULE_LICENSE("GPL");
+
+static struct v4l2_clock *masterclock;
+
+/*
+ *	CONTROL CATEGORIES
+ */
+void
+v4l2_fill_ctrl_category(struct v4l2_queryctrl *qc)
+{
+	if ((qc->id >= V4L2_CID_BRIGHTNESS &&
+	     qc->id <= V4L2_CID_HUE) ||
+	    (qc->id >= V4L2_CID_BLACK_LEVEL &&
+	     qc->id <= V4L2_CID_LASTP1-1))
+	{
+		qc->category = V4L2_CTRL_CAT_VIDEO;
+		strcpy(qc->group, "Video");
+	} else
+	if ((qc->id >= V4L2_CID_AUDIO_VOLUME &&
+	     qc->id <= V4L2_CID_AUDIO_LOUDNESS))
+	{
+		qc->category = V4L2_CTRL_CAT_AUDIO;
+		strcpy(qc->group, "Audio");
+	} else
+	if ((qc->id >= V4L2_CID_EFFECT_BASE &&
+	     qc->id <= V4L2_CID_EFFECT_BASE + 10000))
+	{
+		qc->category = V4L2_CTRL_CAT_EFFECT;
+		strcpy(qc->group, "Effect");
+	} else
+	{
+		strcpy(qc->group, "Private");
+	}
+}
+
+/*
+ *
+ *	V 4 L 2   D R I V E R   H E L P E R   A P I
+ *
+ */
+
+void
+v4l2_version(int *major, int *minor)
+{
+	*major = V4L2_MAJOR_VERSION;
+	*minor = V4L2_MINOR_VERSION;
+}
+
+
+/*
+ *  memory management
+ */
+struct page *kvirt_to_pa(unsigned long adr)
+{
+	struct page *ret = NULL;
+	pmd_t *pmd;
+	pte_t *pte;
+	pgd_t *pgd;
+
+	pgd = pgd_offset_k(adr);
+	if (!pgd_none(*pgd)) {
+		pmd = pmd_offset(pgd, adr);
+		if (!pmd_none(*pmd)) {
+			pte = pte_offset(pmd, adr);
+			if (pte_present(*pte)) {
+				ret = pte_page(*pte);
+			}
+		}
+	}
+
+	return ret;
+}
+
+
+struct page *
+v4l2_vmalloc_to_page(void *virt)
+{
+	return kvirt_to_pa((unsigned long) virt);
+}
+
+#if 0
+/*
+ * this is obsolete, virt_to_bus() is not supported any more on all
+ * architectures.  You should use pci dma mapping API instead (see
+ * Documentation/DMA-mapping.txt)
+ */
+unsigned long
+v4l2_vmalloc_to_bus(void *virt)
+{
+	struct page *page;
+	unsigned long kva, ret;
+
+	page = kvirt_to_pa((unsigned long) virt);
+	kva = ((unsigned long)page_address(page)) | (((unsigned long) virt) & (PAGE_SIZE - 1));
+	ret = virt_to_bus((void *) kva);
+
+	return ret;
+}
+#endif
+
+/*
+ *  Simple queue management
+ */
+static rwlock_t rw_lock_unlocked = RW_LOCK_UNLOCKED;
+void
+v4l2_q_init(struct v4l2_queue *q)
+{
+	if (q == NULL)
+		return;
+	q->qlock = rw_lock_unlocked;
+	q->forw = (struct v4l2_q_node *)q;
+	q->back = (struct v4l2_q_node *)q;
+}
+void
+v4l2_q_add_head(struct v4l2_queue *q, struct v4l2_q_node *node)
+{
+	unsigned long flags;
+	if (q == NULL || node == NULL)
+		return;
+	if (q->forw == NULL || q->back == NULL)
+		v4l2_q_init(q);
+	write_lock_irqsave(&(q->qlock), flags);
+	node->forw = q->forw;
+	node->back = (struct v4l2_q_node *)q;
+	q->forw->back = node;
+	q->forw = node;
+	write_unlock_irqrestore(&(q->qlock), flags);
+}
+void
+v4l2_q_add_tail(struct v4l2_queue *q, struct v4l2_q_node *node)
+{
+	unsigned long flags;
+	if (q == NULL || node == NULL)
+		return;
+	if (q->forw == NULL || q->back == NULL)
+		v4l2_q_init(q);
+	write_lock_irqsave(&(q->qlock), flags);
+	node->forw = (struct v4l2_q_node *)q;
+	node->back = q->back;
+	q->back->forw = node;
+	q->back = node;
+	write_unlock_irqrestore(&(q->qlock), flags);
+}
+void *
+v4l2_q_del_head(struct v4l2_queue *q)
+{
+	unsigned long flags;
+	struct v4l2_q_node *node;
+	if (q == NULL)
+		return NULL;
+	write_lock_irqsave(&(q->qlock), flags);
+	if (q->forw == NULL || q->back == NULL ||
+	    q->forw == (struct v4l2_q_node *)q ||
+	    q->back == (struct v4l2_q_node *)q)
+	{
+		write_unlock_irqrestore(&(q->qlock), flags);
+		return NULL;
+	}
+	node = q->forw;
+	node->forw->back = (struct v4l2_q_node *)q;
+	q->forw = node->forw;
+	node->forw = NULL;
+	node->back = NULL;
+	write_unlock_irqrestore(&(q->qlock), flags);
+	return node;
+}
+void *
+v4l2_q_del_tail(struct v4l2_queue *q)
+{
+	unsigned long flags;
+	struct v4l2_q_node *node;
+	if (q == NULL)
+		return NULL;
+	write_lock_irqsave(&(q->qlock), flags);
+	if (q->forw == NULL || q->back == NULL ||
+	    q->forw == (struct v4l2_q_node *)q ||
+	    q->back == (struct v4l2_q_node *)q)
+	{
+		write_unlock_irqrestore(&(q->qlock), flags);
+		return NULL;
+	}
+	node = q->back;
+	node->back->forw = (struct v4l2_q_node *)q;
+	q->back = node->back;
+	node->forw = NULL;
+	node->back = NULL;
+	write_unlock_irqrestore(&(q->qlock), flags);
+	return node;
+}
+void *
+v4l2_q_peek_head(struct v4l2_queue *q)
+{
+	unsigned long flags;
+	struct v4l2_q_node *node;
+	read_lock_irqsave(&(q->qlock), flags);
+	if (q == NULL || q->forw == NULL || q->forw == (struct v4l2_q_node *)q)
+	{
+		read_unlock_irqrestore(&(q->qlock), flags);
+		return NULL;
+	}
+	node = q->forw;
+	read_unlock_irqrestore(&(q->qlock), flags);
+	return node;
+}
+void *
+v4l2_q_peek_tail(struct v4l2_queue *q)
+{
+	unsigned long flags;
+	struct v4l2_q_node *node;
+	read_lock_irqsave(&(q->qlock), flags);
+	if (q == NULL || q->back == NULL || q->back == (struct v4l2_q_node *)q)
+	{
+		read_unlock_irqrestore(&(q->qlock), flags);
+		return NULL;
+	}
+	node = q->back;
+	read_unlock_irqrestore(&(q->qlock), flags);
+	return node;
+}
+void *
+v4l2_q_yank_node(struct v4l2_queue *q, struct v4l2_q_node *node)
+{
+	unsigned long flags;
+	struct v4l2_q_node *t;
+	if (v4l2_q_peek_head(q) == NULL || node == NULL)
+		return NULL;
+	write_lock_irqsave(&(q->qlock), flags);
+	for (t = q->forw; t != (struct v4l2_q_node *)q; t = t->forw)
+		if (t == node)
+		{
+			node->back->forw = node->forw;
+			node->forw->back = node->back;
+			node->forw = NULL;
+			node->back = NULL;
+			write_unlock_irqrestore(&(q->qlock), flags);
+			return node;
+		}
+	write_unlock_irqrestore(&(q->qlock), flags);
+	return NULL;
+}
+int
+v4l2_q_last(struct v4l2_queue *q)
+{
+/*  This function by Olivier Carmona  */
+
+	unsigned long flags;
+	read_lock_irqsave(&(q->qlock), flags);
+	if (q == NULL)
+	{
+		read_unlock_irqrestore(&(q->qlock), flags);
+		return -1;
+	}
+	if (q->forw == NULL || q->back == NULL ||
+	    q->forw == (struct v4l2_q_node *)q ||
+	    q->back == (struct v4l2_q_node *)q)
+	{
+		read_unlock_irqrestore(&(q->qlock), flags);
+		return -1;
+	}
+	if (q->forw == q->back)
+	{
+		read_unlock_irqrestore(&(q->qlock), flags);
+		return 1;
+	}
+	read_unlock_irqrestore(&(q->qlock), flags);
+	return 0;
+}
+
+
+/*
+ *  Math functions
+ */
+
+#if 0
+u32
+v4l2_math_div6432(u64 a, u32 d, u32 *r)
+{
+	u32 q, m;
+#ifdef __i386__
+/*  Danger: This function will fault if the quotient exceeds (1<<32) - 1  */
+	__asm__ __volatile__ (
+		"	movl %2,%%eax\n"
+		"	movl %3,%%edx\n"
+		"	divl %4\n"
+		"	movl %%eax,%0\n"
+		"	movl %%edx,%1\n"
+		: "=g" (q), "=g" (m)
+		: "g" ((u32)a), "g" ((u32)(a >> 32)), "g" (d)
+		: "eax", "edx"
+		);
+#else
+	q = a / d;
+	m = a % d;
+#endif
+	if (r) *r = m;
+	return q;
+}
+#endif
+
+unsigned long
+v4l2_timestamp_divide(stamp_t t, unsigned long p_100ns)
+{
+#if 0
+	/*  Note: 't' is in 1ns units, 'p_100ns' is in 100ns units, */
+	/*  and the quotient is rounded  */
+	u64	p;
+
+	p = (u64)p_100ns * 100;  /* 1ns units */
+	t >>= 6;      /*  /64 to allow p_100ns longer than 4 secs. */
+	p >>= 6;  /*  to keep quotient the same  */
+	return v4l2_math_div6432((u64)t + (p >> 1), (u32)p, NULL);
+#else
+	u32 p;
+
+	p = ((u64)p_100ns * 100) >> 6;
+	t = (t >> 6) + (p >> 1);
+	do_div(t,p);
+	return t;
+#endif
+}
+
+/*  Force the timestamp to be an integer multiple of p_100ns  */
+unsigned long
+v4l2_timestamp_correct(stamp_t *t, unsigned long p_100ns)
+{
+	/*  Note: 't' is in 1ns units, 'p_100ns' is in 100ns units */
+	unsigned long	n;
+
+	n = v4l2_timestamp_divide((u64)*t, p_100ns);
+	*t = (u64)p_100ns * n * 100;
+	return n;
+}
+
+/*
+ *	Master clock operations
+ */
+
+int
+v4l2_masterclock_register(struct v4l2_clock *clock)
+{
+	if (clock == NULL || clock->gettime == NULL)
+		return -1;
+	if (masterclock != NULL)
+		return -1;
+	masterclock = clock;
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+void
+v4l2_masterclock_unregister(struct v4l2_clock *clock)
+{
+	if (clock != masterclock)
+		return;
+	masterclock = NULL;
+	MOD_DEC_USE_COUNT;
+}
+void
+v4l2_masterclock_gettime(stamp_t *curr)
+{
+	if (masterclock)
+		masterclock->gettime(curr);
+	else
+	{
+#if defined(CONFIG_UST) || defined(CONFIG_UST_MODULE)
+		ust_gettime(curr);
+#else
+		struct timeval	t;
+		stamp_t stamp;
+		do_gettimeofday(&t);
+		stamp = (stamp_t)t.tv_sec * 1000000 + t.tv_usec;
+		stamp *= 1000;
+		*curr = stamp;
+#endif
+	}
+}
+
+/*
+ *  Video Standard Operations (contributed by Michael Schimek)
+ */
+
+/* This is the recommended method to deal with the framerate fields. More 
+   sophisticated drivers will access the fields directly. */
+unsigned int
+v4l2_video_std_fps(struct v4l2_standard *vs)
+{ 
+	if (vs->framerate.numerator > 0)
+		return (((vs->framerate.denominator << 8) / 
+			 vs->framerate.numerator) + 
+			(1 << 7)) / (1 << 8);
+	return 0;
+}
+
+/*  Compute the time per frame in 100ns units  */
+unsigned long
+v4l2_video_std_tpf(struct v4l2_standard *vs)
+{
+#if 0
+	return v4l2_math_div6432(
+		(u64)vs->framerate.numerator * 10000000
+		+ vs->framerate.denominator / 2,
+		vs->framerate.denominator,
+		NULL);
+#else
+	u64 a;
+	u32 b;
+
+	a = (u64)vs->framerate.numerator * 10000000 + vs->framerate.denominator / 2;
+	b = vs->framerate.denominator;
+	do_div(a,b);
+	return a;
+#endif
+}
+
+/*  Used only in v4l2_video_std_confirm()  */
+static void
+catc1p2e6(__u8 *s, char c, int n)
+{
+	n /= 10000;
+	sprintf(s + strlen(s), "%c%d.%02d", c, n / 100, n % 100);
+}
+
+/* Verify the validity of the parameters of a v4l2_standard structure and
+   create the name and id from the other fields. It does not relieve a 
+   driver from examining if it can fulfill the request.  Returns an 
+   errno < 0 if inconsistent, 0 if an unknown but maybe usable format, 
+   or the V4L2_STD_XXX_X value if a known standard. */
+int
+v4l2_video_std_confirm(struct v4l2_standard *vs)
+{
+	unsigned int	rate  = 0;
+	unsigned int	lines = vs->framelines;
+	int		std   = 0;
+
+	strcpy(vs->name, "Unknown");
+	if (vs->reserved1 || vs->reserved2)
+		return -EINVAL;
+
+	if (vs->framerate.numerator > 0 &&	
+	    vs->framerate.denominator > 0)
+		rate = v4l2_video_std_fps(vs);
+
+	if (vs->framelines >= 624 && vs->framelines <= 626)
+		lines = 625;
+	else if (vs->framelines >= 524 && vs->framelines <= 526)
+		lines = 525;
+
+	if (rate == 0 || lines == 0 || rate > 200)
+		return -EINVAL;
+
+	switch (vs->colorstandard)
+	{
+	case V4L2_COLOR_STD_PAL:
+		strcpy(vs->name, "PAL");
+		if (rate == 25 && lines == 625)
+			switch (vs->colorstandard_data.pal.colorsubcarrier)
+			{
+			case V4L2_COLOR_SUBC_PAL_N:
+				strcpy(vs->name, "PAL-N");
+				if (vs->transmission & ~V4L2_TRANSM_STD_N)
+					return -EINVAL;
+				return V4L2_STD_PAL_N;
+			case V4L2_COLOR_SUBC_PAL:
+				if (vs->transmission & 
+				    ~(V4L2_TRANSM_STD_B | V4L2_TRANSM_STD_G |
+				      V4L2_TRANSM_STD_H | V4L2_TRANSM_STD_I |
+				      V4L2_TRANSM_STD_D))
+					return -EINVAL;
+				std = V4L2_STD_PAL;
+				goto addtransm;
+			}
+		else if (rate == 30 && lines == 525)
+			switch (vs->colorstandard_data.pal.colorsubcarrier)
+			{
+			case V4L2_COLOR_SUBC_PAL_M:
+				strcpy(vs->name, "PAL-M");
+				if (vs->transmission & ~V4L2_TRANSM_STD_M)
+					return -EINVAL;
+				return V4L2_STD_PAL_M;
+			case V4L2_COLOR_SUBC_PAL:
+				strcpy(vs->name, "PAL-60");
+				if (vs->transmission)
+					return -EINVAL;
+				return V4L2_STD_PAL_60;
+			}
+		if (vs->transmission)
+			return -EINVAL;
+		catc1p2e6(vs->name, ' ', 
+			  vs->colorstandard_data.pal.colorsubcarrier);
+		break;
+
+	case V4L2_COLOR_STD_NTSC:
+		strcpy(vs->name, "NTSC");
+		if (rate == 25 && lines == 625)
+			switch (vs->colorstandard_data.ntsc.colorsubcarrier)
+			{
+			case V4L2_COLOR_SUBC_NTSC:
+				strcpy(vs->name, "NTSC-N");
+				if (vs->transmission & ~V4L2_TRANSM_STD_N)
+					return -EINVAL;
+				return V4L2_STD_NTSC_N;
+			}
+		else if (rate == 30 && lines == 525)
+			switch (vs->colorstandard_data.ntsc.colorsubcarrier)
+			{
+			case V4L2_COLOR_SUBC_NTSC:
+				if (vs->transmission & ~V4L2_TRANSM_STD_M)
+					return -EINVAL;
+				std = V4L2_STD_NTSC;
+				goto addtransm;
+			case V4L2_COLOR_SUBC_PAL:
+				strcpy(vs->name, "NTSC-44");
+				if (vs->transmission)
+					return -EINVAL;
+				return V4L2_STD_NTSC_44;
+			}
+		if (vs->transmission)
+			return -EINVAL;
+		catc1p2e6(vs->name, ' ', 
+			  vs->colorstandard_data.ntsc.colorsubcarrier);
+		break;
+
+	case V4L2_COLOR_STD_SECAM:
+		strcpy(vs->name, "SECAM");
+		if (rate == 25 && lines == 625)
+			if (vs->colorstandard_data.secam.f0b == 
+			    V4L2_COLOR_SUBC_SECAMB &&
+			    vs->colorstandard_data.secam.f0r == 
+			    V4L2_COLOR_SUBC_SECAMR)
+			{
+				if (vs->transmission &
+				    ~(V4L2_TRANSM_STD_B | V4L2_TRANSM_STD_D |
+			              V4L2_TRANSM_STD_G | V4L2_TRANSM_STD_K |
+			              V4L2_TRANSM_STD_K1 | V4L2_TRANSM_STD_L))
+					return -EINVAL;
+				std = V4L2_STD_SECAM;
+				goto addtransm;
+			}
+		if (vs->transmission)
+			return -EINVAL;
+		catc1p2e6(vs->name, ' ', vs->colorstandard_data.secam.f0b);
+		catc1p2e6(vs->name, '/', vs->colorstandard_data.secam.f0r);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+        sprintf(vs->name + strlen(vs->name), " %d/%d",
+	        vs->framelines, rate);
+
+	return std;
+
+ addtransm:
+	if (vs->transmission) strcat(vs->name, "-");
+
+        if (vs->transmission & V4L2_TRANSM_STD_B) strcat(vs->name, "B/");
+        if (vs->transmission & V4L2_TRANSM_STD_G) strcat(vs->name, "G/");
+        if (vs->transmission & V4L2_TRANSM_STD_H) strcat(vs->name, "H/");
+	if (vs->transmission & V4L2_TRANSM_STD_I) strcat(vs->name, "I/");
+	if (vs->transmission & V4L2_TRANSM_STD_D) strcat(vs->name, "D/");
+	if (vs->transmission & V4L2_TRANSM_STD_K) strcat(vs->name, "K/");
+	if (vs->transmission & V4L2_TRANSM_STD_K1) strcat(vs->name, "K1/");
+	if (vs->transmission & V4L2_TRANSM_STD_L) strcat(vs->name, "L/");
+	if (vs->transmission & V4L2_TRANSM_STD_M) strcat(vs->name, "M/");
+	if (vs->transmission & V4L2_TRANSM_STD_N) strcat(vs->name, "N/");
+
+	if (vs->name[strlen(vs->name) - 1] == '/')
+		vs->name[strlen(vs->name) - 1] = 0;    
+
+	return std;
+}
+
+/* Fill in the fields of a v4l2_standard structure according to the
+   'id' and 'transmission' parameters.  Returns negative on error.  */
+int
+v4l2_video_std_construct(struct v4l2_standard *vs,
+			 int id, __u32 transmission)
+{
+	memset(vs, 0, sizeof(struct v4l2_standard));
+
+	vs->framerate.numerator = 1;
+	vs->framerate.denominator = 25;
+	vs->framelines = 625;
+
+	switch (id)
+	{
+	case V4L2_STD_PAL_60:
+		vs->framerate.numerator = 1001;
+		vs->framerate.denominator = 30000;
+		vs->framelines = 525;
+		/* fall thru */
+	case V4L2_STD_PAL:
+		vs->colorstandard = V4L2_COLOR_STD_PAL;
+		vs->colorstandard_data.pal.colorsubcarrier =
+			V4L2_COLOR_SUBC_PAL;
+		break;
+	case V4L2_STD_PAL_M:
+		vs->framerate.numerator = 1001;
+		vs->framerate.denominator = 30000;
+		vs->framelines = 525;
+		vs->colorstandard = V4L2_COLOR_STD_PAL;
+		vs->colorstandard_data.pal.colorsubcarrier = 
+			V4L2_COLOR_SUBC_PAL_M;
+		break;
+	case V4L2_STD_PAL_N:
+		vs->colorstandard = V4L2_COLOR_STD_PAL;
+		vs->colorstandard_data.pal.colorsubcarrier = 
+			V4L2_COLOR_SUBC_PAL_N;
+		break;
+
+	case V4L2_STD_NTSC:
+		vs->framerate.numerator = 1001;
+		vs->framerate.denominator = 30000;
+		vs->framelines = 525;
+		/* fall thru */
+	case V4L2_STD_NTSC_N:
+		vs->colorstandard = V4L2_COLOR_STD_NTSC;
+		vs->colorstandard_data.ntsc.colorsubcarrier = 
+			V4L2_COLOR_SUBC_NTSC;
+		break;
+	case V4L2_STD_NTSC_44:
+		vs->framerate.numerator = 1001;
+		vs->framerate.denominator = 30000;
+		vs->framelines = 525;
+		vs->colorstandard = V4L2_COLOR_STD_NTSC;
+		vs->colorstandard_data.ntsc.colorsubcarrier = 
+			V4L2_COLOR_SUBC_PAL;
+		break;
+
+	case V4L2_STD_SECAM:
+		vs->colorstandard = V4L2_COLOR_STD_SECAM;
+		vs->colorstandard_data.secam.f0b = V4L2_COLOR_SUBC_SECAMB;
+		vs->colorstandard_data.secam.f0r = V4L2_COLOR_SUBC_SECAMR;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	vs->transmission = transmission;
+
+	return v4l2_video_std_confirm(vs);
+}
+
+
+/*---------------------------------------*/
+
+EXPORT_SYMBOL(v4l2_version);
+EXPORT_SYMBOL(v4l2_fill_ctrl_category);
+EXPORT_SYMBOL(v4l2_vmalloc_to_page);
+EXPORT_SYMBOL(v4l2_q_init);
+EXPORT_SYMBOL(v4l2_q_add_head);
+EXPORT_SYMBOL(v4l2_q_add_tail);
+EXPORT_SYMBOL(v4l2_q_del_head);
+EXPORT_SYMBOL(v4l2_q_del_tail);
+EXPORT_SYMBOL(v4l2_q_peek_head);
+EXPORT_SYMBOL(v4l2_q_peek_tail);
+EXPORT_SYMBOL(v4l2_q_yank_node);
+EXPORT_SYMBOL(v4l2_q_last);
+#if 0
+EXPORT_SYMBOL(v4l2_math_div6432);
+#endif
+EXPORT_SYMBOL(v4l2_timestamp_divide);
+EXPORT_SYMBOL(v4l2_timestamp_correct);
+EXPORT_SYMBOL(v4l2_masterclock_register);
+EXPORT_SYMBOL(v4l2_masterclock_unregister);
+EXPORT_SYMBOL(v4l2_masterclock_gettime);
+EXPORT_SYMBOL(v4l2_video_std_fps);
+EXPORT_SYMBOL(v4l2_video_std_tpf);
+EXPORT_SYMBOL(v4l2_video_std_confirm);
+EXPORT_SYMBOL(v4l2_video_std_construct);
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
--- linux-2.4.15-pre6/drivers/media/video/videodev.c	Mon Nov 19 11:41:10 2001
+++ linux/drivers/media/video/videodev.c	Mon Nov 19 11:41:21 2001
@@ -32,6 +32,7 @@
 #include <asm/semaphore.h>
 
 #include <linux/videodev.h>
+#include <linux/videodev2.h>
 
 #define VIDEO_NUM_DEVICES	256 
 
@@ -233,7 +234,32 @@
 }
 
 /*
+ *  register/unregister v4l2->v4l1 back compatibility layer hook
+ */
+static v4l2_ioctl_compat compat_hook = NULL;
+
+int
+v4l2_compat_register(v4l2_ioctl_compat hook)
+{
+	if (compat_hook != NULL)
+		return -EBUSY;
+	compat_hook = hook;
+	printk(KERN_INFO"V4L2: v4l1 backward compatibility enabled.\n");
+	return 0;
+}
+
+void
+v4l2_compat_unregister(v4l2_ioctl_compat hook)
+{
+	if (compat_hook != hook)
+		BUG();
+	compat_hook = NULL;
+	printk(KERN_INFO"V4L2: v4l1 backward compatibility disabled.\n");
+}
+
+/*
  * ioctl helper function -- handles userspace copying
+ * also calls into the v4l2->v4l1 compatibility layer if needed
  */
 int
 video_generic_ioctl(struct inode *inode, struct file *file,
@@ -274,8 +300,14 @@
 
 	/* call driver */
 	err = vfl->kernel_ioctl(inode, file, cmd, parg);
-	if (err == -ENOIOCTLCMD)
-		err = -EINVAL;
+	if (err == -ENOIOCTLCMD) {
+		/* try to handle unknown v4l1 ioctls using the
+		   v4l2->v4l1 compatibility layer */
+		if (compat_hook && _IOC_TYPE(cmd) == 'v')
+			err = compat_hook(inode, file, cmd, parg);
+		if (err == -ENOIOCTLCMD)
+			err = -EINVAL;
+	}
 	if (err < 0)
 		goto out;
 
@@ -638,6 +670,9 @@
 EXPORT_SYMBOL(video_unregister_device);
 EXPORT_SYMBOL(video_devdata);
 EXPORT_SYMBOL(video_generic_ioctl);
+
+EXPORT_SYMBOL(v4l2_compat_register);
+EXPORT_SYMBOL(v4l2_compat_unregister);
 
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers");
--- linux-2.4.15-pre6/Documentation/Configure.help	Mon Nov 19 11:41:11 2001
+++ linux/Documentation/Configure.help	Mon Nov 19 11:41:21 2001
@@ -20998,15 +20998,33 @@
   this are available from
   <ftp://ftp.uk.linux.org/pub/linux/video4linux>.
 
-  If you are interested in writing a driver for such an audio/video
-  device or user software interacting with such a driver, please read
-  the file <file:Documentation/video4linux/API.html>.
+  This kernel includes support for the new Video for Linux Two API,
+  (V4L2) as well as the original system. Drivers and applications
+  need to be rewritten to use V4L2, but drivers for popular cards
+  and applications for most video capture functions already exist.
+
+  Documentation for the original API is included in the file
+  Documentation/video4linux/API.html. Documentation for V4L2 is 
+  available on the web at http://www.thedirks.org/v4l2/
 
   This driver is also available as a module called videodev.o ( = code
   which can be inserted in and removed from the running kernel
   whenever you want). If you want to compile it as a module, say M
   here and read <file:Documentation/modules.txt>.
 
+Backward compatibility for V4L2 drivers
+CONFIG_VIDEO_V4LCOMPAT
+  Choose Y here to enable drivers written to the new V4L2 spec to
+  work with older applications written for the original V4L spec.
+
+  This code is also available as module called v4l1-compat.o (code
+  which can be inserted in and removed from the running kernel
+  whenever you want). If you want to compile it as a module, say M
+  here and read Documentation/modules.txt.
+
+  If unsure, say M, and the module will be loaded automatically if it
+  is ever needed.
+  
 Video For Linux /proc file system information
 CONFIG_VIDEO_PROC_FS
   If you say Y here, you are able to access video device information
