直白的记录一下,翻译的文件来自kernel:
kernel/documentation/devicetree/bindings/leds/leds-qpnp-flash.txt
---------------
QPNP (Qualcomm Technologies Plug N Play) Flash LED,
用于在相机sensor拍照时,背景比较暗时能拍出更好的图片。
它是高通平台上PMIC的一部分。PMIC通过SPMI连接到主机处理器。
(也就是说,这玩意就是高通平台的闪光灯和手电筒驱动)
-----------
dsti节点:? ? ? ?
compatible :? ? ? ? "qcom, qpnp-flash-led"
qcom, startup-dly: delay before flashing after flash excuted(value: 10, 32, 64 ,128us)
qcom, thermal-derate-threshold: thermal threshold for derate, (80,100摄氏度这种)
--------------------------
Example:
qcom,leds@d300 {
compatible = "qcom,qpnp-flash-led";
status = "okay";
reg = <0xd300 0x100>;
label = "flash";
qcom,headroom = <500>;
qcom,startup-dly = <128>;
qcom,clamp-curr = <200>;
qcom,pmic-charger-support;
qcom,self-check-enabled;
qcom,thermal-derate-enabled;
qcom,thermal-derate-threshold = <80>;
qcom,thermal-derate-rate = "4_PERCENT";
qcom,current-ramp-enabled;
qcom,ramp_up_step = "27US";
qcom,ramp_dn_step = "27US";
qcom,vph-pwr-droop-enabled;
qcom,vph-pwr-droop-threshold = <3200>;
qcom,vph-pwr-droop-debounce-time = <10>;
qcom,headroom-sense-ch0-enabled;
qcom,headroom-sense-ch1-enabled;
pm8226_flash0: qcom,flash_0 {
label = "flash";
qcom,led-name = "led:flash_0";
qcom,default-led-trigger =
"flash0_trigger";
qcom,max-current = <1000>;
qcom,duration = <1280>;
qcom,id = <0>;
qcom,current = <625>;
boost-supply = <&pm8226_chg_boost>;
};
pm8226_torch: qcom,torch_0 {
label = "torch";
qcom,led-name = "led:torch_0";
qcom,default-led-trigger =
"torch0_trigger";
boost-supply = <&pm8226_chg_boost>;
qcom,max-current = <200>;
qcom,id = <0>;
qcom,current = <120>;
boost-voltage-max = <3600000>;
};
};
-----------------
驱动:
? ? ? ? spmi_driver_register(&qpnp_flash_led_driver);
(spmi:连接soc的集成电源控制器和电源管理IC)
结构体是struct qpnp_flash_led {
struct spmi_device;
struct flash_led_platform_data *pdata;
//flash_node_data结构记录了一些灯的控制参数
struct flash_node_data *flash_node;
struct power_supply *battery_psy;
struct muxtext flash_led_lock;
int num_leds;
u16 base;
u8 peripheral_type;
}
记录一下驱动代码的结构:
spmi_driver_register(&qpnp_flash_led_driver); //注册驱动,匹配device, 进入probe
|
qpnp_flash_led_probe(struct spmi_device *spmi)
|
--- a. 申请qpnp_flash_led空间
----b. qpnp_flash_led_parse_common_dt(led, node) //解析dtsi
----c. 申请flash_node_data实例的空间,初始化填充dtsi里面的参数
初始化了两个函数指针成员
brightness_set = qpnp_flash_led_brightness_set
brightness_get = qpnp_flash_led_brightness_get
---d. INIT_WORK(&led->flash_node[i].work, qpnp_flash_led_work);
---e. led_class_dev_register(&spmi->dev, &led->flash_node[i]->dev);
---f. 然后是dtsli解析第二层的节点,区分是闪光灯还是手电筒的
qpnp_flash_led_parse_each_led_dt(led, &led->flash_node[i])
---g. 分别创建了文件节点
sysfs_create_file(&led->flash_node[i].cdev.dev->kobj, &qpnp_flash_led_attrs[j].attr);
-------------
驱动就是这个架子
主要的函数就是 static void qpnp_flash_led_work(struct work_struct *work);
这个里面的if...else判断了手电筒和闪光灯,功能函数是通过qpnp_ledmasked_write来操作的,该函数可以通过地址等参数来设置灯使能以及亮度。
函数:
//kernel/driver/leds/leds-qpnp-flash.c
static int qpnp_led_masked_write(struct spmi_device *spmi_dev, u16 addr, u8 mask, u8 val);
---------------------driver end----------------------
那么上层应用是怎么个调用的呢 ?
App里面打开手电筒就是
private CameraManger manager;
manager = (Cameramanager)getSystemService(Context.CAMERA_SERVICE);
manager.setTorchMode("0", true);
--------
流程:
manager.setTorchMode
|
cameraManager.seTorchMode //frameworks/base/core/java/android/hardware/camera2/CameraManager.java
|
cameraService.setTorchMode(cameraId, enabled, mTorchClientBinder) //frameworks/base/core/java/android/hardware/camera2/CameraManager.java
|
CameraService:setTorchMode(const String& cameraId, bool enabled, const sp<IBinder>& clienBinder) //frameworks/av/services/camera/libcameraservice/CameraService.cpp
|
err = mFlashlight->setTorchMode(id, enabled); //mFlashlight = new CameraFlashlight(*mModule, *this);
|
CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) //frameworks/av/services/camera/libcameraservice/CameraFlashlight.cpp
|
res = mFlashControl->setTorchMode(cameraId, enabled); // mFlashControl = new ModuleFlashControl(*mCameraModule, *mCallbacks);
|
mCameraModule->setTorchMode(cameraId.toString, enabled);
|
CameraModule::setTorchMode(const char* camera_id, bool enable); //frameworks/av/services/camera/libcameraservice/common/CameraModule.cpp
|
res = mModule->set_torch_mode(cameraid, enable); //Camera_module_t
|
|
终 于 到 HAL 层 了
|
迷了还在看,怎么在hardware里看不到set_torch_mode原型 ??
晚上全局搜了,很奇怪没搜到。。。按道理有个c文件里面gpio_device_t的结构赋值这个函数指针啊。。。。。。。先记录一下

?
|