msm: camera: sensor: Support for read operation

Supporting read operation for sensor and
sub modules OIS and actuator.

CRs-Fixed: 2538801
Change-Id: I83ad154dd577d5a664c4d68792a90489e725fbfd
Signed-off-by: Jigarkumar Zala <jzala@codeaurora.org>
Signed-off-by: Sureshnaidu Laveti <lsuresh@codeaurora.org>
This commit is contained in:
Sureshnaidu Laveti
2019-11-18 14:00:11 -08:00
committed by Gerrit - the friendly Code Review server
parent dd1ac7b717
commit 50e83233ad
8 changed files with 495 additions and 20 deletions

View File

@@ -554,7 +554,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
rc = cam_sensor_i2c_command_parser(
&a_ctrl->io_master_info,
i2c_reg_settings,
&cmd_desc[i], 1);
&cmd_desc[i], 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"Failed:parse init settings: %d",
@@ -612,7 +612,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
rc = cam_sensor_i2c_command_parser(
&a_ctrl->io_master_info,
i2c_reg_settings,
cmd_desc, 1);
cmd_desc, 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"Auto move lens parsing failed: %d", rc);
@@ -643,7 +643,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
rc = cam_sensor_i2c_command_parser(
&a_ctrl->io_master_info,
i2c_reg_settings,
cmd_desc, 1);
cmd_desc, 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"Manual move lens parsing failed: %d", rc);
@@ -662,6 +662,68 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
}
cam_actuator_update_req_mgr(a_ctrl, csl_packet);
break;
case CAM_ACTUATOR_PACKET_OPCODE_READ: {
struct cam_buf_io_cfg *io_cfg;
struct i2c_settings_array i2c_read_settings;
if (a_ctrl->cam_act_state < CAM_ACTUATOR_CONFIG) {
rc = -EINVAL;
CAM_WARN(CAM_ACTUATOR,
"Not in right state to read actuator: %d",
a_ctrl->cam_act_state);
goto end;
}
CAM_DBG(CAM_ACTUATOR, "number of I/O configs: %d:",
csl_packet->num_io_configs);
if (csl_packet->num_io_configs == 0) {
CAM_ERR(CAM_ACTUATOR, "No I/O configs to process");
rc = -EINVAL;
goto end;
}
INIT_LIST_HEAD(&(i2c_read_settings.list_head));
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&csl_packet->payload +
csl_packet->io_configs_offset);
if (io_cfg == NULL) {
CAM_ERR(CAM_ACTUATOR, "I/O config is invalid(NULL)");
rc = -EINVAL;
goto end;
}
offset = (uint32_t *)&csl_packet->payload;
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
i2c_read_settings.is_settings_valid = 1;
i2c_read_settings.request_id = 0;
rc = cam_sensor_i2c_command_parser(&a_ctrl->io_master_info,
&i2c_read_settings,
cmd_desc, 1, io_cfg);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"actuator read pkt parsing failed: %d", rc);
goto end;
}
rc = cam_sensor_i2c_read_data(
&i2c_read_settings,
&a_ctrl->io_master_info);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR, "cannot read data, rc:%d", rc);
delete_request(&i2c_read_settings);
goto end;
}
rc = delete_request(&i2c_read_settings);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"Failed in deleting the read settings");
goto end;
}
break;
}
default:
CAM_ERR(CAM_ACTUATOR, "Wrong Opcode: %d",
csl_packet->header.op_code & 0xFFFFFF);

View File

@@ -1070,7 +1070,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
rc = cam_sensor_i2c_command_parser(
&fctrl->io_master_info,
i2c_reg_settings,
&cmd_desc[i], 1);
&cmd_desc[i], 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_FLASH,
"pkt parsing failed: %d", rc);
@@ -1150,7 +1150,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
rc = cam_sensor_i2c_command_parser(
&fctrl->io_master_info,
i2c_reg_settings, cmd_desc, 1);
i2c_reg_settings, cmd_desc, 1, NULL);
if (rc) {
CAM_ERR(CAM_FLASH,
"Failed in parsing i2c packets");
@@ -1181,7 +1181,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
rc = cam_sensor_i2c_command_parser(
&fctrl->io_master_info,
i2c_reg_settings, cmd_desc, 1);
i2c_reg_settings, cmd_desc, 1, NULL);
if (rc) {
CAM_ERR(CAM_FLASH,
"Failed in parsing i2c NRT packets");

View File

@@ -540,7 +540,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
rc = cam_sensor_i2c_command_parser(
&o_ctrl->io_master_info,
i2c_reg_settings,
&cmd_desc[i], 1);
&cmd_desc[i], 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_OIS,
"init parsing failed: %d", rc);
@@ -557,7 +557,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
rc = cam_sensor_i2c_command_parser(
&o_ctrl->io_master_info,
i2c_reg_settings,
&cmd_desc[i], 1);
&cmd_desc[i], 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Calib parsing failed: %d", rc);
@@ -629,7 +629,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
i2c_reg_settings->request_id = 0;
rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info,
i2c_reg_settings,
cmd_desc, 1);
cmd_desc, 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc);
return rc;
@@ -648,6 +648,67 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
return rc;
}
break;
case CAM_OIS_PACKET_OPCODE_READ: {
struct cam_buf_io_cfg *io_cfg;
struct i2c_settings_array i2c_read_settings;
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
rc = -EINVAL;
CAM_WARN(CAM_OIS,
"Not in right state to read OIS: %d",
o_ctrl->cam_ois_state);
return rc;
}
CAM_DBG(CAM_OIS, "number of I/O configs: %d:",
csl_packet->num_io_configs);
if (csl_packet->num_io_configs == 0) {
CAM_ERR(CAM_OIS, "No I/O configs to process");
rc = -EINVAL;
return rc;
}
INIT_LIST_HEAD(&(i2c_read_settings.list_head));
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&csl_packet->payload +
csl_packet->io_configs_offset);
if (io_cfg == NULL) {
CAM_ERR(CAM_OIS, "I/O config is invalid(NULL)");
rc = -EINVAL;
return rc;
}
offset = (uint32_t *)&csl_packet->payload;
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
i2c_read_settings.is_settings_valid = 1;
i2c_read_settings.request_id = 0;
rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info,
&i2c_read_settings,
cmd_desc, 1, io_cfg);
if (rc < 0) {
CAM_ERR(CAM_OIS, "OIS read pkt parsing failed: %d", rc);
return rc;
}
rc = cam_sensor_i2c_read_data(
&i2c_read_settings,
&o_ctrl->io_master_info);
if (rc < 0) {
CAM_ERR(CAM_OIS, "cannot read data rc: %d", rc);
delete_request(&i2c_read_settings);
return rc;
}
rc = delete_request(&i2c_read_settings);
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Failed in deleting the read settings");
return rc;
}
break;
}
default:
CAM_ERR(CAM_OIS, "Invalid Opcode: %d",
(csl_packet->header.op_code & 0xFFFFFF));

View File

@@ -87,6 +87,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
struct cam_control *ioctl_ctrl = NULL;
struct cam_packet *csl_packet = NULL;
struct cam_cmd_buf_desc *cmd_desc = NULL;
struct cam_buf_io_cfg *io_cfg = NULL;
struct i2c_settings_array *i2c_reg_settings = NULL;
size_t len_of_buff = 0;
size_t remain_len = 0;
@@ -187,7 +188,28 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
i2c_reg_settings->is_settings_valid = 1;
break;
}
case CAM_SENSOR_PACKET_OPCODE_SENSOR_READ: {
i2c_reg_settings = &(i2c_data->read_settings);
i2c_reg_settings->request_id = 0;
i2c_reg_settings->is_settings_valid = 1;
CAM_DBG(CAM_SENSOR, "number of IO configs: %d:",
csl_packet->num_io_configs);
if (csl_packet->num_io_configs == 0) {
CAM_ERR(CAM_SENSOR, "No I/O configs to process");
goto end;
}
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&csl_packet->payload +
csl_packet->io_configs_offset);
if (io_cfg == NULL) {
CAM_ERR(CAM_SENSOR, "I/O config is invalid(NULL)");
goto end;
}
break;
}
case CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE: {
if ((s_ctrl->sensor_state == CAM_SENSOR_INIT) ||
(s_ctrl->sensor_state == CAM_SENSOR_ACQUIRE)) {
@@ -239,7 +261,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
rc = cam_sensor_i2c_command_parser(&s_ctrl->io_master_info,
i2c_reg_settings, cmd_desc, 1);
i2c_reg_settings, cmd_desc, 1, io_cfg);
if (rc < 0) {
CAM_ERR(CAM_SENSOR, "Fail parsing I2C Pkt: %d", rc);
goto end;
@@ -951,6 +973,24 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
}
s_ctrl->sensor_state = CAM_SENSOR_CONFIG;
}
if (s_ctrl->i2c_data.read_settings.is_settings_valid) {
rc = cam_sensor_i2c_read_data(
&s_ctrl->i2c_data.read_settings,
&s_ctrl->io_master_info);
if (rc < 0) {
CAM_ERR(CAM_SENSOR, "cannot read data: %d", rc);
delete_request(&s_ctrl->i2c_data.read_settings);
goto release_mutex;
}
rc = delete_request(
&s_ctrl->i2c_data.read_settings);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Fail in deleting the read settings");
goto release_mutex;
}
}
}
break;
default:

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*/
#include "cam_sensor_dev.h"
@@ -179,6 +179,7 @@ static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client,
INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head));
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head));
@@ -314,6 +315,7 @@ static int32_t cam_sensor_driver_platform_probe(
INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head));
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head));

View File

@@ -152,13 +152,15 @@ enum cam_sensor_packet_opcodes {
CAM_SENSOR_PACKET_OPCODE_SENSOR_PROBE,
CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG,
CAM_SENSOR_PACKET_OPCODE_SENSOR_STREAMOFF,
CAM_SENSOR_PACKET_OPCODE_SENSOR_READ,
CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP = 127
};
enum cam_actuator_packet_opcodes {
CAM_ACTUATOR_PACKET_OPCODE_INIT,
CAM_ACTUATOR_PACKET_AUTO_MOVE_LENS,
CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS
CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS,
CAM_ACTUATOR_PACKET_OPCODE_READ
};
enum cam_eeprom_packet_opcodes {
@@ -168,7 +170,8 @@ enum cam_eeprom_packet_opcodes {
enum cam_ois_packet_opcodes {
CAM_OIS_PACKET_OPCODE_INIT,
CAM_OIS_PACKET_OPCODE_OIS_CONTROL
CAM_OIS_PACKET_OPCODE_OIS_CONTROL,
CAM_OIS_PACKET_OPCODE_READ
};
enum msm_bus_perf_setting {
@@ -218,7 +221,8 @@ enum cam_sensor_i2c_cmd_type {
CAM_SENSOR_I2C_WRITE_RANDOM,
CAM_SENSOR_I2C_WRITE_BURST,
CAM_SENSOR_I2C_WRITE_SEQ,
CAM_SENSOR_I2C_READ,
CAM_SENSOR_I2C_READ_RANDOM,
CAM_SENSOR_I2C_READ_SEQ,
CAM_SENSOR_I2C_POLL
};
@@ -270,6 +274,8 @@ struct cam_sensor_i2c_reg_setting {
enum camera_sensor_i2c_type addr_type;
enum camera_sensor_i2c_type data_type;
unsigned short delay;
uint8_t *read_buff;
uint32_t read_buff_len;
};
struct cam_sensor_i2c_seq_reg {
@@ -297,6 +303,7 @@ struct i2c_data_settings {
struct i2c_settings_array config_settings;
struct i2c_settings_array streamon_settings;
struct i2c_settings_array streamoff_settings;
struct i2c_settings_array read_settings;
struct i2c_settings_array *per_frame;
};

View File

@@ -233,6 +233,134 @@ static int32_t cam_sensor_handle_continuous_write(
return rc;
}
static int32_t cam_sensor_get_io_buffer(
struct cam_buf_io_cfg *io_cfg,
struct cam_sensor_i2c_reg_setting *i2c_settings)
{
uintptr_t buf_addr = 0x0;
size_t buf_size = 0;
int32_t rc = 0;
if (io_cfg->direction == CAM_BUF_OUTPUT) {
rc = cam_mem_get_cpu_buf(io_cfg->mem_handle[0],
&buf_addr, &buf_size);
if ((rc < 0) || (!buf_addr)) {
CAM_ERR(CAM_SENSOR,
"invalid buffer, rc: %d, buf_addr: %pK",
rc, buf_addr);
return -EINVAL;
}
CAM_DBG(CAM_SENSOR,
"buf_addr: %pK, buf_size: %zu, offsetsize: %d",
(void *)buf_addr, buf_size, io_cfg->offsets[0]);
if (io_cfg->offsets[0] >= buf_size) {
CAM_ERR(CAM_SENSOR,
"invalid size:io_cfg->offsets[0]: %d, buf_size: %d",
io_cfg->offsets[0], buf_size);
return -EINVAL;
}
i2c_settings->read_buff =
(uint8_t *)buf_addr + io_cfg->offsets[0];
i2c_settings->read_buff_len =
buf_size - io_cfg->offsets[0];
} else {
CAM_ERR(CAM_SENSOR, "Invalid direction: %d",
io_cfg->direction);
rc = -EINVAL;
}
return rc;
}
static int32_t cam_sensor_handle_random_read(
struct cam_cmd_i2c_random_rd *cmd_i2c_random_rd,
struct i2c_settings_array *i2c_reg_settings,
uint16_t *cmd_length_in_bytes,
int32_t *offset,
struct list_head **list,
struct cam_buf_io_cfg *io_cfg)
{
struct i2c_settings_list *i2c_list;
int32_t rc = 0, cnt = 0;
i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings,
cmd_i2c_random_rd->header.count);
if ((i2c_list == NULL) ||
(i2c_list->i2c_settings.reg_setting == NULL)) {
CAM_ERR(CAM_SENSOR,
"Failed in allocating i2c_list: %pK",
i2c_list);
return -ENOMEM;
}
rc = cam_sensor_get_io_buffer(io_cfg, &(i2c_list->i2c_settings));
if (rc) {
CAM_ERR(CAM_SENSOR, "Failed to get read buffer: %d", rc);
} else {
*cmd_length_in_bytes = sizeof(struct i2c_rdwr_header) +
(sizeof(struct cam_cmd_read) *
(cmd_i2c_random_rd->header.count));
i2c_list->op_code = CAM_SENSOR_I2C_READ_RANDOM;
i2c_list->i2c_settings.addr_type =
cmd_i2c_random_rd->header.addr_type;
i2c_list->i2c_settings.data_type =
cmd_i2c_random_rd->header.data_type;
i2c_list->i2c_settings.size =
cmd_i2c_random_rd->header.count;
for (cnt = 0; cnt < (cmd_i2c_random_rd->header.count);
cnt++) {
i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
cmd_i2c_random_rd->data_read[cnt].reg_data;
}
*offset = cnt;
*list = &(i2c_list->list);
}
return rc;
}
static int32_t cam_sensor_handle_continuous_read(
struct cam_cmd_i2c_continuous_rd *cmd_i2c_continuous_rd,
struct i2c_settings_array *i2c_reg_settings,
uint16_t *cmd_length_in_bytes, int32_t *offset,
struct list_head **list,
struct cam_buf_io_cfg *io_cfg)
{
struct i2c_settings_list *i2c_list;
int32_t rc = 0, cnt = 0;
i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings, 1);
if ((i2c_list == NULL) ||
(i2c_list->i2c_settings.reg_setting == NULL)) {
CAM_ERR(CAM_SENSOR,
"Failed in allocating i2c_list: %pK",
i2c_list);
return -ENOMEM;
}
rc = cam_sensor_get_io_buffer(io_cfg, &(i2c_list->i2c_settings));
if (rc) {
CAM_ERR(CAM_SENSOR, "Failed to get read buffer: %d", rc);
} else {
*cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd);
i2c_list->op_code = CAM_SENSOR_I2C_READ_SEQ;
i2c_list->i2c_settings.addr_type =
cmd_i2c_continuous_rd->header.addr_type;
i2c_list->i2c_settings.data_type =
cmd_i2c_continuous_rd->header.data_type;
i2c_list->i2c_settings.size =
cmd_i2c_continuous_rd->header.count;
i2c_list->i2c_settings.reg_setting[0].reg_addr =
cmd_i2c_continuous_rd->reg_addr;
*offset = cnt;
*list = &(i2c_list->list);
}
return rc;
}
static int cam_sensor_handle_slave_info(
struct camera_io_master *io_master,
uint32_t *cmd_buf)
@@ -271,8 +399,11 @@ static int cam_sensor_handle_slave_info(
/**
* Name : cam_sensor_i2c_command_parser
* Description : Parse CSL CCI packet and apply register settings
* Parameters : s_ctrl input/output sub_device
* arg input cam_control
* Parameters : io_master input master information
* i2c_reg_settings output register settings to fill
* cmd_desc input command description
* num_cmd_buffers input number of command buffers to process
* io_cfg input buffer details for read operation only
* Description :
* Handle multiple I2C RD/WR and WAIT cmd formats in one command
* buffer, for example, a command buffer of m x RND_WR + 1 x HW_
@@ -283,11 +414,12 @@ int cam_sensor_i2c_command_parser(
struct camera_io_master *io_master,
struct i2c_settings_array *i2c_reg_settings,
struct cam_cmd_buf_desc *cmd_desc,
int32_t num_cmd_buffers)
int32_t num_cmd_buffers,
struct cam_buf_io_cfg *io_cfg)
{
int16_t rc = 0, i = 0;
size_t len_of_buff = 0;
uintptr_t generic_ptr;
uintptr_t generic_ptr;
uint16_t cmd_length_in_bytes = 0;
size_t remain_len = 0;
size_t tot_size = 0;
@@ -472,7 +604,7 @@ int cam_sensor_i2c_command_parser(
}
case CAMERA_SENSOR_CMD_TYPE_I2C_INFO: {
if (remain_len - byte_cnt <
sizeof(struct cam_cmd_i2c_info)) {
sizeof(struct cam_cmd_i2c_info)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer space");
rc = -EINVAL;
@@ -493,6 +625,88 @@ int cam_sensor_i2c_command_parser(
byte_cnt += cmd_length_in_bytes;
break;
}
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_RD: {
uint16_t cmd_length_in_bytes = 0;
struct cam_cmd_i2c_random_rd *i2c_random_rd =
(struct cam_cmd_i2c_random_rd *)cmd_buf;
if (remain_len - byte_cnt <
sizeof(struct cam_cmd_i2c_random_rd)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer space");
rc = -EINVAL;
goto end;
}
tot_size = sizeof(struct i2c_rdwr_header) +
(sizeof(struct cam_cmd_read) *
i2c_random_rd->header.count);
if (tot_size > (remain_len - byte_cnt)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer provided %d, %d, %d",
tot_size, remain_len, byte_cnt);
rc = -EINVAL;
goto end;
}
rc = cam_sensor_handle_random_read(
i2c_random_rd,
i2c_reg_settings,
&cmd_length_in_bytes, &j, &list,
io_cfg);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed in random read %d", rc);
goto end;
}
cmd_buf += cmd_length_in_bytes /
sizeof(uint32_t);
byte_cnt += cmd_length_in_bytes;
break;
}
case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD: {
uint16_t cmd_length_in_bytes = 0;
struct cam_cmd_i2c_continuous_rd
*i2c_continuous_rd =
(struct cam_cmd_i2c_continuous_rd *)cmd_buf;
if (remain_len - byte_cnt <
sizeof(struct cam_cmd_i2c_continuous_rd)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer space");
rc = -EINVAL;
goto end;
}
tot_size =
sizeof(struct cam_cmd_i2c_continuous_rd);
if (tot_size > (remain_len - byte_cnt)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer provided %d, %d, %d",
tot_size, remain_len, byte_cnt);
rc = -EINVAL;
goto end;
}
rc = cam_sensor_handle_continuous_read(
i2c_continuous_rd,
i2c_reg_settings,
&cmd_length_in_bytes, &j, &list,
io_cfg);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed in continuous read %d", rc);
goto end;
}
cmd_buf += cmd_length_in_bytes /
sizeof(uint32_t);
byte_cnt += cmd_length_in_bytes;
break;
}
default:
CAM_ERR(CAM_SENSOR, "Invalid Command Type:%d",
cmm_hdr->cmd_type);
@@ -576,6 +790,90 @@ int cam_sensor_util_i2c_apply_setting(
return rc;
}
int32_t cam_sensor_i2c_read_data(
struct i2c_settings_array *i2c_settings,
struct camera_io_master *io_master_info)
{
int32_t rc = 0;
struct i2c_settings_list *i2c_list;
uint32_t cnt = 0;
uint8_t *read_buff = NULL;
uint32_t buff_length = 0;
uint32_t read_length = 0;
list_for_each_entry(i2c_list,
&(i2c_settings->list_head), list) {
read_buff = i2c_list->i2c_settings.read_buff;
buff_length = i2c_list->i2c_settings.read_buff_len;
if ((read_buff == NULL) || (buff_length == 0)) {
CAM_ERR(CAM_SENSOR,
"Invalid input buffer, buffer: %pK, length: %d",
read_buff, buff_length);
return -EINVAL;
}
if (i2c_list->op_code == CAM_SENSOR_I2C_READ_RANDOM) {
read_length = i2c_list->i2c_settings.data_type *
i2c_list->i2c_settings.size;
if ((read_length > buff_length) ||
(read_length < i2c_list->i2c_settings.size)) {
CAM_ERR(CAM_SENSOR,
"Invalid size, readLen:%d, bufLen:%d, size: %d",
read_length, buff_length,
i2c_list->i2c_settings.size);
return -EINVAL;
}
for (cnt = 0; cnt < (i2c_list->i2c_settings.size);
cnt++) {
struct cam_sensor_i2c_reg_array *reg_setting =
&(i2c_list->i2c_settings.reg_setting[cnt]);
rc = camera_io_dev_read(io_master_info,
reg_setting->reg_addr,
&reg_setting->reg_data,
i2c_list->i2c_settings.addr_type,
i2c_list->i2c_settings.data_type);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed: random read I2C settings: %d",
rc);
return rc;
}
if (i2c_list->i2c_settings.data_type <
CAMERA_SENSOR_I2C_TYPE_MAX) {
memcpy(read_buff,
&reg_setting->reg_data,
i2c_list->i2c_settings.data_type);
read_buff +=
i2c_list->i2c_settings.data_type;
}
}
} else if (i2c_list->op_code == CAM_SENSOR_I2C_READ_SEQ) {
read_length = i2c_list->i2c_settings.size;
if (read_length > buff_length) {
CAM_ERR(CAM_SENSOR,
"Invalid buffer size, readLen: %d, bufLen: %d",
read_length, buff_length);
return -EINVAL;
}
rc = camera_io_dev_read_seq(
io_master_info,
i2c_list->i2c_settings.reg_setting[0].reg_addr,
read_buff,
i2c_list->i2c_settings.addr_type,
i2c_list->i2c_settings.data_type,
i2c_list->i2c_settings.size);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"failed: seq read I2C settings: %d",
rc);
return rc;
}
}
}
return rc;
}
int32_t msm_camera_fill_vreg_params(
struct cam_hw_soc_info *soc_info,
struct cam_sensor_power_setting *power_setting,

View File

@@ -30,11 +30,16 @@ int msm_camera_pinctrl_init
int cam_sensor_i2c_command_parser(struct camera_io_master *io_master,
struct i2c_settings_array *i2c_reg_settings,
struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers);
struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers,
struct cam_buf_io_cfg *io_cfg);
int cam_sensor_util_i2c_apply_setting(struct camera_io_master *io_master_info,
struct i2c_settings_list *i2c_list);
int32_t cam_sensor_i2c_read_data(
struct i2c_settings_array *i2c_settings,
struct camera_io_master *io_master_info);
int32_t delete_request(struct i2c_settings_array *i2c_array);
int cam_sensor_util_request_gpio_table(
struct cam_hw_soc_info *soc_info, int gpio_en);