diff options
6 files changed, 91 insertions, 74 deletions
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index 9bd07604a506..86cc2fad2e63 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -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, diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c index 92a1d5ccf28b..375d3e582168 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c +++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c @@ -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__); diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index 15705179301e..7315327e6d12 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -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; diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h index eac70f5379d9..0fbe35713d8e 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h @@ -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 diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c index 41b4952f4f40..f542ec2e26bf 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c @@ -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; + } + if (rc == I2C_COMPARE_MISMATCH) break; - usleep_range(10000, 11000); + 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; diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c index 664517a8e959..fc2c6b6e95b1 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c +++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c @@ -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; } |
