1.马达以及相关寄存器介绍
以dw9763为例进行介绍;音圈马达是通过不同的电流值,产生不同推力来推动镜头; 10bit(普遍使用)数据位,对应0-1023 DAC code值;0-1023 code代表0mA电流->max mA电流,如果是中置马达,则电流会有负值(-100mA~100mA);电流与code的关系,如下
output_current / Decimal(D[9:0]) = 100mA / 1023 ; 其中Decimal(D[9:0]) 就是给马达的位置 code值;
例如某一款马达dw9764,10bit的输出,最大输出电流是100mA,但10bit值为1111111111,可以输出100mA的电流;那么想要输出25mA的电流,那么code值应该设置为多大?答案是255,即10bit值为1001010101。
通过控制DAC code值来改变输出电流值的大小,也就是向寄存器0x03写入的是code值,而不是电流值;ISP通过清晰度来判断该给多少DAC值;
先看下dw9764的datasheet,了解下寄存器
SAC/PRESCALE 即模式选择和时钟分频,一般默认是选择SAC4;寄存器地址0x06,其中高3bit是属于SAC[2:0],低3bit是PRESC[2:0];因此代码中的dev_vcm->step_mode 需要左移5bit; dev_vcm->t_div & 0x07 即保留低3bit;然后mode_val | = (dev_vcm->t_div & 0x07 )
vbusy的判断,在向MSB/LSB (也就是DAC code)寄存器写值的时候,vbusy bit必须为0;在SAC operation时,vbusy bit保持为1;vbusy由寄存器0x05控制的。
马达位移控制的流程大致如下:
2.af驱动介绍
驱动中的主要函数:
dw9763_set_pos
dw9763_update_vcm_cfg
dw9763_init // 可以初始化选定下电流模式,即SAC
dw9763_move_time函数的实现主要参考datasheet中的规定:
启动电流 : VCM 刚好能够推动模组镜头从模组镜头可移动行程最近端(模组远焦)移动,此时VCM driver ic的输出电流值定义为启动电流.
额定电流: VCM刚好推动模组镜头至模组镜头可移动行程的最远端(模组近焦),此时VCM driver ic的输出电流值定义为额定电流.
dw9763: dw9763@0c { // vcm驱动配置,支持AF时需要有这个设置
compatible = "dw9763";
status = "okay";
reg = <0x0c>;
rockchip,vcm-start-current = <20>; // 马达的启动电流
rockchip,vcm-rated-current = <100>; // 马达的额定电流
rockchip,vcm-step-mode = <4>; // 马达驱动ic的电流输出模式
rockchip,camera-module-index = <0>; // 模组编号
rockchip,camera-module-facing = "back"; // 模组朝向,有"back"和"front" };
ov13850: ov13850@10 {
......
lens-focus = <&vm149c>; // vcm驱动设置,支持AF时需要有这个设置
...... };
马达的v4l2-ctl命令控制: v4l2-ctl -d /dev/v4l-subdevXXX --set-ctrl focus_absolute=YYY XXX是马达设备编号 YYY是马达code值,取值范围0~64 如果会移动,说明底层马达控制 OK
RK AF算法将模组镜头整个可移动行程的位置参数定义为[0,64],模组镜头整个可移动行程在VCM驱动电流上对应的变化范围为[启动电流,额定电流],dw9763_set_pos 该函数中建议实现这2者间的映射换算关系;
dev_vcm->start_current = dev_vcm->vcm_cfg.start_ma * DW9763_MAX_REG / dev_vcm->max_ma;
3.马达的电源介绍
1.一般模组中sensor和马达共用avdd(vcc2v8_dvp),所以dts中需要将马达的电源引用配置上:avdd-supply=<&vcc2v8_dvp>;
2.默认camera使用的电源都需要有属性:regulator-boot-on,不能屏蔽;
3.regulator-always-on是表示电源常供,如果camera,马达dts有引用就要屏蔽上述第二点,想要默认常供就加上,同时camera节点中对电源的引用要去掉,不然会堆栈报错。
vcc2v8_dvp: LDO_REG9 {
// regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-name = "vcc2v8_dvp";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <2800000>;
};
};
4.android上层相关设置
-
camera3_profiles.xml 也需要配置马达,注意只有RAW SENSOR才支持马达控制 <control.afAvailableModes value="OFF,AUTO,MACRO,CONTINUOUS_VIDEO,CONTINUOUS_PICTURE,EDOF"/> <control.maxRegions value="1,0,1"/> <lens.info.minimumFocusDistance value="0.1"/> <!-- HAL may override this value from CMC for RAW sensors -->
-
如果录像中不需要马达对焦,可以尝试将 CONTINUOUS_VIDEO 关键字去掉
<request.availableRequestKeys 中需要包含:control.afRegions 字段 <request.availableResultKeys 中需要包含: control.afRegions 字段 <sensorType value="SENSOR_TYPE_RAW"/> // SENSOR_TYPE 需要是 RAW 的而不是 SOC;
3. 效果文件如果支持马达对焦 效果文件中 contrast_af 中 enable 设置为:1
5.调试碰到的一些问题
5.1 录像无法对焦
预览可以对焦,但是录视频不会对焦,试试如下修改:
5.2 摄像头退出有哒的声音
摄像头预览退出的过程会触发一声轻轻的 “哒” 声,该响声是由马达模组发出来的;有可能是模组电源中的马达电源被sensor控制了,所以sensor预览退出时下电,导致马达的电源也被关闭了,所以才出现了 "哒" 的响声。 可以做个试验,在sensor驱动中的suspend函数,将power_off注释,结果显示摄像头预览退出,没有了 "哒"的响声,验证了我们的猜想。所以解决方法是让马达在sensor之前关闭,可以在sensor的suspend调用power_off之前调用马达的远焦复位操作;dw9714中有在上下电函数中做处理,逐步移动马达到远焦位置,可参考dw9714去实现!
5.3 摄像头无法聚焦且不清晰
摄像头无法聚焦,不清晰,文字也看不清楚;首先查阅马达的规格书,看是否为中置马达,里面电流有负值的,dts中的启动电流截止电流要用dac值表示,取值范围是0~1023,对应-100mA ~ 100mA
5.4 af出现i2c通信异常
断电上电重新开机,再打开摄像头,会出现af通信失败的问题;解决方法可以是先注册camera,后注册af