msm: camera: sensor: I2C poll implementation
Remove additional delay after poll. Delay in ms is acounted during polling the register. If read is successful and match fails, then poll is non-fatal. CRs-Fixed: 971014 Change-Id: I655a272bed125edc2dc60504640f1d57652a64e2 Signed-off-by: Rajesh Bondugula <rajeshb@codeaurora.org>
This commit is contained in:
parent
db36660f6c
commit
b15dc12577
6 changed files with 90 additions and 73 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -156,7 +156,7 @@ static int msm_actuator_bivcm_handle_i2c_ops(
|
|||
uint32_t hw_dword = hw_params;
|
||||
uint16_t i2c_byte1 = 0, i2c_byte2 = 0;
|
||||
uint16_t value = 0, reg_data = 0;
|
||||
uint32_t size = a_ctrl->reg_tbl_size, i = 0, j = 0;
|
||||
uint32_t size = a_ctrl->reg_tbl_size, i = 0;
|
||||
int32_t rc = 0;
|
||||
struct msm_camera_i2c_reg_array i2c_tbl;
|
||||
struct msm_camera_i2c_reg_setting reg_setting;
|
||||
|
@ -266,23 +266,17 @@ static int msm_actuator_bivcm_handle_i2c_ops(
|
|||
write_arr[i].addr_type);
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < ACTUATOR_MAX_POLL_COUNT; j++) {
|
||||
rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
|
||||
&a_ctrl->i2c_client,
|
||||
write_arr[i].reg_addr,
|
||||
write_arr[i].reg_data,
|
||||
write_arr[i].data_type);
|
||||
if (rc == 1)
|
||||
continue;
|
||||
if (rc < 0) {
|
||||
pr_err("i2c poll error:%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
|
||||
&a_ctrl->i2c_client,
|
||||
write_arr[i].reg_addr,
|
||||
write_arr[i].reg_data,
|
||||
write_arr[i].data_type,
|
||||
write_arr[i].delay);
|
||||
if (rc < 0) {
|
||||
pr_err("i2c poll error:%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
if (j == ACTUATOR_MAX_POLL_COUNT)
|
||||
CDBG("%s:%d Poll register not as expected\n",
|
||||
__func__, __LINE__);
|
||||
break;
|
||||
case MSM_ACTUATOR_READ_WRITE:
|
||||
i2c_tbl.reg_addr = write_arr[i].reg_addr;
|
||||
|
@ -386,13 +380,19 @@ static int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
|
|||
settings[i].reg_addr,
|
||||
settings[i].reg_data,
|
||||
settings[i].data_type);
|
||||
if (settings[i].delay > 20)
|
||||
msleep(settings[i].delay);
|
||||
else if (0 != settings[i].delay)
|
||||
usleep_range(settings[i].delay * 1000,
|
||||
(settings[i].delay * 1000) + 1000);
|
||||
break;
|
||||
case MSM_ACT_POLL:
|
||||
rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
|
||||
&a_ctrl->i2c_client,
|
||||
settings[i].reg_addr,
|
||||
settings[i].reg_data,
|
||||
settings[i].data_type);
|
||||
settings[i].data_type,
|
||||
settings[i].delay);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unsupport i2c_operation: %d\n",
|
||||
|
@ -400,9 +400,6 @@ static int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
|
|||
break;
|
||||
}
|
||||
|
||||
if (0 != settings[i].delay)
|
||||
msleep(settings[i].delay);
|
||||
|
||||
if (rc < 0) {
|
||||
pr_err("%s:%d fail addr = 0X%X, data = 0X%X, dt = %d",
|
||||
__func__, __LINE__, settings[i].reg_addr,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -194,8 +194,8 @@ static int read_eeprom_memory(struct msm_eeprom_ctrl_t *e_ctrl,
|
|||
e_ctrl->i2c_client.addr_type = emap[j].poll.addr_t;
|
||||
rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
|
||||
&(e_ctrl->i2c_client), emap[j].poll.addr,
|
||||
emap[j].poll.data, emap[j].poll.data_t);
|
||||
msleep(emap[j].poll.delay);
|
||||
emap[j].poll.data, emap[j].poll.data_t,
|
||||
emap[j].poll.delay);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: poll failed\n", __func__);
|
||||
return rc;
|
||||
|
@ -380,8 +380,8 @@ static int eeprom_parse_memory_map(struct msm_eeprom_ctrl_t *e_ctrl,
|
|||
&(e_ctrl->i2c_client),
|
||||
eeprom_map->mem_settings[i].reg_addr,
|
||||
eeprom_map->mem_settings[i].reg_data,
|
||||
eeprom_map->mem_settings[i].data_type);
|
||||
msleep(eeprom_map->mem_settings[i].delay);
|
||||
eeprom_map->mem_settings[i].data_type,
|
||||
eeprom_map->mem_settings[i].delay);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: poll failed\n",
|
||||
__func__);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -18,10 +18,6 @@
|
|||
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
#define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
|
||||
#define I2C_COMPARE_MATCH 0
|
||||
#define I2C_COMPARE_MISMATCH 1
|
||||
#define I2C_POLL_MAX_ITERATION 20
|
||||
|
||||
int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
|
||||
uint32_t addr, uint16_t *data,
|
||||
enum msm_camera_i2c_data_type data_type)
|
||||
|
@ -384,14 +380,34 @@ static int32_t msm_camera_cci_i2c_compare(struct msm_camera_i2c_client *client,
|
|||
|
||||
int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client,
|
||||
uint32_t addr, uint16_t data,
|
||||
enum msm_camera_i2c_data_type data_type)
|
||||
enum msm_camera_i2c_data_type data_type, uint32_t delay_ms)
|
||||
{
|
||||
int32_t rc;
|
||||
int32_t i = 0;
|
||||
S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n",
|
||||
__func__, addr, data, data_type);
|
||||
|
||||
rc = msm_camera_cci_i2c_compare(client,
|
||||
addr, data, data_type);
|
||||
if (delay_ms > MAX_POLL_DELAY_MS) {
|
||||
pr_err("%s:%d invalid delay = %d max_delay = %d\n",
|
||||
__func__, __LINE__, delay_ms, MAX_POLL_DELAY_MS);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < delay_ms; i++) {
|
||||
rc = msm_camera_cci_i2c_compare(client,
|
||||
addr, data, data_type);
|
||||
if (!rc)
|
||||
return rc;
|
||||
usleep_range(1000, 1010);
|
||||
}
|
||||
|
||||
/* If rc is 1 then read is successful but poll is failure */
|
||||
if (rc == 1)
|
||||
pr_err("%s:%d poll failed rc=%d(non-fatal)\n",
|
||||
__func__, __LINE__, rc);
|
||||
|
||||
if (rc < 0)
|
||||
pr_err("%s:%d poll failed rc=%d\n", __func__, __LINE__, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -465,7 +481,7 @@ int32_t msm_camera_cci_i2c_write_conf_tbl(
|
|||
rc = msm_camera_cci_i2c_poll(client,
|
||||
reg_conf_tbl->reg_addr,
|
||||
reg_conf_tbl->reg_data,
|
||||
reg_conf_tbl->dt);
|
||||
reg_conf_tbl->dt, I2C_POLL_TIME_MS);
|
||||
} else {
|
||||
if (reg_conf_tbl->dt == 0)
|
||||
dt = data_type;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -17,6 +17,12 @@
|
|||
#include <media/v4l2-subdev.h>
|
||||
#include <media/msm_cam_sensor.h>
|
||||
|
||||
#define I2C_POLL_TIME_MS 5
|
||||
#define MAX_POLL_DELAY_MS 100
|
||||
|
||||
#define I2C_COMPARE_MATCH 0
|
||||
#define I2C_COMPARE_MISMATCH 1
|
||||
|
||||
struct msm_camera_i2c_client {
|
||||
struct msm_camera_i2c_fn_t *i2c_func_tbl;
|
||||
struct i2c_client *client;
|
||||
|
@ -47,7 +53,7 @@ struct msm_camera_i2c_fn_t {
|
|||
enum msm_camera_i2c_data_type data_type);
|
||||
int32_t (*i2c_poll)(struct msm_camera_i2c_client *client,
|
||||
uint32_t addr, uint16_t data,
|
||||
enum msm_camera_i2c_data_type data_type);
|
||||
enum msm_camera_i2c_data_type data_type, uint32_t delay_ms);
|
||||
int32_t (*i2c_read_burst)(struct msm_camera_i2c_client *client,
|
||||
uint32_t read_byte, uint8_t *buffer, uint32_t addr,
|
||||
enum msm_camera_i2c_data_type data_type);
|
||||
|
@ -111,7 +117,7 @@ int32_t msm_sensor_cci_i2c_util(struct msm_camera_i2c_client *client,
|
|||
|
||||
int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client,
|
||||
uint32_t addr, uint16_t data,
|
||||
enum msm_camera_i2c_data_type data_type);
|
||||
enum msm_camera_i2c_data_type data_type, uint32_t delay_ms);
|
||||
|
||||
int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
|
||||
uint32_t addr, uint16_t *data,
|
||||
|
@ -144,6 +150,6 @@ int32_t msm_camera_qup_i2c_write_conf_tbl(
|
|||
|
||||
int32_t msm_camera_qup_i2c_poll(struct msm_camera_i2c_client *client,
|
||||
uint32_t addr, uint16_t data,
|
||||
enum msm_camera_i2c_data_type data_type);
|
||||
enum msm_camera_i2c_data_type data_type, uint32_t delay_ms);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011, 2013-2014, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011, 2013-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -22,10 +22,6 @@
|
|||
#define S_I2C_DBG(fmt, args...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define I2C_COMPARE_MATCH 0
|
||||
#define I2C_COMPARE_MISMATCH 1
|
||||
#define I2C_POLL_MAX_ITERATION 20
|
||||
|
||||
static int32_t msm_camera_qup_i2c_rxdata(
|
||||
struct msm_camera_i2c_client *dev_client, unsigned char *rxdata,
|
||||
int data_length)
|
||||
|
@ -342,8 +338,8 @@ int32_t msm_camera_qup_i2c_write_table_w_microdelay(
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int32_t msm_camera_qup_i2c_compare(struct msm_camera_i2c_client *client,
|
||||
uint32_t addr, uint16_t data,
|
||||
static int32_t msm_camera_qup_i2c_compare(
|
||||
struct msm_camera_i2c_client *client, uint32_t addr, uint16_t data,
|
||||
enum msm_camera_i2c_data_type data_type)
|
||||
{
|
||||
int32_t rc;
|
||||
|
@ -400,19 +396,30 @@ static int32_t msm_camera_qup_i2c_compare(struct msm_camera_i2c_client *client,
|
|||
|
||||
int32_t msm_camera_qup_i2c_poll(struct msm_camera_i2c_client *client,
|
||||
uint32_t addr, uint16_t data,
|
||||
enum msm_camera_i2c_data_type data_type)
|
||||
enum msm_camera_i2c_data_type data_type, uint32_t delay_ms)
|
||||
{
|
||||
int32_t rc;
|
||||
int i;
|
||||
S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n",
|
||||
__func__, addr, data, data_type);
|
||||
|
||||
for (i = 0; i < I2C_POLL_MAX_ITERATION; i++) {
|
||||
if (delay_ms > MAX_POLL_DELAY_MS) {
|
||||
pr_err("%s:%d invalid delay = %d max_delay = %d\n",
|
||||
__func__, __LINE__, delay_ms, MAX_POLL_DELAY_MS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < delay_ms; i++) {
|
||||
rc = msm_camera_qup_i2c_compare(client,
|
||||
addr, data, data_type);
|
||||
if (rc == 0 || rc < 0)
|
||||
if (rc < 0) {
|
||||
pr_err("%s:%d qup_i2c_compare failed rc = %d", __func__,
|
||||
__LINE__, rc);
|
||||
break;
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
if (rc == I2C_COMPARE_MISMATCH)
|
||||
break;
|
||||
usleep_range(1000, 1010);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -489,7 +496,7 @@ int32_t msm_camera_qup_i2c_write_conf_tbl(
|
|||
rc = msm_camera_qup_i2c_poll(client,
|
||||
reg_conf_tbl->reg_addr,
|
||||
reg_conf_tbl->reg_data,
|
||||
reg_conf_tbl->dt);
|
||||
reg_conf_tbl->dt, I2C_POLL_TIME_MS);
|
||||
} else {
|
||||
if (reg_conf_tbl->dt == 0)
|
||||
dt = data_type;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -26,8 +26,6 @@ DEFINE_MSM_MUTEX(msm_ois_mutex);
|
|||
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
#endif
|
||||
|
||||
#define MAX_POLL_COUNT 100
|
||||
|
||||
static struct v4l2_file_operations msm_ois_v4l2_subdev_fops;
|
||||
static int32_t msm_ois_power_up(struct msm_ois_ctrl_t *o_ctrl);
|
||||
static int32_t msm_ois_power_down(struct msm_ois_ctrl_t *o_ctrl);
|
||||
|
@ -90,26 +88,25 @@ static int32_t msm_ois_write_settings(struct msm_ois_ctrl_t *o_ctrl,
|
|||
settings[i].data_type);
|
||||
break;
|
||||
}
|
||||
if (settings[i].delay > 20)
|
||||
msleep(settings[i].delay);
|
||||
else if (0 != settings[i].delay)
|
||||
usleep_range(settings[i].delay * 1000,
|
||||
(settings[i].delay * 1000) + 1000);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSM_OIS_POLL: {
|
||||
int32_t poll_count = 0;
|
||||
switch (settings[i].data_type) {
|
||||
case MSM_CAMERA_I2C_BYTE_DATA:
|
||||
case MSM_CAMERA_I2C_WORD_DATA:
|
||||
do {
|
||||
rc = o_ctrl->i2c_client.i2c_func_tbl
|
||||
->i2c_poll(&o_ctrl->i2c_client,
|
||||
settings[i].reg_addr,
|
||||
settings[i].reg_data,
|
||||
settings[i].data_type);
|
||||
|
||||
if (poll_count++ > MAX_POLL_COUNT) {
|
||||
pr_err("MSM_OIS_POLL failed");
|
||||
break;
|
||||
}
|
||||
} while (rc != 0);
|
||||
rc = o_ctrl->i2c_client.i2c_func_tbl
|
||||
->i2c_poll(&o_ctrl->i2c_client,
|
||||
settings[i].reg_addr,
|
||||
settings[i].reg_data,
|
||||
settings[i].data_type,
|
||||
settings[i].delay);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -120,12 +117,6 @@ static int32_t msm_ois_write_settings(struct msm_ois_ctrl_t *o_ctrl,
|
|||
}
|
||||
}
|
||||
|
||||
if (settings[i].delay > 20)
|
||||
msleep(settings[i].delay);
|
||||
else if (0 != settings[i].delay)
|
||||
usleep_range(settings[i].delay * 1000,
|
||||
(settings[i].delay * 1000) + 1000);
|
||||
|
||||
if (rc < 0)
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue