diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 507725791020..41c309bcde79 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -32,12 +32,14 @@ #define DEVICE_NAME_LEN 32 #define MAX_ACTUATOR_NUM 3 #define REGULATOR_NAME_MAX_LEN 32 +#define LENS_MAX_STAGES 10 typedef enum { MOT_ACTUATOR_INVALID, MOT_ACTUATOR_FIRST, MOT_ACTUATOR_GT9767 = MOT_ACTUATOR_FIRST, MOT_ACTUATOR_GT9772, + MOT_ACTUATOR_DW9800V, MOT_ACTUATOR_NUM, } mot_actuator_type; @@ -50,6 +52,7 @@ typedef enum { typedef enum { MOT_DEVICE_NIO, MOT_DEVICE_CAPRIP, + MOT_DEVICE_RHODE, MOT_DEVICE_NUM, } mot_dev_type; @@ -58,6 +61,16 @@ typedef struct { uint16_t step; } mot_park_lens_step; +typedef struct { + uint16_t kneePoint; + uint16_t step; +} mot_lens_step; + +typedef struct { + bool launch_lens_needed; + mot_lens_step launch_lens_step[LENS_MAX_STAGES]; +} mot_launch_lens; + typedef struct { struct cam_sensor_i2c_reg_setting *init_setting; struct cam_sensor_i2c_reg_setting *dac_setting; @@ -66,12 +79,14 @@ typedef struct { typedef struct { mot_actuator_type actuator_type; uint16_t dac_pos; + uint16_t init_pos; uint16_t cci_addr; uint16_t cci_dev; uint16_t cci_master; char *regulator_list[REGULATOR_NUM]; uint32_t regulator_volt_uv[REGULATOR_NUM]; bool park_lens_needed; + mot_launch_lens launch_lens; } mot_actuator_hw_info; typedef struct { @@ -134,11 +149,39 @@ static struct cam_sensor_i2c_reg_setting mot_gt9772_dac_settings = { .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, }; + +static struct cam_sensor_i2c_reg_array mot_dw9800v_init_setting[] ={ + {0x02, 0x01, 0}, + {0x02, 0x00, 100}, + {0x02, 0x02, 0}, + {0x06, 0x40, 0}, + {0x07, 0x79, 0}, +}; + +static struct cam_sensor_i2c_reg_array mot_dw9800v_dac_setting[] ={ + {0x03, 0x3ff, 0} +}; + +static struct cam_sensor_i2c_reg_setting mot_dw9800v_init_settings = { + .reg_setting = mot_dw9800v_init_setting, + .size = ARRAY_SIZE(mot_dw9800v_init_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_BYTE, +}; + +static struct cam_sensor_i2c_reg_setting mot_dw9800v_dac_settings = { + .reg_setting = mot_dw9800v_dac_setting, + .size = ARRAY_SIZE(mot_dw9800v_dac_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, +}; + /*Register settings of all supported actuator types*/ -static mot_actuator_settings mot_actuator_list[MOT_ACTUATOR_NUM-1] = { +static mot_actuator_settings mot_actuator_list[MOT_ACTUATOR_NUM] = { //MUST be sorted as definition order in above structure: mot_actuator_type {&mot_gt9767_init_settings, &mot_gt9767_dac_settings}, {&mot_gt9772_init_settings, &mot_gt9772_dac_settings}, + {&mot_dw9800v_init_settings, &mot_dw9800v_dac_settings}, }; static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { @@ -174,6 +217,31 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { }, }, }, + { + .dev_type = MOT_DEVICE_RHODE, + .dev_name = "rhode", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 1023, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x0, + .regulator_list = {"ldo4", "ldo3"}, + .regulator_volt_uv = {1800000, 2800000}, + .park_lens_needed = true, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {600, 200}, + {800, 101}, + {900, 100} + }, + }, + }, + }, + }, }; static uint32_t mot_device_index = MOT_DEVICE_NUM; @@ -199,6 +267,7 @@ __setup("androidboot.device=", cam_select_actuator_by_device_name); /*=================ACTUATOR RUNTIME====================*/ #define VIBRATING_MAX_INTERVAL 2000//ms #define PARK_LENS_MAX_STAGES 10 +#define LAUNCH_LENS_MAX_STAGES LENS_MAX_STAGES struct mot_actuator_ctrl_t { struct cam_subdev v4l2_dev_str; @@ -359,12 +428,20 @@ static int32_t mot_actuator_power_off(uint32_t index) int32_t mot_actuator_init_cci(uint32_t index) { - int32_t ret = 0; + int32_t ret = 0,rc = 0; CAM_DBG(CAM_ACTUATOR, "init cci."); ret = camera_io_init(&mot_actuator_runtime[index].io_master); if (ret != 0) { - CAM_ERR(CAM_ACTUATOR, "init cci failed, ret=%d!!!", ret); + rc = camera_io_release(&mot_actuator_runtime[index].io_master); + CAM_ERR(CAM_ACTUATOR, "init cci failed!!! ret=%d,release rc=%d. try again!", ret, rc); + /*delay 100ms and try again*/ + usleep_range(100000, 100100); + ret = camera_io_init(&mot_actuator_runtime[index].io_master); + if (ret != 0) { + rc = camera_io_release(&mot_actuator_runtime[index].io_master); + CAM_ERR(CAM_ACTUATOR, "try again init cci failed!!! ret=%d, release rc=%d", ret, rc); + } } return ret; } @@ -381,16 +458,119 @@ int32_t mot_actuator_release_cci(uint32_t index) return ret; } +static int32_t mot_actuator_launch_lens(uint32_t index, uint32_t dac_value) +{ + uint32_t cur_len_pos = mot_dev_list[mot_device_index].actuator_info[index].init_pos; + uint32_t last_len_pos = 0; + int stageIndex; + unsigned int consumers = 0; + int32_t ret = 0; + uint32_t lens_launch_pos = dac_value; + mot_lens_step const *lens_launch_table = mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_step; + + if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_needed == false) { + CAM_DBG(CAM_ACTUATOR, "Launch lens is not needed."); + return 0; + } + while (cur_len_pos < lens_launch_pos) { + consumers = mot_actuator_get_consumers(); + if ((consumers & (~CLINET_VIBRATOR_MASK)) != 0) { + CAM_WARN(CAM_ACTUATOR, "Launch lens was broken by other actuator requests."); + break; + } + + for (stageIndex=0; stageIndex 0) { + cur_len_pos += lens_launch_table[stageIndex].step; + break; + } + } + + if (stageIndex == LAUNCH_LENS_MAX_STAGES && cur_len_pos < lens_launch_pos) { + cur_len_pos += 10; + } + + if(last_len_pos == cur_len_pos) + /*break the cycle when cur_len_pos didn't update*/ + break; + else + last_len_pos = cur_len_pos; + + ret = mot_actuator_move_lens_by_dac(index, cur_len_pos); + + if (ret < 0 ) { + CAM_ERR(CAM_ACTUATOR, "Launch Lens encounter CCI error, break now."); + break; + } + + if (cur_len_pos >= lens_launch_pos) { + /*For skipping the last delay*/ + CAM_DBG(CAM_ACTUATOR, "Launch lens done."); + break; + } + + usleep_range(2000, 3000); + } + + // from 512 to 0 + while (cur_len_pos > lens_launch_pos) { + consumers = mot_actuator_get_consumers(); + if ((consumers & (~CLINET_VIBRATOR_MASK)) != 0) { + CAM_WARN(CAM_ACTUATOR, "Launch lens was broken by other actuator requests."); + break; + } + + for (stageIndex = 0; stageIndex < LENS_MAX_STAGES; stageIndex++) { + if (lens_launch_table[stageIndex].kneePoint == 0 && lens_launch_table[stageIndex].step == 0) { + break; + } + + if (cur_len_pos >= lens_launch_table[stageIndex].kneePoint && lens_launch_table[stageIndex].step > 0) { + cur_len_pos -= lens_launch_table[stageIndex].step; + break; + } + } + + if (lens_launch_table[stageIndex].step == 0 && cur_len_pos > lens_launch_pos) { + cur_len_pos -= 10; + if (cur_len_pos < 10) + cur_len_pos = 0; + } + + ret = mot_actuator_move_lens_by_dac(index, cur_len_pos); + + if (ret < 0 ) { + CAM_ERR(CAM_ACTUATOR, "Launch Lens encounter CCI error, break now."); + break; + } + + if (cur_len_pos <= lens_launch_pos) { + /*For skipping the last delay*/ + CAM_DBG(CAM_ACTUATOR, "Launch lens done."); + break; + } + + usleep_range(10000, 12000); + } + return ret; +} + static int32_t mot_actuator_vib_move_lens(uint32_t index) { int32_t ret = 0; + unsigned int consumers = 0; if (mot_device_index >= MOT_DEVICE_NUM || index >= MAX_ACTUATOR_NUM) { CAM_ERR(CAM_ACTUATOR, "INVALID device!!!"); return -1; } - if (mot_actuator_state <= MOT_ACTUATOR_IDLE || mot_actuator_state >= MOT_ACTUATOR_RELEASED) { + consumers = mot_actuator_get_consumers(); + + if (consumers & CLINET_CAMERA_MASK) { + /*Don't init actuator when camera on*/ + CAM_WARN(CAM_ACTUATOR, "Camera is holding actuator,don't init actuator for vibrator,consumers=%d",consumers); + } else if (mot_actuator_state <= MOT_ACTUATOR_IDLE || mot_actuator_state >= MOT_ACTUATOR_RELEASED) { mot_actuator_init_runtime(); mot_actuator_power_on(index); ret = mot_actuator_init_cci(index); @@ -415,8 +595,6 @@ static int32_t mot_actuator_vib_move_lens(uint32_t index) if (ret == 0 && mot_actuator_state == MOT_ACTUATOR_INITED) { /*Move lens to the specified position.*/ - unsigned int consumers = mot_actuator_get_consumers(); - CAM_DBG(CAM_ACTUATOR, "actuator consumers: %d", consumers); if ((consumers & CLINET_VIBRATOR_MASK) == 0) { @@ -425,9 +603,18 @@ static int32_t mot_actuator_vib_move_lens(uint32_t index) if (consumers == 0) { /*Just move lens when camera off and before first vibrating*/ - ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); + /*use launch_lens to move lens step-by-step,reduce TICK noise*/ + if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_needed == true) { + ret = mot_actuator_launch_lens(index, mot_actuator_runtime[index].safe_dac_pos); + usleep_range(10000, 12000); + }else { + ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); + /*delay 10~12ms to wait lens move to specify location*/ + usleep_range(10000, 12000); + } if (ret == 0) { - CAM_DBG(CAM_ACTUATOR, "actuator:%d is safe now, please start vibrating"); + CAM_DBG(CAM_ACTUATOR, "actuator is safe now, safe_dac_pos:%d, please start vibrating.", + mot_actuator_runtime[index].safe_dac_pos); } else { CAM_ERR(CAM_ACTUATOR, "write dac failed, ret=%d!!!", ret); }