/* (C) 1999-2001 Nemosoft Unv. (webcam@smcc.demon.nl) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PWC_H #define PWC_H #include <linux/config.h> #include <linux/module.h> #include <linux/usb.h> #include <linux/spinlock.h> #include <linux/videodev.h> #include <linux/wait.h> #include <asm/semaphore.h> #include <asm/errno.h> /* Defines and structures for the Philips webcam */ /* Used for checking memory corruption/pointer validation */ #define PWC_MAGIC 0x89DC10ABUL #undef PWC_MAGIC /* Debugging info on/off */ #define PWC_DEBUG 0 #define TRACE_MODULE 0x0001 #define TRACE_PROBE 0x0002 #define TRACE_OPEN 0x0004 #define TRACE_READ 0x0008 #define TRACE_MEMORY 0x0010 #define TRACE_FLOW 0x0020 #define TRACE_SIZE 0x0040 #define TRACE_SEQUENCE 0x1000 #define Trace(R, A...) if (pwc_trace & R) printk(KERN_DEBUG PWC_NAME " " A) #define Debug(A...) printk(KERN_DEBUG PWC_NAME " " A) #define Info(A...) printk(KERN_INFO PWC_NAME " " A) #define Err(A...) printk(KERN_ERR PWC_NAME " " A) /* Defines for ToUCam cameras */ #define TOUCAM_HEADER_SIZE 8 #define TOUCAM_TRAILER_SIZE 4 /* Version block */ #define PWC_MAJOR 7 #define PWC_MINOR 1 #define PWC_RELEASE "7.1" #if defined(CONFIG_ARM) #define PWC_PROCESSOR "ARM" #endif #if defined(CONFIG_M686) #define PWC_PROCESSOR "PPro" #endif #if !defined(PWC_PROCESSOR) #define PWC_PROCESSOR "P5" #endif #if defined(__SMP__) || defined(CONFIG_SMP) #define PWC_SMP "(SMP)" #else #define PWC_SMP "(UP)" #endif #define PWC_VERSION PWC_RELEASE " " PWC_PROCESSOR " " PWC_SMP #define PWC_NAME "pwc" /* Turn certain features on/off */ #define PWC_INT_PIPE 0 /* Ignore errors in the first N frames, to allow for startup delays */ #define FRAME_LOWMARK 5 /* Size and number of buffers for the ISO pipe. */ #define MAX_ISO_BUFS 2 #define ISO_FRAMES_PER_DESC 10 #define ISO_MAX_FRAME_SIZE 960 #define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE) /* Frame buffers: contains compressed or uncompressed video data. */ #define MAX_FRAMES 5 /* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */ #define FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE) /* Absolute maximum number of buffers available for mmap() */ #define MAX_IMAGES 4 struct pwc_coord { int x, y; /* guess what */ int size; /* size, or offset */ }; /* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ struct pwc_iso_buf { void *data; int length; int read; purb_t urb; }; /* intermediate buffers with raw data from the USB cam */ struct pwc_frame_buf { void *data; volatile int filled; /* number of bytes filled */ struct pwc_frame_buf *next; /* list */ #if PWC_DEBUG int sequence; /* Sequence number */ #endif }; struct pwc_device { #ifdef PWC_MAGIC int magic; #endif /* Pointer to our usb_device */ struct usb_device *udev; int type; /* type of cam (645, 646, 675, 680, 690) */ int release; /* release number */ int unplugged; /* set when the plug is pulled */ int usb_init; /* set when the cam has been initialized over USB */ /*** Video data ***/ int vopen; /* flag */ struct video_device *vdev; int vendpoint; /* video isoc endpoint */ int vcinterface; /* video control interface */ int valternate; /* alternate interface needed */ int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ int vpalette; /* YUV, RGB24, RGB32, etc */ int vframe_count; /* received frames */ int vframes_dumped; /* counter for dumped frames */ int vframes_error; /* frames received in error */ int vmax_packet_size; /* USB maxpacket size */ int vlast_packet_size; /* for frame synchronisation */ int vcompression; /* desired compression factor */ int vbandlength; /* compressed band length; 0 is uncompressed */ char vsnapshot; /* snapshot mode */ char vsync; /* used by isoc handler */ /* The image acquisition requires 3 to 5 steps: 1. data is gathered in short packets from the USB controller 2. data is synchronized and packed into a frame buffer 3. in case data is compressed, decompress it into a separate buffer 4. data is optionally converted to RGB/YUV 5. data is transfered to the user process Note that MAX_ISO_BUFS != MAX_FRAMES != MAX_IMAGES.... We have in effect a back-to-back-double-buffer system. */ /* 1: isoc */ struct pwc_iso_buf sbuf[MAX_ISO_BUFS]; char iso_init; /* 2: frame */ struct pwc_frame_buf *fbuf; struct pwc_frame_buf *empty_frames, *empty_frames_tail; struct pwc_frame_buf *full_frames, *full_frames_tail; struct pwc_frame_buf *read_frame; struct pwc_frame_buf *fill_frame; int frame_size; int frame_header_size, frame_trailer_size; int drop_frames; #if PWC_DEBUG int sequence; /* Debugging aid */ #endif /* 3: decompression */ struct pwc_decompressor *decompressor; /* function block with decompression routines */ void *decompress_data; /* private data for decompression engine */ void *decompress_buffer; /* decompressed data */ /* 4: image */ /* We have an 'image' and a 'view', where 'image' is the fixed-size image as delivered by the camera, and 'view' is the size requested by the program. The camera image is centered in this viewport, laced with a gray or black border. view_min <= image <= view <= view_max; */ int image_mask; /* bitmask of supported sizes */ struct pwc_coord view_min, view_max; /* minimum and maximum sizes */ struct pwc_coord image, view; /* image and viewport size */ struct pwc_coord offset; /* offset within the viewport */ void *image_data; /* total buffer, which is subdivided into ... */ void *image_ptr[MAX_IMAGES]; /* ...several images... */ int fill_image; /* ...which are rotated. */ int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ int image_used[MAX_IMAGES]; /* For MCAPTURE and SYNC */ /* Kernel specific structures. These were once moved to the end of the structure and padded with bytes after I found out some of these have different sizes in different kernel versions. But since this is now a source release, I don't have this problem anymore. Fortunately none of these structures are needed in the pwcx module. */ struct semaphore modlock; /* to prevent races in video_open(), etc */ spinlock_t ptrlock; /* for manipulating the buffer pointers */ /*** Misc. data ***/ wait_queue_head_t frameq; /* When waiting for a frame to finish... */ wait_queue_head_t pollq; /* poll() has it's own waitqueue */ wait_queue_head_t remove_ok; /* When we got hot unplugged, we have to avoid a few race conditions */ #if PWC_INT_PIPE void *usb_int_handler; /* for the interrupt endpoint */ #endif }; /* Enumeration of image sizes */ #define PSZ_SQCIF 0x00 #define PSZ_QSIF 0x01 #define PSZ_QCIF 0x02 #define PSZ_SIF 0x03 #define PSZ_CIF 0x04 #define PSZ_VGA 0x05 #define PSZ_MAX 6 #ifdef __cplusplus extern "C" { #endif /* Global variables */ extern int pwc_trace; extern int pwc_preferred_compression; /** functions in pwc-if.c */ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot); /** Functions in pwc-misc.c */ /* sizes in pixels */ extern struct pwc_coord pwc_image_sizes[PSZ_MAX]; int pwc_decode_size(struct pwc_device *pdev, int width, int height); void pwc_construct(struct pwc_device *pdev); /** Functions in pwc-ctrl.c */ /* Request a certain video mode. Returns < 0 if not possible */ extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); /* Calculate the number of bytes per image (not frame) */ extern void pwc_set_image_buffer_size(struct pwc_device *pdev); /* Various controls; should be obvious. Value 0..65535, or < 0 on error */ extern int pwc_get_brightness(struct pwc_device *pdev); extern int pwc_set_brightness(struct pwc_device *pdev, int value); extern int pwc_get_contrast(struct pwc_device *pdev); extern int pwc_set_contrast(struct pwc_device *pdev, int value); extern int pwc_get_gamma(struct pwc_device *pdev); extern int pwc_set_gamma(struct pwc_device *pdev, int value); extern int pwc_get_saturation(struct pwc_device *pdev); extern int pwc_set_saturation(struct pwc_device *pdev, int value); /* Power down or up the camera; not supported by all models */ extern int pwc_camera_power(struct pwc_device *pdev, int power); /* Private ioctl()s; see pwc-ioctl.h */ extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); /** pwc-uncompress.c */ /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ extern int pwc_decompress(struct pwc_device *pdev); #ifdef __cplusplus } #endif #endif