Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b6954df authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: sensor: Add support for Multimodule"

parents fab1a14a b86417c9
Loading
Loading
Loading
Loading
+477 −4
Original line number Diff line number Diff line
// 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 <linux/module.h>
@@ -12,6 +12,8 @@
#include "cam_debug_util.h"
#include "cam_common_util.h"

#define MAX_READ_SIZE  0x7FFFF

/**
 * cam_eeprom_read_memory() - read map data into buffer
 * @e_ctrl:     eeprom control struct
@@ -67,6 +69,7 @@ static int cam_eeprom_read_memory(struct cam_eeprom_ctrl_t *e_ctrl,
					rc);
				return rc;
			}
			memptr = block->mapdata + emap[j].mem.valid_size;
		}

		if (emap[j].pageen.valid_size) {
@@ -404,7 +407,7 @@ static int32_t cam_eeprom_update_slaveInfo(struct cam_eeprom_ctrl_t *e_ctrl,
 */
static int32_t cam_eeprom_parse_memory_map(
	struct cam_eeprom_memory_block_t *data,
	void *cmd_buf, int cmd_length, uint16_t *cmd_length_bytes,
	void *cmd_buf, int cmd_length, uint32_t *cmd_length_bytes,
	int *num_map)
{
	int32_t                            rc = 0;
@@ -420,7 +423,7 @@ static int32_t cam_eeprom_parse_memory_map(
	struct cam_cmd_conditional_wait   *i2c_poll = NULL;
	struct cam_cmd_unconditional_wait *i2c_uncond_wait = NULL;

	generic_op_code = cmm_hdr->third_byte;
	generic_op_code = cmm_hdr->fifth_byte;
	switch (cmm_hdr->cmd_type) {
	case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR:
		i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf;
@@ -510,6 +513,359 @@ static int32_t cam_eeprom_parse_memory_map(
	return rc;
}

static struct i2c_settings_list*
	cam_eeprom_get_i2c_ptr(struct i2c_settings_array *i2c_reg_settings,
		uint32_t size)
{
	struct i2c_settings_list *tmp;

	tmp = kzalloc(sizeof(struct i2c_settings_list), GFP_KERNEL);

	if (tmp != NULL)
		list_add_tail(&(tmp->list),
			&(i2c_reg_settings->list_head));
	else
		return NULL;

	tmp->seq_settings.reg_data =
		kcalloc(size, sizeof(uint8_t), GFP_KERNEL);
	if (tmp->seq_settings.reg_data == NULL) {
		list_del(&(tmp->list));
		kfree(tmp);
		tmp = NULL;
		return NULL;
	}
	tmp->seq_settings.size = size;

	return tmp;
}

static int32_t cam_eeprom_handle_continuous_write(
	struct cam_eeprom_ctrl_t *e_ctrl,
	struct cam_cmd_i2c_continuous_wr *cam_cmd_i2c_continuous_wr,
	struct i2c_settings_array *i2c_reg_settings,
	uint32_t *cmd_length_in_bytes, int32_t *offset,
	struct list_head **list)
{
	struct i2c_settings_list *i2c_list;
	int32_t rc = 0, cnt = 0;


	CAM_DBG(CAM_EEPROM, "Total Size: %d",
		cam_cmd_i2c_continuous_wr->header.count);

	i2c_list = cam_eeprom_get_i2c_ptr(i2c_reg_settings,
		cam_cmd_i2c_continuous_wr->header.count);
	if (i2c_list == NULL ||
		i2c_list->seq_settings.reg_data == NULL) {
		CAM_ERR(CAM_SENSOR, "Failed in allocating i2c_list");
		return -ENOMEM;
	}

	*cmd_length_in_bytes = (sizeof(struct i2c_rdwr_header) +
		sizeof(cam_cmd_i2c_continuous_wr->reg_addr) +
		sizeof(struct cam_cmd_read) *
		(cam_cmd_i2c_continuous_wr->header.count));
	if (cam_cmd_i2c_continuous_wr->header.op_code ==
		CAMERA_SENSOR_I2C_OP_CONT_WR_BRST)
		i2c_list->op_code = CAM_SENSOR_I2C_WRITE_BURST;
	else if (cam_cmd_i2c_continuous_wr->header.op_code ==
		CAMERA_SENSOR_I2C_OP_CONT_WR_SEQN)
		i2c_list->op_code = CAM_SENSOR_I2C_WRITE_SEQ;
	else {
		rc = -EINVAL;
		goto deallocate_i2c_list;
	}

	i2c_list->seq_settings.addr_type =
		cam_cmd_i2c_continuous_wr->header.addr_type;

	CAM_ERR(CAM_EEPROM, "Write Address: 0x%x",
		cam_cmd_i2c_continuous_wr->reg_addr);
	if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
		i2c_list->op_code = CAM_SENSOR_I2C_WRITE_RANDOM;
		e_ctrl->eebin_info.start_address =
			cam_cmd_i2c_continuous_wr->reg_addr;
		e_ctrl->eebin_info.size =
			cam_cmd_i2c_continuous_wr->header.count;
		CAM_DBG(CAM_EEPROM, "Header Count: %d",
			cam_cmd_i2c_continuous_wr->header.count);
		e_ctrl->eebin_info.is_valid = 1;

		i2c_list->seq_settings.reg_addr =
			cam_cmd_i2c_continuous_wr->reg_addr;
	} else
		CAM_ERR(CAM_EEPROM, "Burst Mode Not Supported\n");

	(*offset) += cnt;
	*list = &(i2c_list->list);
	return rc;
deallocate_i2c_list:
	kfree(i2c_list);
	return rc;
}

static int32_t cam_eeprom_handle_delay(
	uint32_t **cmd_buf,
	uint16_t generic_op_code,
	struct i2c_settings_array *i2c_reg_settings,
	uint32_t offset, uint32_t *byte_cnt,
	struct list_head *list_ptr,
	size_t remain_buf_len)
{
	int32_t rc = 0;
	struct i2c_settings_list *i2c_list = NULL;
	struct cam_cmd_unconditional_wait *cmd_uncond_wait =
		(struct cam_cmd_unconditional_wait *) *cmd_buf;

	if (remain_buf_len < (sizeof(struct cam_cmd_unconditional_wait))) {
		CAM_ERR(CAM_EEPROM, "Not Enough buffer");
		return -EINVAL;
	}

	if (list_ptr == NULL) {
		CAM_ERR(CAM_SENSOR, "Invalid list ptr");
		return -EINVAL;
	}

	if (offset > 0) {
		i2c_list =
			list_entry(list_ptr, struct i2c_settings_list, list);
		if (generic_op_code ==
			CAMERA_SENSOR_WAIT_OP_HW_UCND)
			i2c_list->i2c_settings.reg_setting[offset - 1].delay =
				cmd_uncond_wait->delay;
		else
			i2c_list->i2c_settings.delay =
				cmd_uncond_wait->delay;
		(*cmd_buf) +=
			sizeof(
			struct cam_cmd_unconditional_wait) / sizeof(uint32_t);
		(*byte_cnt) +=
			sizeof(
			struct cam_cmd_unconditional_wait);
	} else {
		CAM_ERR(CAM_SENSOR, "Delay Rxed before any buffer: %d", offset);
		return -EINVAL;
	}

	return rc;
}

/**
 * cam_eeprom_parse_write_memory_packet - Write eeprom packet
 * @csl_packet:   csl packet received
 * @e_ctrl:       ctrl structure
 *
 * Returns success or failure
 */
static int32_t cam_eeprom_parse_write_memory_packet(
	struct cam_packet *csl_packet,
	struct cam_eeprom_ctrl_t *e_ctrl)
{
	struct cam_cmd_buf_desc        *cmd_desc = NULL;
	uint32_t                       *offset = NULL;
	int32_t                         i, rc = 0;
	uint32_t                       *cmd_buf = NULL;
	uintptr_t                       generic_pkt_addr;
	size_t                          pkt_len = 0;
	size_t                          remain_len = 0;
	uint32_t                        total_cmd_buf_in_bytes = 0;
	uint32_t                        processed_cmd_buf_in_bytes = 0;
	struct common_header           *cmm_hdr = NULL;
	uint32_t                        cmd_length_in_bytes = 0;
	struct cam_cmd_i2c_info        *i2c_info = NULL;


	offset = (uint32_t *)&csl_packet->payload;
	offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
	cmd_desc = (struct cam_cmd_buf_desc *)(offset);

	CAM_DBG(CAM_EEPROM, "Number of Command Buffers: %d",
		csl_packet->num_cmd_buf);
	for (i = 0; i < csl_packet->num_cmd_buf; i++) {
		struct list_head               *list = NULL;
		uint16_t                       generic_op_code;
		uint32_t                       off = 0;
		int                            master;
		struct cam_sensor_cci_client   *cci;

		total_cmd_buf_in_bytes = cmd_desc[i].length;
		processed_cmd_buf_in_bytes = 0;

		if (!total_cmd_buf_in_bytes)
			continue;

		rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
			&generic_pkt_addr, &pkt_len);
		if (rc) {
			CAM_ERR(CAM_EEPROM, "Failed to get cpu buf");
			return rc;
		}

		cmd_buf = (uint32_t *)generic_pkt_addr;
		if (!cmd_buf) {
			CAM_ERR(CAM_EEPROM, "invalid cmd buf");
			rc = -EINVAL;
			goto rel_cmd_buf;
		}

		if ((pkt_len < sizeof(struct common_header) ||
			(cmd_desc[i].offset) > (pkt_len -
			sizeof(struct common_header)))) {
			CAM_ERR(CAM_EEPROM, "Not enough buffer");
			rc = -EINVAL;
			goto rel_cmd_buf;
		}

		remain_len = pkt_len - cmd_desc[i].offset;
		cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);

		if (total_cmd_buf_in_bytes > remain_len) {
			CAM_ERR(CAM_EEPROM, "Not enough buffer for command");
			rc = -EINVAL;
			goto rel_cmd_buf;
		}

		master = e_ctrl->io_master_info.master_type;
		cci = e_ctrl->io_master_info.cci_client;
		while (processed_cmd_buf_in_bytes < total_cmd_buf_in_bytes) {
			if ((remain_len - processed_cmd_buf_in_bytes) <
				sizeof(struct common_header)) {
				CAM_ERR(CAM_EEPROM, "Not Enough buffer");
				rc = -EINVAL;
				goto rel_cmd_buf;
			}
			cmm_hdr = (struct common_header *)cmd_buf;
			generic_op_code = cmm_hdr->fifth_byte;

			switch (cmm_hdr->cmd_type) {
			case CAMERA_SENSOR_CMD_TYPE_I2C_INFO:
				i2c_info = (struct cam_cmd_i2c_info *)cmd_buf;
				if ((remain_len - processed_cmd_buf_in_bytes) <
					sizeof(struct cam_cmd_i2c_info)) {
					CAM_ERR(CAM_EEPROM, "Not enough buf");
					rc = -EINVAL;
					goto rel_cmd_buf;
				}
				if (master == CCI_MASTER) {
					cci->cci_i2c_master =
						e_ctrl->cci_i2c_master;
					cci->i2c_freq_mode =
						i2c_info->i2c_freq_mode;
					cci->sid =
						i2c_info->slave_addr >> 1;
					CAM_DBG(CAM_EEPROM,
						"Slave addr: 0x%x Freq Mode: %d",
						i2c_info->slave_addr,
						i2c_info->i2c_freq_mode);
				} else if (master == I2C_MASTER) {
					e_ctrl->io_master_info.client->addr =
						i2c_info->slave_addr;
					CAM_DBG(CAM_EEPROM,
						"Slave addr: 0x%x",
						i2c_info->slave_addr);
				} else if (master == SPI_MASTER) {
					CAM_ERR(CAM_EEPROM,
						"No Need of Slave Info");
				} else {
					CAM_ERR(CAM_EEPROM,
						"Invalid Master type: %d",
						master);
					rc = -EINVAL;
					goto rel_cmd_buf;
				}
				cmd_length_in_bytes =
					sizeof(struct cam_cmd_i2c_info);
				processed_cmd_buf_in_bytes +=
					cmd_length_in_bytes;
				cmd_buf += cmd_length_in_bytes/4;
				break;
			case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_WR: {
				struct cam_cmd_i2c_continuous_wr
					*cam_cmd_i2c_continuous_wr =
					(struct cam_cmd_i2c_continuous_wr *)
					cmd_buf;
				if ((remain_len - processed_cmd_buf_in_bytes) <
				sizeof(struct cam_cmd_i2c_continuous_wr)) {
					CAM_ERR(CAM_EEPROM, "Not enough buf");
					rc = -EINVAL;
					goto rel_cmd_buf;
				}

				CAM_DBG(CAM_EEPROM,
					"CAMERA_SENSOR_CMD_TYPE_I2C_CONT_WR");
				rc = cam_eeprom_handle_continuous_write(
					e_ctrl,
					cam_cmd_i2c_continuous_wr,
					&(e_ctrl->wr_settings),
					&cmd_length_in_bytes, &off, &list);
				if (rc < 0) {
					CAM_ERR(CAM_SENSOR,
					"Failed in continuous write %d", rc);
					goto rel_cmd_buf;
				}

				processed_cmd_buf_in_bytes +=
					cmd_length_in_bytes;
				cmd_buf += cmd_length_in_bytes /
					sizeof(uint32_t);
				break;
			}
			case CAMERA_SENSOR_CMD_TYPE_WAIT: {
				CAM_DBG(CAM_EEPROM,
					"CAMERA_SENSOR_CMD_TYPE_WAIT");
				if (generic_op_code ==
					CAMERA_SENSOR_WAIT_OP_HW_UCND ||
					generic_op_code ==
						CAMERA_SENSOR_WAIT_OP_SW_UCND) {

					rc = cam_eeprom_handle_delay(
						&cmd_buf, generic_op_code,
						&(e_ctrl->wr_settings), off,
						&cmd_length_in_bytes,
						list, (remain_len -
						processed_cmd_buf_in_bytes));
					if (rc < 0) {
						CAM_ERR(CAM_EEPROM,
							"delay hdl failed: %d",
							rc);
						goto rel_cmd_buf;
					}
					processed_cmd_buf_in_bytes +=
						cmd_length_in_bytes;
					cmd_buf += cmd_length_in_bytes /
					sizeof(uint32_t);
				} else {
					CAM_ERR(CAM_EEPROM,
						"Wrong Wait Command: %d",
						generic_op_code);
					rc = -EINVAL;
					goto rel_cmd_buf;
				}
				break;
			}
			default:
				CAM_DBG(CAM_EEPROM,
					"Invalid Cmd_type rxed: %d\n",
					cmm_hdr->cmd_type);
				break;
			}
		}
		if (cam_mem_put_cpu_buf(cmd_desc[i].mem_handle))
			CAM_WARN(CAM_EEPROM, "Failed to put cpu buf: 0x%x",
				cmd_desc[i].mem_handle);
	}

	return rc;
rel_cmd_buf:
	if (cam_mem_put_cpu_buf(cmd_desc[i].mem_handle))
		CAM_WARN(CAM_EEPROM, "Failed to put cpu buf: 0x%x",
			cmd_desc[i].mem_handle);

	return rc;
}

/**
 * cam_eeprom_init_pkt_parser - Parse eeprom packet
 * @e_ctrl:       ctrl structure
@@ -530,7 +886,7 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl,
	uint32_t                        total_cmd_buf_in_bytes = 0;
	uint32_t                        processed_cmd_buf_in_bytes = 0;
	struct common_header           *cmm_hdr = NULL;
	uint16_t                        cmd_length_in_bytes = 0;
	uint32_t                        cmd_length_in_bytes = 0;
	struct cam_cmd_i2c_info        *i2c_info = NULL;
	int                             num_map = -1;
	struct cam_eeprom_memory_map_t *map = NULL;
@@ -712,6 +1068,61 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl,
	return rc;
}

static int32_t delete_eeprom_request(struct i2c_settings_array *i2c_array)
{
	struct i2c_settings_list *i2c_list = NULL, *i2c_next = NULL;
	int32_t rc = 0;

	if (i2c_array == NULL) {
		CAM_ERR(CAM_SENSOR, "FATAL:: Invalid argument");
		return -EINVAL;
	}

	list_for_each_entry_safe(i2c_list, i2c_next,
		&(i2c_array->list_head), list) {
		kfree(i2c_list->seq_settings.reg_data);
		list_del(&(i2c_list->list));
		kfree(i2c_list);
	}
	INIT_LIST_HEAD(&(i2c_array->list_head));
	i2c_array->is_settings_valid = 0;

	return rc;
}

/**
 * cam_eeprom_write - Write Packet
 * @e_ctrl:     ctrl structure
 *
 * Returns success or failure
 */
static int32_t cam_eeprom_write(struct cam_eeprom_ctrl_t *e_ctrl)
{
	int32_t rc = 0;
	struct i2c_settings_array *i2c_set = NULL;
	struct i2c_settings_list *i2c_list = NULL;

	i2c_set = &e_ctrl->wr_settings;

	if (i2c_set->is_settings_valid == 1) {
		list_for_each_entry(i2c_list,
			&(i2c_set->list_head), list) {
			rc = camera_io_dev_write_continuous(
				&e_ctrl->io_master_info,
				&i2c_list->i2c_settings, 1);
		if (rc < 0) {
			CAM_ERR(CAM_EEPROM,
				"Error in EEPROM write");
			goto del_req;
		}
		}
	}

del_req:
	delete_eeprom_request(i2c_set);
	return rc;
}

/**
 * cam_eeprom_pkt_parse - Parse csl packet
 * @e_ctrl:     ctrl structure
@@ -788,6 +1199,15 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
			goto error;
		}

		if (e_ctrl->eeprom_device_type == MSM_CAMERA_SPI_DEVICE) {
			rc = cam_eeprom_match_id(e_ctrl);
			if (rc) {
				CAM_DBG(CAM_EEPROM,
					"eeprom not matching %d", rc);
				goto power_down;
			}
		}

		rc = cam_eeprom_power_up(e_ctrl,
			&soc_private->power_info);
		if (rc) {
@@ -817,6 +1237,56 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
		e_ctrl->cal_data.num_data = 0;
		e_ctrl->cal_data.num_map = 0;
		break;
	case CAM_EEPROM_WRITE: {
		struct i2c_settings_array *i2c_reg_settings =
			&e_ctrl->wr_settings;

		i2c_reg_settings->is_settings_valid = 1;
		rc = cam_eeprom_parse_write_memory_packet(
			csl_packet, e_ctrl);
		if (rc < 0) {
			CAM_ERR(CAM_EEPROM, "Failed: rc : %d", rc);
			return rc;
		}

		rc = cam_eeprom_power_up(e_ctrl,
			&soc_private->power_info);
		if (rc) {
			CAM_ERR(CAM_EEPROM, "failed power up rc %d", rc);
			goto memdata_free;
		}

		usleep_range(10*1000, 11*1000);
		CAM_DBG(CAM_EEPROM,
			"Calling Erase : %d start Address: 0x%x size: %d",
			rc, e_ctrl->eebin_info.start_address,
			e_ctrl->eebin_info.size);

		rc = camera_io_dev_erase(&e_ctrl->io_master_info,
			e_ctrl->eebin_info.start_address,
			e_ctrl->eebin_info.size);
		if (rc < 0) {
			CAM_ERR(CAM_EEPROM, "Failed in erase : %d", rc);
			return rc;
		}

		/* Buffer time margin */
		usleep_range(10*1000, 11*1000);

		rc = cam_eeprom_write(e_ctrl);
		if (rc < 0) {
			CAM_ERR(CAM_EEPROM, "Failed: rc : %d", rc);
			return rc;
		}

		rc = cam_eeprom_power_down(e_ctrl);
		if (rc) {
			CAM_ERR(CAM_EEPROM, "failed power down rc %d", rc);
			goto memdata_free;
		}

		break;
	}
	default:
		break;
	}
@@ -918,6 +1388,9 @@ int32_t cam_eeprom_driver_cmd(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
		else
			eeprom_cap.eeprom_kernel_probe = false;

		eeprom_cap.is_multimodule_mode =
			e_ctrl->is_multimodule_mode;

		if (copy_to_user(u64_to_user_ptr(cmd->handle),
			&eeprom_cap,
			sizeof(struct cam_eeprom_query_cap_t))) {
+8 −3
Original line number Diff line number Diff line
// 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_eeprom_dev.h"
@@ -65,6 +65,9 @@ int32_t cam_eeprom_update_i2c_info(struct cam_eeprom_ctrl_t *e_ctrl,
	} else if (e_ctrl->io_master_info.master_type == I2C_MASTER) {
		e_ctrl->io_master_info.client->addr = i2c_info->slave_addr;
		CAM_DBG(CAM_EEPROM, "Slave addr: 0x%x", i2c_info->slave_addr);
	} else if (e_ctrl->io_master_info.master_type == SPI_MASTER) {
		CAM_ERR(CAM_EEPROM, "Slave addr: 0x%x Freq Mode: %d",
		i2c_info->slave_addr, i2c_info->i2c_freq_mode);
	}
	return 0;
}
@@ -178,6 +181,7 @@ static int cam_eeprom_i2c_driver_probe(struct i2c_client *client,

	mutex_init(&(e_ctrl->eeprom_mutex));

	INIT_LIST_HEAD(&(e_ctrl->wr_settings.list_head));
	soc_info = &e_ctrl->soc_info;
	soc_info->dev = &client->dev;
	soc_info->dev_name = client->name;
@@ -303,7 +307,7 @@ static int cam_eeprom_spi_setup(struct spi_device *spi)
	e_ctrl->io_master_info.spi_client = spi_client;
	e_ctrl->io_master_info.master_type = SPI_MASTER;
	spi_client->spi_master = spi;

	INIT_LIST_HEAD(&(e_ctrl->wr_settings.list_head));
	power_info = &eb_info->power_info;
	power_info->dev = &spi->dev;

@@ -314,6 +318,7 @@ static int cam_eeprom_spi_setup(struct spi_device *spi)
	/* Initialize mutex */
	mutex_init(&(e_ctrl->eeprom_mutex));

	e_ctrl->bridge_intf.device_hdl = -1;
	rc = cam_eeprom_parse_dt(e_ctrl);
	if (rc) {
		CAM_ERR(CAM_EEPROM, "failed: spi soc init rc %d", rc);
@@ -330,7 +335,6 @@ static int cam_eeprom_spi_setup(struct spi_device *spi)
	if (rc)
		goto board_free;

	e_ctrl->bridge_intf.device_hdl = -1;
	e_ctrl->bridge_intf.ops.get_dev_info = NULL;
	e_ctrl->bridge_intf.ops.link_setup = NULL;
	e_ctrl->bridge_intf.ops.apply_req = NULL;
@@ -454,6 +458,7 @@ static int32_t cam_eeprom_platform_driver_probe(
		goto free_soc;
	}

	INIT_LIST_HEAD(&(e_ctrl->wr_settings.list_head));
	rc = cam_eeprom_init_subdev(e_ctrl);
	if (rc)
		goto free_soc;
+30 −16
Original line number Diff line number Diff line
/* 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.
 */
#ifndef _CAM_EEPROM_DEV_H_
#define _CAM_EEPROM_DEV_H_

#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/gpio.h>
#include <media/v4l2-event.h>
#include <media/v4l2-subdev.h>
@@ -19,6 +21,7 @@
#include <cam_req_mgr_interface.h>
#include <cam_mem_mgr.h>
#include <cam_subdev.h>
#include <media/cam_sensor.h>
#include "cam_soc_util.h"

#define DEFINE_MSM_MUTEX(mutexname) \
@@ -142,8 +145,14 @@ struct cam_eeprom_intf_params {
	struct cam_req_mgr_crm_cb *crm_cb;
};

struct eebin_info {
	uint32_t start_address;
	uint32_t size;
	uint32_t is_valid;
};

/**
 * struct cam_cmd_conditional_wait - Conditional wait command
 * struct cam_eeprom_ctrl_t - EEPROM control structure
 * @pdev                :   platform device
 * @spi                 :   spi device
 * @eeprom_mutex        :   eeprom mutex
@@ -157,7 +166,9 @@ struct cam_eeprom_intf_params {
 * @userspace_probe     :   flag indicates userspace or kernel probe
 * @cal_data            :   Calibration data
 * @device_name         :   Device name
 *
 * @is_multimodule_mode :   To identify multimodule node
 * @wr_settings         :   I2C write settings
 * @eebin_info          :   EEBIN address, size info
 */
struct cam_eeprom_ctrl_t {
	struct platform_device *pdev;
@@ -175,6 +186,9 @@ struct cam_eeprom_ctrl_t {
	bool userspace_probe;
	struct cam_eeprom_memory_block_t cal_data;
	char device_name[20];
	uint16_t is_multimodule_mode;
	struct i2c_settings_array wr_settings;
	struct eebin_info eebin_info;
};

int32_t cam_eeprom_update_i2c_info(struct cam_eeprom_ctrl_t *e_ctrl,
+8 −1
Original line number Diff line number Diff line
// 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 <linux/of.h>
@@ -293,6 +293,8 @@ int cam_eeprom_parse_dt(struct cam_eeprom_ctrl_t *e_ctrl)
		return -EINVAL;
	}

	e_ctrl->is_multimodule_mode = false;

	rc = cam_soc_util_get_dt_properties(soc_info);
	if (rc < 0) {
		CAM_ERR(CAM_EEPROM, "Failed to read DT properties rc : %d", rc);
@@ -301,6 +303,11 @@ int cam_eeprom_parse_dt(struct cam_eeprom_ctrl_t *e_ctrl)

	of_node = soc_info->dev->of_node;

	if (of_property_read_bool(of_node, "multimodule-support")) {
		CAM_DBG(CAM_UTIL, "Multi Module is Supported");
		e_ctrl->is_multimodule_mode = true;
	}

	rc = of_property_read_string(of_node, "eeprom-name",
		&soc_private->eeprom_name);
	if (rc < 0) {
+1 −1
Original line number Diff line number Diff line
// 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 <linux/module.h>
Loading