rhode: Actuator noise reduction
details: To eliminate the resonance noise during system vibrator vibrating, set actuator to DAC 1023 position,then the resonance noise can be obviously improved. To achieve the combination between vibrator and camera AF actuator,we implement: - Actuator separately control during camera power off. Change-Id: Ic6ed6370b59d189c8b8f81055c98829be1125b88 Signed-off-by: qiaopf1 <qiaopf1@motorola.com> Reviewed-on: https://gerrit.mot.com/2163432 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shuo Wang <wangsh18@motorola.com> Reviewed-by: Long Cheng <chengl1@motorola.com> Reviewed-by: Zhichao Chen <chenzc2@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
1 parent
98933b9b12
commit
41c6737d79
1 file changed
+195
-8
@@ -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<LAUNCH_LENS_MAX_STAGES; stageIndex++) {
|
||||
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 (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);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user