--- linux-2.4.19-rc3/include/linux/videodev.h.v4l2 Wed Jul 24 16:27:58 2002 +++ linux-2.4.19-rc3/include/linux/videodev.h Thu Jul 25 16:55:17 2002 @@ -4,7 +4,7 @@ #include #include -#if 0 +#if 1 /* * v4l2 is still work-in-progress, integration planed for 2.5.x * v4l2 project homepage: http://www.thedirks.org/v4l2/ --- linux-2.4.19-rc3/include/linux/videodev2.h.v4l2 Thu Jul 25 16:55:17 2002 +++ linux-2.4.19-rc3/include/linux/videodev2.h Thu Jul 25 16:55:17 2002 @@ -0,0 +1,944 @@ +#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 + * 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]; +}; + +struct v4l2_jpegcompression +{ + int quality; + + int APPn; /* Number of APP segment to be written, + * must be 0..15 */ + int APP_len; /* Length of data in JPEG APPn segment */ + char APP_data[60]; /* Data in the JPEG APPn segment. */ + + int COM_len; /* Length of data in JPEG COM segment */ + char COM_data[60]; /* Data in JPEG COM segment */ + + __u32 jpeg_markers; /* Which markers should go into the JPEG + * output. Unless you exactly know what + * you do, leave them untouched. + * Inluding less markers will make the + * resulting code smaller, but there will + * be fewer aplications which can read it. + * The presence of the APP and COM marker + * is influenced by APP_len and COM_len + * ONLY, not by this property! */ + +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will + * allways use APP0 */ +}; + + +/* + * 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_CROPCAP _IOR ('V', 58, struct v4l2_cropcap) +#define VIDIOC_G_CROP _IOR ('V', 59, struct v4l2_crop) +#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop) +#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression) +#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression) + +#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 (v4l2-common.o module) + */ +#include + +extern void v4l2_version(int *major, int *minor); +extern int v4l2_major_number(void); +extern void v4l2_fill_ctrl_category(struct v4l2_queryctrl *qc); + +/* 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); + +/* 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) */ + +/* Compatibility layer interface */ +typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg); +int v4l_compat_translate_ioctl(struct inode *inode, struct file *file, + int cmd, void *arg, v4l2_kioctl driver_ioctl); + +#endif /* __KERNEL__ */ +#endif /* __LINUX_VIDEODEV2_H */ --- linux-2.4.19-rc3/drivers/media/video/Makefile.v4l2 Wed Jul 24 16:26:46 2002 +++ linux-2.4.19-rc3/drivers/media/video/Makefile Thu Jul 25 16:55:17 2002 @@ -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 bttv-if.o cpia.o \ + v4l2-common.o v4l1-compat.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 v4l1-compat.o obj-$(CONFIG_BUS_I2C) += i2c-old.o obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ --- linux-2.4.19-rc3/drivers/media/video/v4l1-compat.c.v4l2 Thu Jul 25 16:55:17 2002 +++ linux-2.4.19-rc3/drivers/media/video/v4l1-compat.c Thu Jul 25 16:55:17 2002 @@ -0,0 +1,1017 @@ +/* + * 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 + * et al. + * + */ + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_KMOD +#include +#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 inode *inode, + struct file *file, + int cid, + v4l2_kioctl drv) +{ + struct v4l2_queryctrl qctrl2; + struct v4l2_control ctrl2; + int err; + + qctrl2.id = cid; + err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2); + if (err < 0) + dprintk("VIDIOC_QUERYCTRL: %d\n",err); + if (err == 0 && + !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) + { + ctrl2.id = qctrl2.id; + err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2); + if (err < 0) + dprintk("VIDIOC_G_CTRL: %d\n",err); + return ((ctrl2.value - qctrl2.minimum) * 65535 + + (qctrl2.maximum - qctrl2.minimum) / 2) + / (qctrl2.maximum - qctrl2.minimum); + } + return 0; +} + +static int +set_v4l_control(struct inode *inode, + struct file *file, + int cid, + int value, + v4l2_kioctl drv) +{ + struct v4l2_queryctrl qctrl2; + struct v4l2_control ctrl2; + int err; + + qctrl2.id = cid; + err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2); + if (err < 0) + dprintk("VIDIOC_QUERYCTRL: %d\n",err); + if (err == 0 && + !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) && + !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED)) + { + if (value < 0) + value = 0; + if (value > 65535) + value = 65535; + if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN) + value = 65535; + ctrl2.id = qctrl2.id; + ctrl2.value = + (value * (qctrl2.maximum - qctrl2.minimum) + + 32767) + / 65535; + ctrl2.value += qctrl2.minimum; + err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2); + if (err < 0) + dprintk("VIDIOC_S_CTRL: %d\n",err); + } + return 0; +} + +static int +find_tuner(struct inode *inode, + struct file *file, + int n, + v4l2_kioctl drv) +{ + 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 = drv(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. + */ +int +v4l_compat_translate_ioctl(struct inode *inode, + struct file *file, + int cmd, + void *arg, + v4l2_kioctl drv) +{ + int err = -ENOIOCTLCMD; + + switch (cmd) + { + case VIDIOCGCAP: /* capability */ + { + struct video_capability *cap = arg; + struct v4l2_capability cap2; + struct v4l2_framebuffer fbuf2; + + err = drv(inode, file, VIDIOC_QUERYCAP, &cap2); + if (err < 0) { + dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n",err); + break; + } + if (cap2.flags & V4L2_FLAG_PREVIEW) + { + err = drv(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 = drv(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 = drv(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 = drv(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 = drv(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 = drv(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 = drv(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 = drv(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 = drv(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 = drv(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 = drv(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 = drv(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(inode, file, + V4L2_CID_BRIGHTNESS,drv); + pict->hue = get_v4l_control(inode, file, + V4L2_CID_HUE, drv); + pict->contrast = get_v4l_control(inode, file, + V4L2_CID_CONTRAST, drv); + pict->colour = get_v4l_control(inode, file, + V4L2_CID_SATURATION, drv); + pict->whiteness = get_v4l_control(inode, file, + V4L2_CID_WHITENESS, drv); + fmt2.type = V4L2_BUF_TYPE_CAPTURE; + err = drv(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(inode, file, + V4L2_CID_BRIGHTNESS, pict->brightness, drv); + set_v4l_control(inode, file, + V4L2_CID_HUE, pict->hue, drv); + set_v4l_control(inode, file, + V4L2_CID_CONTRAST, pict->contrast, drv); + set_v4l_control(inode, file, + V4L2_CID_SATURATION, pict->colour, drv); + set_v4l_control(inode, file, + V4L2_CID_WHITENESS, pict->whiteness, drv); + err = 0; + fmt2.type = V4L2_BUF_TYPE_CAPTURE; + drv(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 = drv(inode, file, VIDIOC_S_FMT, &fmt2); + if (err < 0) + dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err); + } + err = drv(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 = drv(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(inode, file, tun->tuner, drv); + if (i < 0) + { + err = i; + break; + } + tun2.input = i; + err = drv(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(inode, file, (int)arg, drv); + if (i < 0) + { + err = i; + break; + } + err = drv(inode, file, VIDIOC_S_INPUT, &i); + if (err < 0) + dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err); + break; + } + case VIDIOCGFREQ: /* get frequency */ + { + err = drv(inode, file, VIDIOC_G_FREQ, arg); + if (err < 0) + dprintk("VIDIOCGFREQ / VIDIOC_G_FREQ: %d\n",err); + break; + } + case VIDIOCSFREQ: /* set frequency */ + { + err = drv(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 = drv(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(inode, file, V4L2_CID_AUDIO_VOLUME, drv); + if (v >= 0) + { + aud->volume = v; + aud->flags |= VIDEO_AUDIO_VOLUME; + } + v = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv); + if (v >= 0) + { + aud->bass = v; + aud->flags |= VIDEO_AUDIO_BASS; + } + v = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv); + if (v >= 0) + { + aud->treble = v; + aud->flags |= VIDEO_AUDIO_TREBLE; + } + v = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv); + if (v >= 0) + { + aud->balance = v; + aud->flags |= VIDEO_AUDIO_BALANCE; + } + v = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv); + 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 (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 && + !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) + aud->step = qctrl2.step; + aud->mode = 0; + err = drv(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 = drv(inode, file, VIDIOC_S_AUDIO, &aud2); + if (err < 0) { + dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n",err); + break; + } + + set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, + aud->volume, drv); + set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, + aud->bass, drv); + set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, + aud->treble, drv); + set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, + aud->balance, drv); + set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, + !!(aud->flags & VIDEO_AUDIO_MUTE), drv); + + err = drv(inode, file, VIDIOC_G_INPUT, &i); + if (err < 0) { + dprintk("VIDIOCSAUDIO / VIDIOC_G_INPUT: %d\n",err); + err = 0; + break; + } + tun2.input = i; + err = drv(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 = drv(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 = drv(inode, file, VIDIOC_QUERYCAP, &cap2)) < 0) + break; + fmt2o.type = V4L2_BUF_TYPE_CAPTURE; + if ((err = drv(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 = drv(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 = drv(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; + drv(inode, file, VIDIOC_S_FMT, &fmt2o); + reqbuf2.count = 1; + reqbuf2.type = V4L2_BUF_TYPE_CAPTURE; + err = drv(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 = drv(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 = drv(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 = drv(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 = drv(inode, file, VIDIOC_QUERYBUF, &buf2); + if (err < 0) { + dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n",err); + break; + } + err = drv(inode, file, VIDIOC_QBUF, &buf2); + if (err < 0) { + dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err); + break; + } + err = drv(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 = drv(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 = drv(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 = drv(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; +} + +EXPORT_SYMBOL(v4l_compat_translate_ioctl); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.4.19-rc3/drivers/media/video/v4l2-common.c.v4l2 Thu Jul 25 16:55:17 2002 +++ linux-2.4.19-rc3/drivers/media/video/v4l2-common.c Thu Jul 25 16:55:17 2002 @@ -0,0 +1,650 @@ +/* + * 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 + * based on code by Alan Cox, + * + */ + +/* + * 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, + * + * Fixes: + */ + +/* + * Video4linux 1/2 integration by Justin Schoeman + * + * 2.4 PROCFS support ported from 2.4 kernels by + * Iñaki García Etxebarria + * Makefile fix by "W. Michael Petullo" + * 2.4 devfs support ported from 2.4 kernels by + * Dan Merillat + * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_KMOD +#include +#endif + +#if defined(CONFIG_UST) || defined(CONFIG_UST_MODULE) +#include +#endif + +#include + +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; +} + +/* + * 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 + */ + +unsigned long +v4l2_timestamp_divide(stamp_t t, unsigned long p_100ns) +{ + u32 p; + + p = ((u64)p_100ns * 100) >> 6; + t = (t >> 6) + (p >> 1); + do_div(t,p); + return t; +} + +/* 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) +{ + u64 a; + u32 b; + + a = (u64)vs->framerate.numerator * 10000000 + + vs->framerate.denominator / 2; + b = vs->framerate.denominator; + do_div(a,b); + return a; +} + +/* 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_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); +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.19-rc3/kernel/ksyms.c.v4l2 Wed Jul 24 16:24:08 2002 +++ linux-2.4.19-rc3/kernel/ksyms.c Thu Jul 25 16:56:00 2002 @@ -279,6 +279,7 @@ EXPORT_SYMBOL(dcache_dir_fsync); EXPORT_SYMBOL(dcache_readdir); EXPORT_SYMBOL(dcache_dir_ops); +EXPORT_SYMBOL(do_select); /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ EXPORT_SYMBOL(default_llseek);