pmic闪光灯电流控制的逻辑时从Hal下发电流,在kernel中做判断并工作
Hal
从下面的一段逻辑可以很清晰的得出,当没有tunning参数时,使用的时默认default 300mA,当tunning参数不为0的时候,则
从LED1Setting/LED2Setting中获取,preflash 120 mA + mainflash 900 mA
vendor/qcom/proprietary/camx/src/swl/sensor/camxflash.h
vendor/qcom/proprietary/camx/src/swl/sensor/camxflash.cpp
static const UINT FlashDefaultCurrent = 300; ///< Default flash current in mA
Flash::Flash()
for (UINT i = 0; i < MaxLEDTriggers; i++)
{
m_lowCurrent[i] = FlashDefaultCurrent; ///< Current used for preflash, torch
m_highCurrent[i] = FlashDefaultCurrent; ///< Current used for main flash
m_i2cCurrent[i] = FlashDefaultCurrent; ///< Current used for i2c current
}
CamxResult Flash::ExecuteProcessRequest(
if (FlashInfoTypePre == flashType)
{
if (LEDCurrents[LEDSetting1] != 0 ||
LEDCurrents[LEDSetting2] != 0)
{
m_lowCurrent[0] = LEDCurrents[LEDSetting1];
m_lowCurrent[1] = LEDCurrents[LEDSetting2];
m_i2cCurrent[0] = LEDCurrents[LEDSetting1];
m_i2cCurrent[1] = LEDCurrents[LEDSetting2];
}
else
{
CAMX_LOG_ERROR(CamxLogGroupSensor, "PreFlash Currents are Zero for RequestId = %llu", requestId);
}
}
else if (FlashInfoTypeMain == flashType)
{
if (LEDCurrents[LEDSetting1] != 0 ||
LEDCurrents[LEDSetting2] != 0)
{
m_highCurrent[0] = LEDCurrents[LEDSetting1];
m_highCurrent[1] = LEDCurrents[LEDSetting2];
m_i2cCurrent[0] = LEDCurrents[LEDSetting1];
m_i2cCurrent[1] = LEDCurrents[LEDSetting2];
}
else
{
CAMX_LOG_ERROR(CamxLogGroupSensor, "MainFlash Currents are Zero for RequestId = %llu", requestId);
}
}
Tunning
tunning/s5k3l6/Scenario.Default/XML/STATS/Flash.xml
可以得知preflash current = 120 mainflash current = 900
<LEDTable>
<enableDualLED type="bool">false</enableDualLED>
<dualLEDIntersectSlope type="float" range="[0.0,10.0]">1</dualLEDIntersectSlope>
<LEDPowerSize type="int" range="[2,6]">2</LEDPowerSize>
<LEDMixSize type="int" range="[1,16]">1</LEDMixSize>
<CCTTables>
<LED1Setting type="int" range="[0,unbounded]">120</LED1Setting>
<LED2Setting type="int" range="[0,unbounded]">0</LED2Setting>
<RGRatio type="float" range="[0.0,10.0]">1.289493</RGRatio>
<BGRatio type="float" range="[0.0,10.0]">0.274609</BGRatio>
<flux type="float" range="[0.0,100.0]">1</flux>
</CCTTables>
<CCTTables>
<LED1Setting type="int" range="[0,unbounded]">900</LED1Setting>
<LED2Setting type="int" range="[0,unbounded]">0</LED2Setting>
<RGRatio type="float" range="[0.0,10.0]">1.192793</RGRatio>
<BGRatio type="float" range="[0.0,10.0]">0.265689</BGRatio>
<flux type="float" range="[0.0,100.0]">4.818847</flux>
</CCTTables>
Kernel
从下面一段逻辑也可以很清晰的得出led_current_ma时HAL传下来的,flash_max_current时dtsi中解析的,
两者会做一次比较判断是否会超出支持范围,(torch max_current 500mA , flash max_current 1500mA)
adb shell “echo 0x1000 > /sys/module/cam_debug_util/parameters/debug_mdl”
kernel/msm-4.19/techpack/camera/drivers/cam_sensor_module/cam_flash/cam_flash_core.c
static int cam_flash_ops
if (op == CAMERA_SENSOR_FLASH_OP_FIRELOW) {
for (i = 0; i < flash_ctrl->torch_num_sources; i++) {
if (flash_ctrl->torch_trigger[i]) {
max_current = soc_private->torch_max_current[i];
if (flash_data->led_current_ma[i] <= max_current)
curr = flash_data->led_current_ma[i];
else
curr = max_current;
}
CAM_DBG(CAM_FLASH, "Led_Torch[%d]: Current: %d",
i, curr);
cam_res_mgr_led_trigger_event(
flash_ctrl->torch_trigger[i], curr);
}
} else if (op == CAMERA_SENSOR_FLASH_OP_FIREHIGH) {
for (i = 0; i < flash_ctrl->flash_num_sources; i++) {
if (flash_ctrl->flash_trigger[i]) {
max_current = soc_private->flash_max_current[i];
if (flash_data->led_current_ma[i] <=
max_current)
curr = flash_data->led_current_ma[i];
else
curr = max_current;
}
CAM_DBG(CAM_FLASH, "LED_Flash[%d]: Current: %d",
i, curr);
cam_res_mgr_led_trigger_event(
flash_ctrl->flash_trigger[i], curr);
}
} else {
CAM_ERR(CAM_FLASH, "Wrong Operation: %d", op);
return -EINVAL;
}
dtsi
以上就可以得出pmic 闪光灯修改电流具体的位置,这里还需要注意并非修改dtsi中的qcom,current-ma就可以,虽然qcom 注释时operation current,实际还得log确认或者硬件去量电流,dtsi中主要去关注qcom,max-current
pmi632_flash0: qcom,flash_0 {
label = "flash";
qcom,led-name = "led:flash_0";
qcom,max-current = <1500>;
qcom,default-led-trigger = "flash0_trigger";
qcom,id = <0>;
qcom,current-ma = <1000>;
qcom,duration-ms = <1280>;
qcom,ires-ua = <12500>;
qcom,hdrm-voltage-mv = <400>;
qcom,hdrm-vol-hi-lo-win-mv = <100>;
};
pmi632_torch0: qcom,torch_0 {
label = "torch";
qcom,led-name = "led:torch_0";
qcom,max-current = <500>;
qcom,default-led-trigger = "torch0_trigger";
qcom,id = <0>;
qcom,current-ma = <300>;
qcom,ires-ua = <12500>;
qcom,hdrm-voltage-mv = <400>;
qcom,hdrm-vol-hi-lo-win-mv = <100>;
};
Bringup
adb root
rem adb shell setenforce 0
adb shell "echo 0 > /sys/class/leds/led:switch_0/brightness"
adb shell "echo 10 > /sys/class/leds/led:flash_0/brightness"
adb shell "echo 1 > /sys/class/leds/led:switch_0/brightness"
adb shell "cat /sys/class/leds/led:flash_0/brightness"
pause
pmic的闪光灯的bringup其实最简单,其实就是去配置dtsi中的 flash-source/ torch-source/ switch-source,可以通过adb命令去测试,有些时需要flash_0 + flash_1,如果遇到闪光灯没有双闪,怀疑就是dualed没有配置对,之前遇到过一次,记不太清了,tunning参数中有enableDualLED需要注意,还有bringup的时候记得在全暗的环境下测试,这个也受tunning参数影响,没注意的话可能会以为闪光灯没功能