MTK平台闪光灯驱动分析
以前没写过博客,总想写着来着,把之前学到的做过的东西都记录下来,但是一直没有时间也没那么大的决心。这次趁着刚换工作,正在学习熟悉平台不是太忙的机会,把自己总结的文档写下来,算是给自己一个全新的开始吧。
这次我分析的事闪光灯控制器的驱动代码,使用的芯片是TI的LM3644双闪光灯控制芯片,由于是第一次写,就只分析这个驱动好了,该驱动的相关技术知识在接下来的博客中一一分析,不过现在先记录一下,免得之后忘了。
写过这篇博客之后,要对接下来的知识进行分析。
1. Linux文件系统挂载流程
2. devtmpfs的挂载流程及运行原理
3. platform总线初始化及原理
4. I2C总线初始化及原理分析
在第3,4目标中要掺杂Linux设备模型及sysfs文件系统框架的介绍。好了,给自己定好目标了,接下来开始今天的正片吧。
一、芯片工作原理
该芯片通过一个I2C接口与AP通信。可为闪光灯模式的LED提供93mA到1.5A的电流,可为手电筒模式的LED提供48.4mA到375mA的电流。我们可以通过I2C设置该芯片内部的寄存器,继而控制哪个闪光灯开启/关闭、进入闪光灯/手电筒模式、闪光灯模式时的电流大小、手电筒模式的电流大小、闪光灯开启/结束时间等。该芯片的I2C地址是0x63,挂在AP的I2C Bus 2。I2C地址是芯片手册上可以看到的,挂在I2C的哪条总线上这个你要和你的HW工程师沟通或者自己看原理图。
二、硬件连接图
由于信息安全问题,我不能把公司项目的硬件原理图贴出来,但是可以贴出datasheet上的参考电路,大致是一样的。
我们只使用上图的SDA,SCL引脚用于I2C通信。
三、代码分析
3.1、驱动初始化
在驱动文件中如下所示的代码是该内核模块的入口和出口。
module_init(flashlight_init);
module_exit(flashlight_exit);
很明显其初始化函数是flashlight_init()函数。接下来我们开看该函数是怎么实现的。
static int __init flashlight_init(void)
{
int ret = 0;
logI("[flashlight_probe] start ~");
ret = platform_device_register (&flashlight_platform_device);//注册platform设备
if (ret) {
logE("[flashlight_probe] platform_device_register fail ~");
return ret;
}
ret = platform_driver_register(&flashlight_platform_driver);//注册platform驱动
if(ret){
logE("[flashlight_probe] platform_driver_register fail ~");
return ret;
}
register_low_battery_notify(&Lbat_protection_powerlimit_flash, LOW_BATTERY_PRIO_FLASHLIGHT);//添加低电量notify函数
register_battery_percent_notify(&bat_per_protection_powerlimit_flashlight, BATTERY_PERCENT_PRIO_FLASHLIGHT);
//@@ register_battery_oc_notify(&bat_oc_protection_powerlimit, BATTERY_OC_PRIO_FLASHLIGHT);
logI("[flashlight_probe] done! ~");
return ret;
}
在此函数中有两个重要的函数,platform_device_register( ),platform_driver_register( )。他们分别是platform设备,和platform设备驱动注册。这遵循linux设备模型原理,分别把device,和driver注册进platform bus中。同时由于platform bus中的mat