#ifndef __LINUX_OVFX2_H #define __LINUX_OVFX2_H #include #include #include #include #include #include #include "ovsensor.h" #define OVFX2_DEBUG #ifdef OVFX2_DEBUG #define PDEBUG(level, fmt, args...) \ if (debug >= (level)) info("[%s:%d] " fmt, \ __PRETTY_FUNCTION__, __LINE__ , ## args) #else #define PDEBUG(level, fmt, args...) do {} while(0) #endif /* This macro restricts an int variable to an inclusive range */ #define RESTRICT_TO_RANGE(v,mi,ma) { \ if ((v) < (mi)) (v) = (mi); \ else if ((v) > (ma)) (v) = (ma); \ } /* --------------------------------- */ /* DEFINES FOR OV511 AND OTHER CHIPS */ /* --------------------------------- */ /* USB IDs */ #define VEND_OMNIVISION 0x05a9 #define VEND_ORANGE_MICRO 0x0b62 #define PROD_IBOT2 0x0059 /* --------------------------------- */ /* FX2 REGISTER MNEMONICS */ /* --------------------------------- */ #define REG_I2C_ADDR 0x00 #define REG_SAT 0xe9 #define REG_HUE 0xea #define REG_CNTR 0xeb #define REG_BRIGHT 0xec #define REG_SHARP 0xee /* --------------------------------- */ /* MISCELLANEOUS DEFINES */ /* --------------------------------- */ /* USB bRequest values */ #define OVFX2_REQ_I2C_WRITE 0x02 #define OVFX2_REQ_I2C_READ 0x03 #define OVFX2_REQ_REG_WRITE 0x0a #define OVFX2_REQ_REG_READ 0x0b /* Endpoints */ #define OVFX2_INT_ENDPOINT_ADDR 1 #define OVFX2_BULK_ENDPOINT_ADDR 2 /* # of BULK scratch buffers */ #define OVFX2_NUMSBUF 8 #define OVFX2_BULK_SIZE 32768 #define OVFX2_NUMFRAMES 2 #if OV511_NUMFRAMES > VIDEO_MAX_FRAME #error "OV511_NUMFRAMES is too high" #endif /* All known registers are only 1 byte */ #define OVFX2_CBUF_SIZE 1 /* Size of usb_make_path() buffer */ #define OVFX2_USB_PATH_LEN 64 /* Bridge types */ enum { BRG_UNKNOWN, BRG_2800, /* iBot2, OV "2800" ref design */ BRG_9000, /* OV "9000" ref design */ }; enum { STATE_SCANNING, /* Scanning for start */ STATE_LOCKED, /* Found start, waiting for data */ STATE_RECEIVING, /* Receiving image data */ }; /* Buffer states */ enum { BUF_NOT_ALLOCATED, BUF_ALLOCATED, }; struct usb_ovfx2; /* Forward declaration */ struct ovfx2_sbuf { struct usb_ovfx2 *ov; unsigned char *data; struct urb *urb; spinlock_t lock; int n; }; enum { FRAME_UNUSED, /* Unused (no MCAPTURE) */ FRAME_READY, /* Ready to start grabbing */ FRAME_GRABBING, /* In the process of being grabbed into */ FRAME_DONE, /* Finished grabbing, but not been synced yet */ FRAME_ERROR, /* Something bad happened while processing */ }; struct regval { unsigned char reg; unsigned char val; unsigned char mask; }; struct ovfx2_frame { int framenum; /* Index of this frame */ unsigned char *data; /* Frame buffer */ unsigned char *tempdata; /* Temp buffer for multi-stage conversions */ unsigned char *rawdata; /* Raw camera data buffer */ int depth; /* Bytes per pixel */ int width; /* Width application is expecting */ int height; /* Height application is expecting */ int rawwidth; /* Actual width of frame sent from camera */ int rawheight; /* Actual height of frame sent from camera */ int sub_flag; /* Sub-capture mode for this frame? */ unsigned int format; /* Format for this frame */ volatile int grabstate; /* State of grabbing */ int scanstate; /* State of scanning */ int bytes_recvd; /* Number of image bytes received from camera */ long bytes_read; /* Amount that has been read() */ wait_queue_head_t wq; /* Processes waiting */ }; struct usb_ovfx2 { struct video_device vdev; /* Device structure */ struct usb_device *dev; int customid; char *desc; char usb_path[OVFX2_USB_PATH_LEN]; /* Determined by sensor type */ int maxwidth; int maxheight; int minwidth; int minheight; int auto_brt; /* Auto brightness enabled flag */ int auto_gain; /* Auto gain control enabled flag */ int auto_exp; /* Auto exposure enabled flag */ int backlight; /* Backlight exposure algorithm flag */ int mirror; /* Image is reversed horizontally */ int lightfreq; /* Power (lighting) frequency */ int bandfilt; /* Banding filter enabled flag */ struct semaphore lock; /* Serializes user-accessible operations */ int user; /* user count for exclusive use */ int present; /* Device is plugged in */ int streaming; /* Are we streaming BULK? */ int grabbing; /* Are we grabbing? */ unsigned char *fbuf; /* Videodev buffer area */ unsigned char *tempfbuf; /* Temporary (intermediate) buffer area */ unsigned char *rawfbuf; /* Raw camera data buffer area */ int sub_flag; /* Pix Array subcapture on flag */ int subx; /* Pix Array subcapture x offset */ int suby; /* Pix Array subcapture y offset */ int subw; /* Pix Array subcapture width */ int subh; /* Pix Array subcapture height */ int bridge; /* Type of bridge (BRG_*) */ int sensor; /* Type of image sensor chip (SEN_*) */ /* /proc entries, relative to /proc/video/ov511/ */ struct proc_dir_entry *proc_devdir; /* Per-device proc directory */ struct proc_dir_entry *proc_info; /* /info entry */ /* Framebuffer/sbuf management */ int buf_state; struct semaphore buf_lock; int curframe; /* Frame being written to */ struct ovfx2_frame frame[OVFX2_NUMFRAMES]; struct ovfx2_sbuf sbuf[OVFX2_NUMSBUF]; wait_queue_head_t wq; /* Processes waiting */ /* Stop streaming while changing picture settings */ int stop_during_set; int stopped; /* Streaming is temporarily paused */ /* Internal I2C interface */ struct i2c_client internal_client; /* Client for internal use */ /* I2C interface to kernel */ struct i2c_adapter i2c_adap; struct i2c_client *sensor_client; unsigned char last_slave; /* Last accessed I2C slave */ /* Control transaction stuff */ unsigned char *cbuf; /* Buffer for payload */ struct semaphore cbuf_lock; }; /* Used to represent a list of values and their respective symbolic names */ struct symbolic_list { int num; char *name; }; #define NOT_DEFINED_STR "Unknown" /* Returns the name of the matching element in the symbolic_list array. The * end of the list must be marked with an element that has a NULL name. */ static inline char * symbolic(struct symbolic_list list[], int num) { int i; for (i = 0; list[i].name != NULL; i++) if (list[i].num == num) return (list[i].name); return (NOT_DEFINED_STR); } #endif