Bläddra i källkod

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 <[email protected]>
Signed-off-by: Sureshnaidu Laveti <[email protected]>
Sureshnaidu Laveti 5 år sedan
förälder
incheckning
50e83233ad

+ 65 - 3
drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c

@@ -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);

+ 3 - 3
drivers/cam_sensor_module/cam_flash/cam_flash_core.c

@@ -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");

+ 64 - 3
drivers/cam_sensor_module/cam_ois/cam_ois_core.c

@@ -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));

+ 41 - 1
drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c

@@ -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:

+ 3 - 1
drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.c

@@ -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));

+ 10 - 3
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h

@@ -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;
 };
 

+ 303 - 5
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c

@@ -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,

+ 6 - 1
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h

@@ -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);