1.概述
actuator驱动信息文件是指vendor目录下的$ActuatorName_actuator.h文件(如gigaset_actuator.h)。此信息文件就是一个actuator_driver_ctrl_t结构体。包括actuator_params与actuator_tuned_params两部分,即driver与tunning两部分。文档以目前最主流的VCM为例进行参数的介绍。
2.driver部分信息actuator_params
act_type:actuator类型,目前就VCM、PIEZO及HVCM三种
data_size:数据长度(VCM指传输lens位置的数据长度?)
init_settings:actuator的初始化参数
reg_tbl:寄存器列表,用来下actuator移动参数,这些参数又包括如下一些参数选项
reg_write_type:写入数据的格式,VCM一般使用DAC,10位表示0~1023
reg_addr:写入数据寄存器地址,如果不需要具体地址,则配置为0xFFFF
data_shift:数据对应寄存器的移位
hw_mask:其它bit位的控制设置,比如VCM的ring_ctrl
hw_shift:控制设置对应寄存器的移位
reg_tbl部分举例AD5823如下:
.reg_tbl =
{
.reg_tbl_size = 1,
.reg_params =
{
{
.reg_write_type = MSM_ACTUATOR_WRITE_DAC,
.hw_mask = 0x00000400, 除data外的其它b it位的mask
.reg_addr = 0x04, //寄存器写地址为reg04
.hw_shift = 0, //hw_mask已经制定了明确的bit位,所以不再需要移位
.data_shift = 0, //reg05[7:0]为数据,所以不需要移位
},
},
},
查看驱动代码大致如下:
value = (next_lens_position
write_arr[i].data_shift) |
((hw_dword write_arr[i].hw_mask)
write_arr[i].hw_shift);
最终获得I2C数据代码如下:
i2c_byte1 = (value 0xFF00) 8; // 对应reg04寄存器值
i2c_byte2 = value 0xFF; //对应reg05寄存器值
这里获得的value及需要写入寄存器的值,上面的hw_dword参数来自于tunning参数表中的hw_params (此驱动的hw_params值为0x00000400)。下面再来看看AD5823的寄存器介绍:
上图中reg04的bit[3]设置是否开启RING_CTRL模式,bit[7:4]为零,由前面讲到的hw_dword及hw_mask来设置。
再举例DW9714如下:
.reg_params =
{
{
.reg_write_type = MSM_ACTUATOR_WRITE_DAC,
.hw_mask = 0x0000000F, //除data外的其它b it位的mask
.reg_addr = 0xFFFF, //没有寄存器地址
.hw_shift = 0, //hw_mask已经制定了明确的bit位,不再需要移位
.data_shift = 4, //10bit的数据移位
},
},
再看DW9714规格书寄存器介绍如下:
与代码对比可以看出,byte2的S[3:0]对应给出了mask位,需要根据tunning参数的hw_dword来确定具体的模式,此驱动给出的tunning参数为0x00000004,即S[3:0]-0100;而PD及FLAG被设置为0。
3. tunning部分actuator_tuned_params
tunning参数分为向近景方向移动与向远景方向移动两部分(MOVE_NEARMOVE_FAR),每个部分又可设定多个移动场景,各个场景参数可以单独设定,以便实现更细化的控制。
高通在这里实现了一个lens位置数组,数组中的具体值对应着实际的lens位置,所以在驱动中可以看到step_pos与lens_pos两个参数,分别对应词数组表的下标index及当前index对应的值(此值为lens的实际位置)。代码体现如下:
curr_lens_pos = a_ctrl-step_position_table[a_ctrl-curr_step_pos];
具体一些参数介绍如下:
initial_code:初始lens的位置,对应VCM的0~1023的范围
scenario_size:向近景与远景方向移动部分的场景数
ringing_scenario:各对应场景向近景与远景方向的移动步数最大值
region_size:对lens的移动进行多个区段划分,可实现更细化的设置(针对非线性?)
region_params:对应每个区段的在移动步数表中的index范围,即bound
step_bound:对应具体的macro及infinity的bound边界值,所有区段合起来就是总 长度(对应上面提到的表的长度)
code_per_step:在当前分区中每个step对应移动的实际lens长度
上面这些参数一起最终声场移动步数表数组,具体在msm_actuator_init_step_table函数中实现,具体可查看代码(msm_actuator.c文件),关键语句:
cur_code = set_info-af_tuning_params.initial_code; //初始值
code_per_step =a_ctrl-region_params[region_index].code_per_step;//当前分区的步长
cur_code += code_per_step; //每步叠加一个步长
damping:这部分参数用来做刹车消除磁滞,与前面的场景参数相呼应。
ringing_params:各个具体场景对应的参数设置。下面三个参数为当前场景各区段的参数设置。
damping_step: //对应场景lens每次移动的最大步长
damping_delay: //对应场景lens每次移动I2C命令间的延时
hw_params: // 对应场景actuator硬件寄存器的控制设置
上面写了那么多,总结起来也就下面几点:
1.有一个数组lens_pos[max_bound]----- 对应前面多次提到的移动步数数组
2.为了更好的消除磁滞,设定了多种移动的规则,根据每次移动的最大step来确定使用哪个规则----规则即前面讲的场景,最大step就是前面的ringing_scenario数组中对应每个场景的值,这个值表示数组的下标。
3.将整个移动范围分成多个区间,细分每个区间lens步进,针对线性化问题改善。
4.针对不同场景的不同区间设定磁滞消除参数。
另外要注意的一点是高通AF算法发出的参数为step数量,而不是具体的lens位置,具体lens位置需要查表获得。其实从这部分参数设定来看可以发现这里主要对驱动芯片的驱动方式进行设定,算法上前进步长的判断还是在其它地方实现,只要控制了每次的step长度,也就相当于进行了磁滞控制,所以参数damping_step设置为最大值是可以理解的。
下面举例来说明一下:
.actuator_tuned_params =
{
.scenario_size =
{
1, /* MOVE_NEAR */ // 场景数量,这里就定义了一个场景
1, /* MOVE_FAR */
},
.ringing_scenario =
{
/* MOVE_NEAR */
{
400, //对应场景最大步子,移动步数小于此值表示适用此场景参数。这里只定义了一个场景,所以将此值设置为最大步数(即数组容量)。此值表示每次移动步数的步子大小判断,不是具体的数组下标。
},
/* MOVE_FAR */
{
400,
},
},
.initial_code = 70, // 初始lens的位置
.region_size = 1, //对lens的移动进行多个区段划分,用于不同区间磁滞的参数设定
.region_params =
{
{
.step_bound = // 对应每个区段的step bound,这里只定义了一个区间,即整个VCM移动过程使用同样的磁滞处理。
{
400, /* Macro step boundary*/ // 当前区段的结束step
0, /* Infinity step boundary*/ //当前区段的起始step
},
.code_per_step = 1, // step表中lens的步进长度
},
},
.damping =
{
/* damping[MOVE_NEAR] */
{
/* Scenario 0 */ // 当前场景的磁滞参数
{
.ringing_params =
{
/* Region 0 */ // 当前区间的磁滞参数
{
.damping_step = 0x3FF, //这里设置为最大值1023,相当于不做磁滞处理,直接一次设定到需要的值。
.damping_delay = 6000,
.hw_params = 0x00000000,
},
},
},
},
/* damping[MOVE_NEAR] */
{
/* Scenario 0 */
{
.ringing_params =
{
/* Region 0 */
{
.damping_step = 0x3FF,
.damping_delay = 6000,
.hw_params = 0x00000000,
},
},
},
},
},
}, /* actuator_tuned_params */