📄 cpia2_core.c
字号:
/**************************************************************************** * * Filename: cpia2_core.c * * Copyright 2001, STMicrolectronics, Inc. * Contact: steve.miller@st.com * * Description: * This is a USB driver for CPia2 based video cameras. * The infrastructure of this driver is based on the cpia usb driver by * Jochen Scharrlach and Johannes Erdfeldt. * * 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. * * Stripped of 2.4 stuff ready for main kernel submit by * Alan Cox <alan@redhat.com> * ****************************************************************************/#include "cpia2.h"#include <linux/slab.h>#include <linux/vmalloc.h>//#define _CPIA2_DEBUG_#include "cpia2patch.h"#ifdef _CPIA2_DEBUG_static const char *block_name[] = { "System", "VC", "VP", "IDATA"};#endifstatic unsigned int debugs_on = 0;//DEBUG_REG;/****************************************************************************** * * Forward Declarations * *****************************************************************************/static int apply_vp_patch(struct camera_data *cam);static int set_default_user_mode(struct camera_data *cam);static int set_vw_size(struct camera_data *cam, int size);static int configure_sensor(struct camera_data *cam, int reqwidth, int reqheight);static int config_sensor_410(struct camera_data *cam, int reqwidth, int reqheight);static int config_sensor_500(struct camera_data *cam, int reqwidth, int reqheight);static int set_all_properties(struct camera_data *cam);static void get_color_params(struct camera_data *cam);static void wake_system(struct camera_data *cam);static void set_lowlight_boost(struct camera_data *cam);static void reset_camera_struct(struct camera_data *cam);static int cpia2_set_high_power(struct camera_data *cam);/* 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 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; /* Round it off to PAGE_SIZE */ 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 ((long)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; size = PAGE_ALIGN(size); adr = (unsigned long) mem; while ((long)size > 0) { ClearPageReserved(vmalloc_to_page((void *)adr)); adr += PAGE_SIZE; size -= PAGE_SIZE; } vfree(mem);}/****************************************************************************** * * cpia2_do_command * * Send an arbitrary command to the camera. For commands that read from * the camera, copy the buffers into the proper param structures. *****************************************************************************/int cpia2_do_command(struct camera_data *cam, u32 command, u8 direction, u8 param){ int retval = 0; struct cpia2_command cmd; unsigned int device = cam->params.pnp_id.device_type; cmd.command = command; cmd.reg_count = 2; /* default */ cmd.direction = direction; /*** * Set up the command. ***/ switch (command) { case CPIA2_CMD_GET_VERSION: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; cmd.start = CPIA2_SYSTEM_DEVICE_HI; break; case CPIA2_CMD_GET_PNP_ID: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; cmd.reg_count = 8; cmd.start = CPIA2_SYSTEM_DESCRIP_VID_HI; break; case CPIA2_CMD_GET_ASIC_TYPE: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; cmd.start = CPIA2_VC_ASIC_ID; break; case CPIA2_CMD_GET_SENSOR: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.start = CPIA2_VP_SENSOR_FLAGS; break; case CPIA2_CMD_GET_VP_DEVICE: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.start = CPIA2_VP_DEVICEH; break; case CPIA2_CMD_SET_VP_BRIGHTNESS: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_VP_BRIGHTNESS: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; if (device == DEVICE_STV_672) cmd.start = CPIA2_VP4_EXPOSURE_TARGET; else cmd.start = CPIA2_VP5_EXPOSURE_TARGET; break; case CPIA2_CMD_SET_CONTRAST: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_CONTRAST: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_VP_YRANGE; break; case CPIA2_CMD_SET_VP_SATURATION: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_VP_SATURATION: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; if (device == DEVICE_STV_672) cmd.start = CPIA2_VP_SATURATION; else cmd.start = CPIA2_VP5_MCUVSATURATION; break; case CPIA2_CMD_SET_VP_GPIO_DATA: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_VP_GPIO_DATA: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_VP_GPIO_DATA; break; case CPIA2_CMD_SET_VP_GPIO_DIRECTION: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_VP_GPIO_DIRECTION: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_VP_GPIO_DIRECTION; break; case CPIA2_CMD_SET_VC_MP_GPIO_DATA: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_VC_MP_GPIO_DATA: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; cmd.reg_count = 1; cmd.start = CPIA2_VC_MP_DATA; break; case CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; cmd.reg_count = 1; cmd.start = CPIA2_VC_MP_DIR; break; case CPIA2_CMD_ENABLE_PACKET_CTRL: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; cmd.start = CPIA2_SYSTEM_INT_PACKET_CTRL; cmd.reg_count = 1; cmd.buffer.block_data[0] = param; break; case CPIA2_CMD_SET_FLICKER_MODES: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_FLICKER_MODES: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_VP_FLICKER_MODES; break; case CPIA2_CMD_RESET_FIFO: /* clear fifo and enable stream block */ cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; cmd.reg_count = 2; cmd.start = 0; cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL; cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC | CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT; cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL; cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC | CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT | CPIA2_VC_ST_CTRL_FIFO_ENABLE; break; case CPIA2_CMD_SET_HI_POWER: cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM; cmd.reg_count = 2; cmd.buffer.registers[0].index = CPIA2_SYSTEM_SYSTEM_CONTROL; cmd.buffer.registers[1].index = CPIA2_SYSTEM_SYSTEM_CONTROL; cmd.buffer.registers[0].value = CPIA2_SYSTEM_CONTROL_CLEAR_ERR; cmd.buffer.registers[1].value = CPIA2_SYSTEM_CONTROL_HIGH_POWER; break; case CPIA2_CMD_SET_LOW_POWER: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; cmd.reg_count = 1; cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL; cmd.buffer.block_data[0] = 0; break; case CPIA2_CMD_CLEAR_V2W_ERR: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; cmd.reg_count = 1; cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL; cmd.buffer.block_data[0] = CPIA2_SYSTEM_CONTROL_CLEAR_ERR; break; case CPIA2_CMD_SET_USER_MODE: /* Then fall through */ cmd.buffer.block_data[0] = param; case CPIA2_CMD_GET_USER_MODE: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; if (device == DEVICE_STV_672) cmd.start = CPIA2_VP4_USER_MODE; else cmd.start = CPIA2_VP5_USER_MODE; break; case CPIA2_CMD_FRAMERATE_REQ: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; if (device == DEVICE_STV_672) cmd.start = CPIA2_VP4_FRAMERATE_REQUEST; else cmd.start = CPIA2_VP5_FRAMERATE_REQUEST; cmd.buffer.block_data[0] = param; break; case CPIA2_CMD_SET_WAKEUP: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_WAKEUP: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; cmd.reg_count = 1; cmd.start = CPIA2_VC_WAKEUP; break; case CPIA2_CMD_SET_PW_CONTROL: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_PW_CONTROL: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; cmd.reg_count = 1; cmd.start = CPIA2_VC_PW_CTRL; break; case CPIA2_CMD_GET_VP_SYSTEM_STATE: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_VP_SYSTEMSTATE; break; case CPIA2_CMD_SET_SYSTEM_CTRL: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_SYSTEM_CTRL: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; cmd.reg_count = 1; cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL; break; case CPIA2_CMD_SET_VP_SYSTEM_CTRL: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_VP_SYSTEM_CTRL: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_VP_SYSTEMCTRL; break; case CPIA2_CMD_SET_VP_EXP_MODES: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_VP_EXP_MODES: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_VP_EXPOSURE_MODES; break; case CPIA2_CMD_SET_DEVICE_CONFIG: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_DEVICE_CONFIG: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_VP_DEVICE_CONFIG; break; case CPIA2_CMD_SET_SERIAL_ADDR: cmd.buffer.block_data[0] = param; cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; cmd.reg_count = 1; cmd.start = CPIA2_SYSTEM_VP_SERIAL_ADDR; break; case CPIA2_CMD_SET_SENSOR_CR1: cmd.buffer.block_data[0] = param; cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_SENSOR_CR1; break; case CPIA2_CMD_SET_VC_CONTROL: cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_VC_CONTROL: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; cmd.reg_count = 1; cmd.start = CPIA2_VC_VC_CTRL; break; case CPIA2_CMD_SET_TARGET_KB: cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; cmd.reg_count = 1; cmd.buffer.registers[0].index = CPIA2_VC_VC_TARGET_KB; cmd.buffer.registers[0].value = param; break; case CPIA2_CMD_SET_DEF_JPEG_OPT: cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; cmd.reg_count = 4; cmd.buffer.registers[0].index = CPIA2_VC_VC_JPEG_OPT; cmd.buffer.registers[0].value = CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE; cmd.buffer.registers[1].index = CPIA2_VC_VC_USER_SQUEEZE; cmd.buffer.registers[1].value = 20; cmd.buffer.registers[2].index = CPIA2_VC_VC_CREEP_PERIOD; cmd.buffer.registers[2].value = 2; cmd.buffer.registers[3].index = CPIA2_VC_VC_JPEG_OPT; cmd.buffer.registers[3].value = CPIA2_VC_VC_JPEG_OPT_DEFAULT; break; case CPIA2_CMD_REHASH_VP4: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; cmd.start = CPIA2_VP_REHASH_VALUES; cmd.buffer.block_data[0] = param; break; case CPIA2_CMD_SET_USER_EFFECTS: /* Note: Be careful with this as this register can also affect flicker modes */ cmd.buffer.block_data[0] = param; /* Then fall through */ case CPIA2_CMD_GET_USER_EFFECTS: cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; cmd.reg_count = 1; if (device == DEVICE_STV_672) cmd.start = CPIA2_VP4_USER_EFFECTS; else cmd.start = CPIA2_VP5_USER_EFFECTS; break; default: LOG("DoCommand received invalid command\n"); return -EINVAL; } retval = cpia2_send_command(cam, &cmd); if (retval) { return retval; } /*** * Now copy any results from a read into the appropriate param struct. ***/ switch (command) { case CPIA2_CMD_GET_VERSION:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -