?? cpia.c
字號:
/* * 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> * * 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_ define for verbose debug output */#include <linux/config.h>#include <linux/module.h>#include <linux/version.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/vmalloc.h>#include <linux/delay.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>#include <linux/wrapper.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@mindspring.com> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <jerdfelt@valinux.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_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_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)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/* 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);/********************************************************************** * * Memory management * * This is a shameless copy from the USB-cpia driver (linux kernel * version 2.3.29 or so, I have no idea what this code actually does ;). * Actually it seems to be a copy of a shameless copy of the bttv-driver. * Or that is a copy of a shameless copy of ... (To the powers: is there * no generic kernel-function to do this sort of stuff?) * * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says * there will be one, but apparentely not yet - jerdfelt * **********************************************************************//* Given PGD from the address space's page table, return the kernel * virtual mapping of the physical memory mapped at ADR. */static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr){ unsigned long ret = 0UL; pmd_t *pmd; pte_t *ptep, pte; if (!pgd_none(*pgd)) { pmd = pmd_offset(pgd, adr); if (!pmd_none(*pmd)) { ptep = pte_offset(pmd, adr); pte = *ptep; if (pte_present(pte)) { ret = (unsigned long) page_address(pte_page(pte)); ret |= (adr & (PAGE_SIZE-1)); } } } return ret;}/* Here we want the physical address of the memory. * This is used when initializing the contents of the * area and marking the pages as reserved. */static inline unsigned long kvirt_to_pa(unsigned long adr){ unsigned long va, kva, ret; va = VMALLOC_VMADDR(adr); kva = uvirt_to_kva(pgd_offset_k(va), va); ret = __pa(kva); return ret;}static void *rvmalloc(unsigned long size){ void *mem; unsigned long adr, page; /* Round it off to PAGE_SIZE */ size += (PAGE_SIZE - 1); size &= ~(PAGE_SIZE - 1); 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) { page = kvirt_to_pa(adr); mem_map_reserve(virt_to_page(__va(page))); adr += PAGE_SIZE; if (size > PAGE_SIZE) size -= PAGE_SIZE; else size = 0; } return mem;}static void rvfree(void *mem, unsigned long size){ unsigned long adr, page; if (!mem) return; size += (PAGE_SIZE - 1); size &= ~(PAGE_SIZE - 1); adr = (unsigned long) mem; while (size > 0) { page = kvirt_to_pa(adr); mem_map_unreserve(virt_to_page(__va(page))); adr += PAGE_SIZE; if (size > PAGE_SIZE) size -= PAGE_SIZE; else size = 0; } 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[20]; /* 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); out += sprintf(out, "video_size: %s\n", cam->params.format.videoSize == VIDEOSIZE_CIF ? "CIF " : "QCIF"); out += sprintf(out, "sub_sample: %s\n", cam->params.format.subSample == SUBSAMPLE_420 ? "420" : "422"); out += sprintf(out, "yuv_order: %s\n", cam->params.format.yuvOrder == YUVORDER_YUYV ? "YUYV" : "UYVY"); 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, "ecp_timing: %8s %8s %8s %8s\n", cam->params.ecpTiming ? "slow" : "normal", "slow", "normal", "normal"); if (cam->params.colourBalance.balanceModeIsAuto) { 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", 1, 2); else sprintf(tmpstr, "1,2,4,8"); if (cam->params.exposure.gainMode == 0) out += sprintf(out, "max_gain: unknown %18s" " %8d\n", tmpstr, 2); else out += sprintf(out, "max_gain: %8d %18s %8d\n", 1<<(cam->params.exposure.gainMode-1), tmpstr, 2); 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 to 127 */ tmp = 255; else tmp = 511; 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 = 255; else tmp = 65535; 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",
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -