static int32_t ov10820_match_id(struct msm_sensor_ctrl_t *s_ctrl) { int32_t rc = 0; uint16_t chipid = 0; if (ov660_check_probe(s_ctrl) >= 0) ov660_exists = true; if (ov660_exists) ov660_set_i2c_bypass(s_ctrl, (int)1); /* Query each i2c slave address for the camera to if the * part exists since the sensor has two possible i2c slave * addresses. */ rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read( s_ctrl->sensor_i2c_client, s_ctrl->sensordata->slave_info->sensor_id_reg_addr, &chipid, MSM_CAMERA_I2C_WORD_DATA); if (rc >= 0) goto check_chipid; s_ctrl->sensordata->slave_info->sensor_slave_addr = OV10820_SECONDARY_I2C_ADDRESS; s_ctrl->sensor_i2c_client->cci_client->sid = (OV10820_SECONDARY_I2C_ADDRESS >> 1); rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read( s_ctrl->sensor_i2c_client, s_ctrl->sensordata->slave_info->sensor_id_reg_addr, &chipid, MSM_CAMERA_I2C_WORD_DATA); if (rc < 0) { pr_err("ov10820_match_id read failed"); return rc; } check_chipid: if (chipid != s_ctrl->sensordata->slave_info->sensor_id) { pr_err("%s: chip id %x does not match expected %x\n", __func__, chipid, s_ctrl->sensordata-> slave_info->sensor_id); return -ENODEV; } /* Check hardware revision */ rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read( s_ctrl->sensor_i2c_client, OV10820_HW_REV_REG, &ov10820_hw_rev, MSM_CAMERA_I2C_BYTE_DATA); if (rc < 0) { pr_err("%s: unable to determine hw rev of sensor!\n", __func__); return rc; } pr_info("%s: success addr:0x%x hw:0x%x\n", __func__, s_ctrl->sensor_i2c_client->cci_client->sid, ov10820_hw_rev); return 0; }
/* TBD: Need to revisit*/ static int32_t ov10820_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl, uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain) { uint32_t fl_lines, offset; uint8_t int_time[3]; fl_lines = (s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10; offset = s_ctrl->sensor_exp_gain_info->vert_offset; if (line > (fl_lines - offset)) fl_lines = line + offset; fl_lines += (fl_lines & 0x1); int_time[0] = line >> 12; int_time[1] = line >> 4; int_time[2] = line << 4; if (allow_asic_control) { msm_camera_i2c_write(s_ctrl->sensor_i2c_client, s_ctrl->sensor_output_reg_addr-> frame_length_lines, fl_lines, MSM_CAMERA_I2C_WORD_DATA); ov660_set_i2c_bypass(0); ov660_set_exposure_gain(gain, line); ov660_set_i2c_bypass(1); } else { s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl); msm_camera_i2c_write(s_ctrl->sensor_i2c_client, s_ctrl->sensor_output_reg_addr-> frame_length_lines, fl_lines, MSM_CAMERA_I2C_WORD_DATA); msm_camera_i2c_write_seq(s_ctrl->sensor_i2c_client, s_ctrl->sensor_exp_gain_info-> coarse_int_time_addr, &int_time[0], 3); msm_camera_i2c_write(s_ctrl->sensor_i2c_client, s_ctrl->sensor_exp_gain_info-> global_gain_addr, gain, MSM_CAMERA_I2C_BYTE_DATA); s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl); if (update_ov660_gain) ov660_set_exposure_gain2(gain, line); } return 0; }
static int32_t ov10820_check_i2c_configuration(struct msm_sensor_ctrl_t *s_ctrl) { int32_t rc = 0; uint16_t chipid = 0; ov660_set_i2c_bypass(0); rc = msm_camera_i2c_read( s_ctrl->sensor_i2c_client, s_ctrl->sensor_id_info->sensor_id_reg_addr, &chipid, MSM_CAMERA_I2C_BYTE_DATA); if (rc < 0) { pr_info("%s: I2C is configured through ASIC.\n", __func__); allow_asic_control = true; rc = ov660_add_blc_firmware(s_ctrl->sensor_i2c_addr); if (rc < 0) pr_err("%s: Unable to set blc firmware!\n", __func__); } else { pr_info("%s: I2C is configured around ASIC.\n", __func__); allow_asic_control = false; rc = ov660_use_work_around_blc(); if (rc < 0) pr_err("%s: unable to set ov660 blc workaround!\n", __func__); rc = msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client, ov10820_BLC_work_around_settings, ARRAY_SIZE(ov10820_BLC_work_around_settings), MSM_CAMERA_I2C_BYTE_DATA); if (rc < 0) pr_err("%s: unable to write 10MP blc workaround!\n", __func__); } ov660_set_i2c_bypass(1); return 0; }
static int32_t ov10820_check_hw_rev(struct msm_sensor_ctrl_t *s_ctrl) { int32_t rc = 0; ov660_set_i2c_bypass(1); rc = msm_camera_i2c_read( s_ctrl->sensor_i2c_client, 0x302A, &revision, MSM_CAMERA_I2C_BYTE_DATA); if (rc < 0) { pr_err("%s: unable to read revision (%d)\n", __func__, rc); } else { pr_info("%s: revision is 0x%x\n", __func__, revision); if (revision == 0xB1) { pr_info("%s: new revision, using no BLC fix\n", __func__); allow_asic_control = false; return 0; } } return rc; }
static int32_t ov10820_match_id(struct msm_sensor_ctrl_t *s_ctrl) { int32_t rc = 0; uint16_t chipid = 0; struct msm_camera_sensor_info *info = s_ctrl->sensordata; if (!info->oem_data) { pr_err("%s: oem data NULL in sensor info, aborting", __func__); return -EINVAL; } if (ov660_check_probe() >= 0) ov660_exists = true; if (ov660_exists) { ov660_set_i2c_bypass(1); if (ov10820_ov660_rev_check == 0x1) { ov660_read_revision(); /* Reset Flag automatically */ ov10820_ov660_rev_check = 0x0; return -EINVAL; } } /* TODO Need to understand if better way to read chip id is * by the OTP or by normal method per below */ /*Read sensor id*/ rc = msm_camera_i2c_read( s_ctrl->sensor_i2c_client, s_ctrl->sensor_id_info->sensor_id_reg_addr, &chipid, MSM_CAMERA_I2C_BYTE_DATA); if (rc >= 0) goto check_chipid; /* Need to re-assign i2c address to secondary address of the * sensor to see if the part exists under the second address. */ s_ctrl->sensor_i2c_addr = OV10820_SECONDARY_I2C_ADDRESS; s_ctrl->sensor_i2c_client->client->addr = OV10820_SECONDARY_I2C_ADDRESS; rc = msm_camera_i2c_read( s_ctrl->sensor_i2c_client, s_ctrl->sensor_id_info->sensor_id_reg_addr, &chipid, MSM_CAMERA_I2C_BYTE_DATA); if (rc < 0) { pr_err("%s: read id failed\n", __func__); return rc; } check_chipid: if (chipid != s_ctrl->sensor_id_info->sensor_id) { pr_err("%s: chip id %x does not match expected %x\n", __func__, chipid, s_ctrl->sensor_id_info->sensor_id); return -ENODEV; } ov10820_check_hw_rev(s_ctrl); if (ov660_exists) { ov660_initialize_10MP(revision); usleep(10000); } /* Need to determine when to apply BLC firmware fix * or when to use the old method of blc work around fix */ if (revision <= 0xB0) ov10820_check_i2c_configuration(s_ctrl); pr_debug("%s: success and using i2c address of: %x\n", __func__, s_ctrl->sensor_i2c_client->client->addr); ov10820_init_confs(s_ctrl); if ((!ov660_exists) && (info->oem_data->sensor_allow_asic_bypass != 1)) { pr_err("%s: detected 10mp, but asic not working!\n", __func__); return -ENODEV; } ov660_set_i2c_bypass(1); rc = ov10820_read_otp(&ov10820_s_ctrl); if (rc < 0) { pr_err("%s: unable to read otp data!\n", __func__); ov10820_otp_info.size = 0; } else { ov10820_otp_info.otp_info = (uint8_t *)ov10820_otp; ov10820_otp_info.size = OV10820_OTP_SIZE; } ov10820_otp_info.asic_rev = info->oem_data->sensor_asic_revision; return 0; }