📄 cpia2_core.c
字号:
cam->params.version.firmware_revision_hi = cmd.buffer.block_data[0]; cam->params.version.firmware_revision_lo = cmd.buffer.block_data[1]; break; case CPIA2_CMD_GET_PNP_ID: cam->params.pnp_id.vendor = (cmd.buffer.block_data[0] << 8) | cmd.buffer.block_data[1]; cam->params.pnp_id.product = (cmd.buffer.block_data[2] << 8) | cmd.buffer.block_data[3]; cam->params.pnp_id.device_revision = (cmd.buffer.block_data[4] << 8) | cmd.buffer.block_data[5]; if (cam->params.pnp_id.vendor == 0x553) { if (cam->params.pnp_id.product == 0x100) { cam->params.pnp_id.device_type = DEVICE_STV_672; } else if (cam->params.pnp_id.product == 0x140 || cam->params.pnp_id.product == 0x151) { cam->params.pnp_id.device_type = DEVICE_STV_676; } } break; case CPIA2_CMD_GET_ASIC_TYPE: cam->params.version.asic_id = cmd.buffer.block_data[0]; cam->params.version.asic_rev = cmd.buffer.block_data[1]; break; case CPIA2_CMD_GET_SENSOR: cam->params.version.sensor_flags = cmd.buffer.block_data[0]; cam->params.version.sensor_rev = cmd.buffer.block_data[1]; break; case CPIA2_CMD_GET_VP_DEVICE: cam->params.version.vp_device_hi = cmd.buffer.block_data[0]; cam->params.version.vp_device_lo = cmd.buffer.block_data[1]; break; case CPIA2_CMD_GET_VP_BRIGHTNESS: cam->params.color_params.brightness = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_CONTRAST: cam->params.color_params.contrast = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_VP_SATURATION: cam->params.color_params.saturation = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_VP_GPIO_DATA: cam->params.vp_params.gpio_data = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_VP_GPIO_DIRECTION: cam->params.vp_params.gpio_direction = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION: cam->params.vc_params.vc_mp_direction =cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_VC_MP_GPIO_DATA: cam->params.vc_params.vc_mp_data = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_FLICKER_MODES: cam->params.flicker_control.cam_register = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_WAKEUP: cam->params.vc_params.wakeup = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_PW_CONTROL: cam->params.vc_params.pw_control = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_SYSTEM_CTRL: cam->params.camera_state.system_ctrl = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_VP_SYSTEM_STATE: cam->params.vp_params.system_state = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_VP_SYSTEM_CTRL: cam->params.vp_params.system_ctrl = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_VP_EXP_MODES: cam->params.vp_params.exposure_modes = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_DEVICE_CONFIG: cam->params.vp_params.device_config = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_VC_CONTROL: cam->params.vc_params.vc_control = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_USER_MODE: cam->params.vp_params.video_mode = cmd.buffer.block_data[0]; break; case CPIA2_CMD_GET_USER_EFFECTS: cam->params.vp_params.user_effects = cmd.buffer.block_data[0]; break; default: break; } return retval;}/****************************************************************************** * * cpia2_send_command * *****************************************************************************/int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd){ u8 count; u8 start; u8 block_index; u8 *buffer; int retval; const char* dir; if (cmd->direction == TRANSFER_WRITE) { dir = "Write"; } else { dir = "Read"; } block_index = cmd->req_mode & 0x03; switch (cmd->req_mode & 0x0c) { case CAMERAACCESS_TYPE_RANDOM: count = cmd->reg_count * sizeof(struct cpia2_register); start = 0; buffer = (u8 *) & cmd->buffer; if (debugs_on & DEBUG_REG) DBG("%s Random: Register block %s\n", dir, block_name[block_index]); break; case CAMERAACCESS_TYPE_BLOCK: count = cmd->reg_count; start = cmd->start; buffer = cmd->buffer.block_data; if (debugs_on & DEBUG_REG) DBG("%s Block: Register block %s\n", dir, block_name[block_index]); break; case CAMERAACCESS_TYPE_MASK: count = cmd->reg_count * sizeof(struct cpia2_reg_mask); start = 0; buffer = (u8 *) & cmd->buffer; if (debugs_on & DEBUG_REG) DBG("%s Mask: Register block %s\n", dir, block_name[block_index]); break; case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */ count = cmd->reg_count; start = cmd->start; buffer = cmd->buffer.block_data; if (debugs_on & DEBUG_REG) DBG("%s Repeat: Register block %s\n", dir, block_name[block_index]); break; default: LOG("%s: invalid request mode\n",__FUNCTION__); return -EINVAL; } retval = cpia2_usb_transfer_cmd(cam, buffer, cmd->req_mode, start, count, cmd->direction);#ifdef _CPIA2_DEBUG_ if (debugs_on & DEBUG_REG) { int i; for (i = 0; i < cmd->reg_count; i++) { if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK) KINFO("%s Block: [0x%02X] = 0x%02X\n", dir, start + i, buffer[i]); if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM) KINFO("%s Random: [0x%02X] = 0x%02X\n", dir, cmd->buffer.registers[i].index, cmd->buffer.registers[i].value); } }#endif return retval;};/************* * Functions to implement camera functionality *************//****************************************************************************** * * cpia2_get_version_info * *****************************************************************************/static void cpia2_get_version_info(struct camera_data *cam){ cpia2_do_command(cam, CPIA2_CMD_GET_VERSION, TRANSFER_READ, 0); cpia2_do_command(cam, CPIA2_CMD_GET_PNP_ID, TRANSFER_READ, 0); cpia2_do_command(cam, CPIA2_CMD_GET_ASIC_TYPE, TRANSFER_READ, 0); cpia2_do_command(cam, CPIA2_CMD_GET_SENSOR, TRANSFER_READ, 0); cpia2_do_command(cam, CPIA2_CMD_GET_VP_DEVICE, TRANSFER_READ, 0);}/****************************************************************************** * * cpia2_reset_camera * * Called at least during the open process, sets up initial params. *****************************************************************************/int cpia2_reset_camera(struct camera_data *cam){ u8 tmp_reg; int retval = 0; int i; struct cpia2_command cmd; /*** * VC setup ***/ retval = configure_sensor(cam, cam->params.roi.width, cam->params.roi.height); if (retval < 0) { ERR("Couldn't configure sensor, error=%d\n", retval); return retval; } /* Clear FIFO and route/enable stream block */ cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; cmd.direction = TRANSFER_WRITE; cmd.reg_count = 2; 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; cpia2_send_command(cam, &cmd); cpia2_set_high_power(cam); if (cam->params.pnp_id.device_type == DEVICE_STV_672) { /* Enable button notification */ cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM; cmd.buffer.registers[0].index = CPIA2_SYSTEM_INT_PACKET_CTRL; cmd.buffer.registers[0].value = CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX; cmd.reg_count = 1; cpia2_send_command(cam, &cmd); } current->state = TASK_INTERRUPTIBLE; schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ if (cam->params.pnp_id.device_type == DEVICE_STV_672) retval = apply_vp_patch(cam); /* wait for vp to go to sleep */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ /*** * If this is a 676, apply VP5 fixes before we start streaming ***/ if (cam->params.pnp_id.device_type == DEVICE_STV_676) { cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP; /* The following writes improve the picture */ cmd.buffer.registers[0].index = CPIA2_VP5_MYBLACK_LEVEL; cmd.buffer.registers[0].value = 0; /* reduce from the default * rec 601 pedestal of 16 */ cmd.buffer.registers[1].index = CPIA2_VP5_MCYRANGE; cmd.buffer.registers[1].value = 0x92; /* increase from 100% to * (256/256 - 31) to fill * available range */ cmd.buffer.registers[2].index = CPIA2_VP5_MYCEILING; cmd.buffer.registers[2].value = 0xFF; /* Increase from the * default rec 601 ceiling * of 240 */ cmd.buffer.registers[3].index = CPIA2_VP5_MCUVSATURATION; cmd.buffer.registers[3].value = 0xFF; /* Increase from the rec * 601 100% level (128) * to 145-192 */ cmd.buffer.registers[4].index = CPIA2_VP5_ANTIFLKRSETUP; cmd.buffer.registers[4].value = 0x80; /* Inhibit the * anti-flicker */ /* The following 4 writes are a fix to allow QVGA to work at 30 fps */ cmd.buffer.registers[5].index = CPIA2_VP_RAM_ADDR_H; cmd.buffer.registers[5].value = 0x01; cmd.buffer.registers[6].index = CPIA2_VP_RAM_ADDR_L; cmd.buffer.registers[6].value = 0xE3; cmd.buffer.registers[7].index = CPIA2_VP_RAM_DATA; cmd.buffer.registers[7].value = 0x02; cmd.buffer.registers[8].index = CPIA2_VP_RAM_DATA; cmd.buffer.registers[8].value = 0xFC; cmd.direction = TRANSFER_WRITE; cmd.reg_count = 9; cpia2_send_command(cam, &cmd); } /* Activate all settings and start the data stream */ /* Set user mode */ set_default_user_mode(cam); /* Give VP time to wake up */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ set_all_properties(cam); cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0); DBG("After SetAllProperties(cam), user mode is 0x%0X\n", cam->params.vp_params.video_mode); /*** * Set audio regulator off. This and the code to set the compresison * state are too complex to form a CPIA2_CMD_, and seem to be somewhat * intertwined. This stuff came straight from the windows driver. ***/ /* Turn AutoExposure off in VP and enable the serial bridge to the sensor */ cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0); tmp_reg = cam->params.vp_params.system_ctrl; cmd.buffer.registers[0].value = tmp_reg & (tmp_reg & (CPIA2_VP_SYSTEMCTRL_HK_CONTROL ^ 0xFF)); cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0); cmd.buffer.registers[1].value = cam->params.vp_params.device_config | CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE; cmd.buffer.registers[0].index = CPIA2_VP_SYSTEMCTRL; cmd.buffer.registers[1].index = CPIA2_VP_DEVICE_CONFIG; cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP; cmd.reg_count = 2; cmd.direction = TRANSFER_WRITE; cmd.start = 0; cpia2_send_command(cam, &cmd); /* Set the correct I2C address in the CPiA-2 system register */ cpia2_do_command(cam, CPIA2_CMD_SET_SERIAL_ADDR, TRANSFER_WRITE, CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR); /* Now have sensor access - set bit to turn the audio regulator off */ cpia2_do_command(cam, CPIA2_CMD_SET_SENSOR_CR1, TRANSFER_WRITE, CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR); /* Set the correct I2C address in the CPiA-2 system register */ if (cam->params.pnp_id.device_type == DEVICE_STV_672) cpia2_do_command(cam, CPIA2_CMD_SET_SERIAL_ADDR, TRANSFER_WRITE, CPIA2_SYSTEM_VP_SERIAL_ADDR_VP); // 0x88 else cpia2_do_command(cam, CPIA2_CMD_SET_SERIAL_ADDR, TRANSFER_WRITE, CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP); // 0x8a /* increase signal drive strength */ if (cam->params.pnp_id.device_type == DEVICE_STV_676) cpia2_do_command(cam, CPIA2_CMD_SET_VP_EXP_MODES, TRANSFER_WRITE, CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP); /* Start autoexposure */ cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0); cmd.buffer.registers[0].value = cam->params.vp_params.device_config & (CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE ^ 0xFF); cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0); cmd.buffer.registers[1].value = cam->params.vp_params.system_ctrl | CPIA2_VP_SYSTEMCTRL_HK_CONTROL; cmd.buffer.registers[0].index = CPIA2_VP_DEVICE_CONFIG; cmd.buffer.registers[1].index = CPIA2_VP_SYSTEMCTRL; cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP; cmd.reg_count = 2; cmd.direction = TRANSFER_WRITE; cpia2_send_command(cam, &cmd); /* Set compression state */ cpia2_do_command(cam, CPIA2_CMD_GET_VC_CONTROL, TRANSFER_READ, 0); if (cam->params.compression.inhibit_htables) { tmp_reg = cam->params.vc_params.vc_control | CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES; } else { tmp_reg = cam->params.vc_params.vc_control & ~CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES; } cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg); /* Set target size (kb) on vc */ cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB, TRANSFER_WRITE, cam->params.vc_params.target_kb); /* Wiggle VC Reset */ /*** * First read and wait a bit. ***/ for (i = 0; i < 50; i++) { cpia2_do_command(cam, CPIA2_CMD_GET_PW_CONTROL, TRANSFER_READ, 0); } tmp_reg = cam->params.vc_params.pw_control; tmp_reg &= ~CPIA2_VC_PW_CTRL_VC_RESET_N; cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg); tmp_reg |= CPIA2_VC_PW_CTRL_VC_RESET_N; cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg); cpia2_do_command(cam, CPIA2_CMD_SET_DEF_JPEG_OPT, TRANSFER_WRITE, 0); cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0); DBG("After VC RESET, user mode is 0x%0X\n", cam->params.vp_params.video_mode); return retval;}/******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -