?? cpia.c
字號(hào):
/* * cpia CPiA driver * * Supports CPiA based Video Camera's. * * (C) Copyright 1999-2000 Peter Pregler * (C) Copyright 1999-2000 Scott J. Bertin * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com> * (C) Copyright 2000 STMicroelectronics * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) *//* #define _CPIA_DEBUG_ 1 */ #include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/vmalloc.h>#include <linux/slab.h>#include <linux/proc_fs.h>#include <linux/ctype.h>#include <linux/pagemap.h>#include <asm/io.h>#include <asm/semaphore.h>#ifdef CONFIG_KMOD#include <linux/kmod.h>#endif#include "cpia.h"#ifdef CONFIG_VIDEO_CPIA_PPextern int cpia_pp_init(void);#endif#ifdef CONFIG_VIDEO_CPIA_USBextern int cpia_usb_init(void);#endifstatic int video_nr = -1;#ifdef MODULEMODULE_PARM(video_nr,"i");MODULE_AUTHOR("Scott J. Bertin <sbertin@securenym.net> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <johannes@erdfeld.com>");MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");MODULE_LICENSE("GPL");MODULE_SUPPORTED_DEVICE("video");#endif#define ABOUT "V4L-Driver for Vision CPiA based cameras"#ifndef VID_HARDWARE_CPIA#define VID_HARDWARE_CPIA 24 /* FIXME -> from linux/videodev.h */#endif#define CPIA_MODULE_CPIA (0<<5)#define CPIA_MODULE_SYSTEM (1<<5)#define CPIA_MODULE_VP_CTRL (5<<5)#define CPIA_MODULE_CAPTURE (6<<5)#define CPIA_MODULE_DEBUG (7<<5)#define INPUT (DATA_IN << 8)#define OUTPUT (DATA_OUT << 8)#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)enum { FRAME_READY, /* Ready to grab into */ FRAME_GRABBING, /* In the process of being grabbed into */ FRAME_DONE, /* Finished grabbing, but not been synced yet */ FRAME_UNUSED, /* Unused (no MCAPTURE) */};#define COMMAND_NONE 0x0000#define COMMAND_SETCOMPRESSION 0x0001#define COMMAND_SETCOMPRESSIONTARGET 0x0002#define COMMAND_SETCOLOURPARAMS 0x0004#define COMMAND_SETFORMAT 0x0008#define COMMAND_PAUSE 0x0010#define COMMAND_RESUME 0x0020#define COMMAND_SETYUVTHRESH 0x0040#define COMMAND_SETECPTIMING 0x0080#define COMMAND_SETCOMPRESSIONPARAMS 0x0100#define COMMAND_SETEXPOSURE 0x0200#define COMMAND_SETCOLOURBALANCE 0x0400#define COMMAND_SETSENSORFPS 0x0800#define COMMAND_SETAPCOR 0x1000#define COMMAND_SETFLICKERCTRL 0x2000#define COMMAND_SETVLOFFSET 0x4000#define COMMAND_SETLIGHTS 0x8000#define ROUND_UP_EXP_FOR_FLICKER 15/* Constants for automatic frame rate adjustment */#define MAX_EXP 302#define MAX_EXP_102 255#define LOW_EXP 140#define VERY_LOW_EXP 70#define TC 94#define EXP_ACC_DARK 50#define EXP_ACC_LIGHT 90#define HIGH_COMP_102 160 #define MAX_COMP 239 #define DARK_TIME 3#define LIGHT_TIME 3/* Maximum number of 10ms loops to wait for the stream to become ready */#define READY_TIMEOUT 100/* Developer's Guide Table 5 p 3-34 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/static u8 flicker_jumps[2][2][4] ={ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } }, { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }};/* forward declaration of local function */static void reset_camera_struct(struct cam_data *cam);static int find_over_exposure(int brightness);static void set_flicker(struct cam_params *params, volatile u32 *command_flags, int on);/********************************************************************** * * Memory management * **********************************************************************//* Here we want the physical address of the memory. * This is used when initializing the contents of the area. */static inline unsigned long kvirt_to_pa(unsigned long adr){ unsigned long kva, ret; kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); kva |= adr & (PAGE_SIZE-1); /* restore the offset */ ret = __pa(kva); return ret;}static void *rvmalloc(unsigned long size){ void *mem; unsigned long adr; size = PAGE_ALIGN(size); mem = vmalloc_32(size); if (!mem) return NULL; memset(mem, 0, size); /* Clear the ram out, no junk to the user */ adr = (unsigned long) mem; while (size > 0) { SetPageReserved(vmalloc_to_page((void *)adr)); adr += PAGE_SIZE; size -= PAGE_SIZE; } return mem;}static void rvfree(void *mem, unsigned long size){ unsigned long adr; if (!mem) return; adr = (unsigned long) mem; while ((long) size > 0) { ClearPageReserved(vmalloc_to_page((void *)adr)); adr += PAGE_SIZE; size -= PAGE_SIZE; } vfree(mem);}/********************************************************************** * * /proc interface * **********************************************************************/#ifdef CONFIG_PROC_FSstatic struct proc_dir_entry *cpia_proc_root=NULL;static int cpia_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data){ char *out = page; int len, tmp; struct cam_data *cam = data; char tmpstr[29]; /* IMPORTANT: This output MUST be kept under PAGE_SIZE * or we need to get more sophisticated. */ out += sprintf(out, "read-only\n-----------------------\n"); out += sprintf(out, "V4L Driver version: %d.%d.%d\n", CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER); out += sprintf(out, "CPIA Version: %d.%02d (%d.%d)\n", cam->params.version.firmwareVersion, cam->params.version.firmwareRevision, cam->params.version.vcVersion, cam->params.version.vcRevision); out += sprintf(out, "CPIA PnP-ID: %04x:%04x:%04x\n", cam->params.pnpID.vendor, cam->params.pnpID.product, cam->params.pnpID.deviceRevision); out += sprintf(out, "VP-Version: %d.%d %04x\n", cam->params.vpVersion.vpVersion, cam->params.vpVersion.vpRevision, cam->params.vpVersion.cameraHeadID); out += sprintf(out, "system_state: %#04x\n", cam->params.status.systemState); out += sprintf(out, "grab_state: %#04x\n", cam->params.status.grabState); out += sprintf(out, "stream_state: %#04x\n", cam->params.status.streamState); out += sprintf(out, "fatal_error: %#04x\n", cam->params.status.fatalError); out += sprintf(out, "cmd_error: %#04x\n", cam->params.status.cmdError); out += sprintf(out, "debug_flags: %#04x\n", cam->params.status.debugFlags); out += sprintf(out, "vp_status: %#04x\n", cam->params.status.vpStatus); out += sprintf(out, "error_code: %#04x\n", cam->params.status.errorCode); /* QX3 specific entries */ if (cam->params.qx3.qx3_detected) { out += sprintf(out, "button: %4d\n", cam->params.qx3.button); out += sprintf(out, "cradled: %4d\n", cam->params.qx3.cradled); } out += sprintf(out, "video_size: %s\n", cam->params.format.videoSize == VIDEOSIZE_CIF ? "CIF " : "QCIF"); out += sprintf(out, "roi: (%3d, %3d) to (%3d, %3d)\n", cam->params.roi.colStart*8, cam->params.roi.rowStart*4, cam->params.roi.colEnd*8, cam->params.roi.rowEnd*4); out += sprintf(out, "actual_fps: %3d\n", cam->fps); out += sprintf(out, "transfer_rate: %4dkB/s\n", cam->transfer_rate); out += sprintf(out, "\nread-write\n"); out += sprintf(out, "----------------------- current min" " max default comment\n"); out += sprintf(out, "brightness: %8d %8d %8d %8d\n", cam->params.colourParams.brightness, 0, 100, 50); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) /* 1-02 firmware limits contrast to 80 */ tmp = 80; else tmp = 96; out += sprintf(out, "contrast: %8d %8d %8d %8d" " steps of 8\n", cam->params.colourParams.contrast, 0, tmp, 48); out += sprintf(out, "saturation: %8d %8d %8d %8d\n", cam->params.colourParams.saturation, 0, 100, 50); tmp = (25000+5000*cam->params.sensorFps.baserate)/ (1<<cam->params.sensorFps.divisor); out += sprintf(out, "sensor_fps: %4d.%03d %8d %8d %8d\n", tmp/1000, tmp%1000, 3, 30, 15); out += sprintf(out, "stream_start_line: %8d %8d %8d %8d\n", 2*cam->params.streamStartLine, 0, cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144, cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120); out += sprintf(out, "sub_sample: %8s %8s %8s %8s\n", cam->params.format.subSample == SUBSAMPLE_420 ? "420" : "422", "420", "422", "422"); out += sprintf(out, "yuv_order: %8s %8s %8s %8s\n", cam->params.format.yuvOrder == YUVORDER_YUYV ? "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV"); out += sprintf(out, "ecp_timing: %8s %8s %8s %8s\n", cam->params.ecpTiming ? "slow" : "normal", "slow", "normal", "normal"); if (cam->params.colourBalance.balanceMode == 2) { sprintf(tmpstr, "auto"); } else { sprintf(tmpstr, "manual"); } out += sprintf(out, "color_balance_mode: %8s %8s %8s" " %8s\n", tmpstr, "manual", "auto", "auto"); out += sprintf(out, "red_gain: %8d %8d %8d %8d\n", cam->params.colourBalance.redGain, 0, 212, 32); out += sprintf(out, "green_gain: %8d %8d %8d %8d\n", cam->params.colourBalance.greenGain, 0, 212, 6); out += sprintf(out, "blue_gain: %8d %8d %8d %8d\n", cam->params.colourBalance.blueGain, 0, 212, 92); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) /* 1-02 firmware limits gain to 2 */ sprintf(tmpstr, "%8d %8d %8d", 1, 2, 2); else sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2); if (cam->params.exposure.gainMode == 0) out += sprintf(out, "max_gain: unknown %28s" " powers of 2\n", tmpstr); else out += sprintf(out, "max_gain: %8d %28s" " 1,2,4 or 8 \n", 1<<(cam->params.exposure.gainMode-1), tmpstr); switch(cam->params.exposure.expMode) { case 1: case 3: sprintf(tmpstr, "manual"); break; case 2: sprintf(tmpstr, "auto"); break; default: sprintf(tmpstr, "unknown"); break; } out += sprintf(out, "exposure_mode: %8s %8s %8s" " %8s\n", tmpstr, "manual", "auto", "auto"); out += sprintf(out, "centre_weight: %8s %8s %8s %8s\n", (2-cam->params.exposure.centreWeight) ? "on" : "off", "off", "on", "on"); out += sprintf(out, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n", 1<<cam->params.exposure.gain, 1, 1); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) /* 1-02 firmware limits fineExp/2 to 127 */ tmp = 254; else tmp = 510; out += sprintf(out, "fine_exp: %8d %8d %8d %8d\n", cam->params.exposure.fineExp*2, 0, tmp, 0); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) /* 1-02 firmware limits coarseExpHi to 0 */ tmp = MAX_EXP_102; else tmp = MAX_EXP; out += sprintf(out, "coarse_exp: %8d %8d %8d" " %8d\n", cam->params.exposure.coarseExpLo+ 256*cam->params.exposure.coarseExpHi, 0, tmp, 185); out += sprintf(out, "red_comp: %8d %8d %8d %8d\n", cam->params.exposure.redComp, COMP_RED, 255, COMP_RED); out += sprintf(out, "green1_comp: %8d %8d %8d %8d\n", cam->params.exposure.green1Comp, COMP_GREEN1, 255, COMP_GREEN1); out += sprintf(out, "green2_comp: %8d %8d %8d %8d\n", cam->params.exposure.green2Comp, COMP_GREEN2, 255, COMP_GREEN2); out += sprintf(out, "blue_comp: %8d %8d %8d %8d\n", cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE); out += sprintf(out, "apcor_gain1: %#8x %#8x %#8x %#8x\n", cam->params.apcor.gain1, 0, 0xff, 0x1c); out += sprintf(out, "apcor_gain2: %#8x %#8x %#8x %#8x\n", cam->params.apcor.gain2, 0, 0xff, 0x1a); out += sprintf(out, "apcor_gain4: %#8x %#8x %#8x %#8x\n", cam->params.apcor.gain4, 0, 0xff, 0x2d); out += sprintf(out, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -