Merge "msm: camera: sensor: OIS lens position data infrastructure" into camera-kernel.lnx.4.0
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
797221b9f9
@@ -198,6 +198,49 @@ static int cam_ois_power_down(struct cam_ois_ctrl_t *o_ctrl)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ois_update_time(struct i2c_settings_array *i2c_set)
|
||||
{
|
||||
struct i2c_settings_list *i2c_list;
|
||||
int32_t rc = 0;
|
||||
uint32_t size = 0;
|
||||
uint32_t i = 0;
|
||||
uint64_t qtime_ns = 0;
|
||||
|
||||
if (i2c_set == NULL) {
|
||||
CAM_ERR(CAM_OIS, "Invalid Args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = cam_sensor_util_get_current_qtimer_ns(&qtime_ns);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS,
|
||||
"Failed to get current qtimer value: %d",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
list_for_each_entry(i2c_list,
|
||||
&(i2c_set->list_head), list) {
|
||||
if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
|
||||
size = i2c_list->i2c_settings.size;
|
||||
/* qtimer is 8 bytes so validate here*/
|
||||
if (size < 8) {
|
||||
CAM_ERR(CAM_OIS, "Invalid write time settings");
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < size; i++) {
|
||||
CAM_DBG(CAM_OIS, "time: reg_data[%d]: 0x%x",
|
||||
i, (qtime_ns & 0xFF));
|
||||
i2c_list->i2c_settings.reg_setting[i].reg_data =
|
||||
(qtime_ns & 0xFF);
|
||||
qtime_ns >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ois_apply_settings(struct cam_ois_ctrl_t *o_ctrl,
|
||||
struct i2c_settings_array *i2c_set)
|
||||
{
|
||||
@@ -225,6 +268,17 @@ static int cam_ois_apply_settings(struct cam_ois_ctrl_t *o_ctrl,
|
||||
"Failed in Applying i2c wrt settings");
|
||||
return rc;
|
||||
}
|
||||
} else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
|
||||
rc = camera_io_dev_write_continuous(
|
||||
&(o_ctrl->io_master_info),
|
||||
&(i2c_list->i2c_settings),
|
||||
0);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS,
|
||||
"Failed to seq write I2C settings: %d",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
} else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) {
|
||||
size = i2c_list->i2c_settings.size;
|
||||
for (i = 0; i < size; i++) {
|
||||
@@ -680,6 +734,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
||||
&csl_packet->payload +
|
||||
csl_packet->io_configs_offset);
|
||||
|
||||
/* validate read data io config */
|
||||
if (io_cfg == NULL) {
|
||||
CAM_ERR(CAM_OIS, "I/O config is invalid(NULL)");
|
||||
rc = -EINVAL;
|
||||
@@ -693,7 +748,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
||||
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);
|
||||
cmd_desc, 1, &io_cfg[0]);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "OIS read pkt parsing failed: %d", rc);
|
||||
return rc;
|
||||
@@ -708,6 +763,17 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (csl_packet->num_io_configs > 1) {
|
||||
rc = cam_sensor_util_write_qtimer_to_io_buffer(
|
||||
&io_cfg[1]);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS,
|
||||
"write qtimer failed rc: %d", rc);
|
||||
delete_request(&i2c_read_settings);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
rc = delete_request(&i2c_read_settings);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS,
|
||||
@@ -716,6 +782,48 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CAM_OIS_PACKET_OPCODE_WRITE_TIME: {
|
||||
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
||||
rc = -EINVAL;
|
||||
CAM_ERR(CAM_OIS,
|
||||
"Not in right state to write time to OIS: %d",
|
||||
o_ctrl->cam_ois_state);
|
||||
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_reg_settings = &(o_ctrl->i2c_time_data);
|
||||
i2c_reg_settings->is_settings_valid = 1;
|
||||
i2c_reg_settings->request_id = 0;
|
||||
rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info,
|
||||
i2c_reg_settings,
|
||||
cmd_desc, 1, NULL);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_ois_update_time(i2c_reg_settings);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "Cannot update time");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_ois_apply_settings(o_ctrl, i2c_reg_settings);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "Cannot apply mode settings");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = delete_request(i2c_reg_settings);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS,
|
||||
"Fail deleting Mode data: rc: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CAM_ERR(CAM_OIS, "Invalid Opcode: %d",
|
||||
(csl_packet->header.op_code & 0xFFFFFF));
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef _CAM_OIS_DEV_H_
|
||||
#define _CAM_OIS_DEV_H_
|
||||
@@ -94,6 +94,7 @@ struct cam_ois_intf_params {
|
||||
* @bridge_intf : bridge interface params
|
||||
* @i2c_init_data : ois i2c init settings
|
||||
* @i2c_mode_data : ois i2c mode settings
|
||||
* @i2c_time_data : ois i2c time write settings
|
||||
* @i2c_calib_data : ois i2c calib settings
|
||||
* @ois_device_type : ois device type
|
||||
* @cam_ois_state : ois_device_state
|
||||
@@ -116,6 +117,7 @@ struct cam_ois_ctrl_t {
|
||||
struct i2c_settings_array i2c_init_data;
|
||||
struct i2c_settings_array i2c_calib_data;
|
||||
struct i2c_settings_array i2c_mode_data;
|
||||
struct i2c_settings_array i2c_time_data;
|
||||
enum msm_camera_device_type_t ois_device_type;
|
||||
enum cam_ois_state cam_ois_state;
|
||||
char ois_name[32];
|
||||
|
@@ -173,7 +173,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_READ
|
||||
CAM_OIS_PACKET_OPCODE_READ,
|
||||
CAM_OIS_PACKET_OPCODE_WRITE_TIME
|
||||
};
|
||||
|
||||
enum msm_bus_perf_setting {
|
||||
|
@@ -1,9 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <clocksource/arm_arch_timer.h>
|
||||
#include "cam_sensor_util.h"
|
||||
#include "cam_mem_mgr.h"
|
||||
#include "cam_res_mgr_api.h"
|
||||
@@ -40,6 +41,29 @@ static struct i2c_settings_list*
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int32_t cam_sensor_util_get_current_qtimer_ns(uint64_t *qtime_ns)
|
||||
{
|
||||
uint64_t ticks = 0;
|
||||
int32_t rc = 0;
|
||||
|
||||
ticks = arch_timer_read_counter();
|
||||
if (ticks == 0) {
|
||||
CAM_ERR(CAM_SENSOR, "qtimer returned 0, rc:%d", rc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (qtime_ns != NULL) {
|
||||
*qtime_ns = mul_u64_u32_div(ticks,
|
||||
QTIMER_MUL_FACTOR, QTIMER_DIV_FACTOR);
|
||||
CAM_DBG(CAM_SENSOR, "Qtimer time: 0x%x", *qtime_ns);
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "NULL pointer passed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t delete_request(struct i2c_settings_array *i2c_array)
|
||||
{
|
||||
struct i2c_settings_list *i2c_list = NULL, *i2c_next = NULL;
|
||||
@@ -277,6 +301,64 @@ static int32_t cam_sensor_get_io_buffer(
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t cam_sensor_util_write_qtimer_to_io_buffer(
|
||||
struct cam_buf_io_cfg *io_cfg)
|
||||
{
|
||||
uintptr_t buf_addr = 0x0, target_buf = 0x0;
|
||||
size_t buf_size = 0, target_size = 0;
|
||||
int32_t rc = 0;
|
||||
uint64_t qtime_ns = 0;
|
||||
|
||||
if (io_cfg == NULL) {
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"Invalid args, io buf is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
target_buf = buf_addr + io_cfg->offsets[0];
|
||||
target_size = buf_size - io_cfg->offsets[0];
|
||||
|
||||
if (target_size < sizeof(uint64_t)) {
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"not enough size for qtimer, target_size:%d",
|
||||
target_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = cam_sensor_util_get_current_qtimer_ns(&qtime_ns);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SENSOR, "failed to get qtimer rc:%d");
|
||||
return rc;
|
||||
}
|
||||
|
||||
memcpy((void *)target_buf, &qtime_ns, sizeof(uint64_t));
|
||||
} 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,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_SENSOR_UTIL_H_
|
||||
@@ -21,6 +21,15 @@
|
||||
|
||||
#define INVALID_VREG 100
|
||||
|
||||
/*
|
||||
* Constant Factors needed to change QTimer ticks to nanoseconds
|
||||
* QTimer Freq = 19.2 MHz
|
||||
* Time(us) = ticks/19.2
|
||||
* Time(ns) = ticks/19.2 * 1000
|
||||
*/
|
||||
#define QTIMER_MUL_FACTOR 10000
|
||||
#define QTIMER_DIV_FACTOR 192
|
||||
|
||||
int cam_get_dt_power_setting_data(struct device_node *of_node,
|
||||
struct cam_hw_soc_info *soc_info,
|
||||
struct cam_sensor_power_ctrl_t *power_info);
|
||||
@@ -28,6 +37,11 @@ int cam_get_dt_power_setting_data(struct device_node *of_node,
|
||||
int msm_camera_pinctrl_init
|
||||
(struct msm_pinctrl_info *sensor_pctrl, struct device *dev);
|
||||
|
||||
int32_t cam_sensor_util_get_current_qtimer_ns(uint64_t *qtime_ns);
|
||||
|
||||
int32_t cam_sensor_util_write_qtimer_to_io_buffer(
|
||||
struct cam_buf_io_cfg *io_cfg);
|
||||
|
||||
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,
|
||||
|
Reference in New Issue
Block a user