13783PMIC及其外围电路使其能够探测充电电源的存在,然后对电池进行充电,辅助电路还能探测和阻止过充电。PMIC Battery Driver附加的功能还有面作用:
1、 支持USB充电
2、 支持电源充电
电池的电压水平能够用AD来监视,过低电压和电池寿命已到能够被通知通过使用硬件中断系统。
PMIC Battery Driver提供IOCTL接口来进行控制和监视电池及充电状态。其中必须的功能有:
1、 充电管理的API包括选择正确的充电通道。
2、 配置充电的模式,比如充电电流。
3、 配置配置电池电压、电流水平监视以及end-of-life函数。
PMIC Battery Drive提供了IOCTL接口通过/dev/pmic_battery设备,每个IOCTL调用都会带来对应的PMIC控制寄存器的操作,当然,这个操作要通过PMIC protocol and SPI drivers来完成。
事件回调函数会通过PMIC protocol driver来直接进行注册,注册的函数会被调用当对应的事件被探测到,并且该事件导致的中断被PMIC protocol driver获知。
在初始化时要注册一个/dev/pmic_battery设备,使得应用层能够访问设备驱动通过IOCTL接口。
源代码在/<ltib_dir>/rpm/BUILD/linux- 2.6.24 /drivers/mxc/pmic/mc13783下,
pmic_battery.c 是PMIC battery 用户端的驱动
pmic_battery_defs.h 是对硬件寄存器的定义
阅读代码pmic_battery.c如下:
一.关于驱动的注册的代码
在代码pmic_battery.c的底部,有如下注册代码:
static int __init pmic_battery_init(void)
{
pr_debug("PMIC Battery driver loading.../n");
return platform_driver_register(&pmic_battery_driver_ldm);
}
static void __exit pmic_battery_exit(void)
{
platform_driver_unregister(&pmic_battery_driver_ldm);
pr_debug("PMIC Battery driver successfully unloaded/n");
}
module_init(pmic_battery_init);
module_exit(pmic_battery_exit);
从以上代码可看出这里进行了电源管理驱动pmic_battery_driver_ldm的注册,而关于这个驱动的定义同样在该文件中,定义为:
static struct platform_driver pmic_battery_driver_ldm = {
.driver = {
.name = "pmic_battery",
.bus = &platform_bus_type,
},
.suspend = pmic_battery_suspend,
.resume = pmic_battery_resume,
.probe = pmic_battery_probe,
.remove = pmic_battery_remove,
};
其中pmic_battery_probe是该驱动注册时要调用的回调函数,这个函数很重要,在这个函数里可以进行设备device的保存,以及资源的获得,以及其他的。
二.Driver驱动pmic_battery_probe回调函数阅读
static int pmic_battery_probe(struct platform_device *pdev)
{
int ret = 0;
struct class_device *temp_class;
pmic_battery_major = register_chrdev(0, PMIC_BATTERY_STRING,
&pmic_battery_fops);
if (pmic_battery_major < 0) {
printk(KERN_ERR "Unable to get a major for pmic_battery/n");
return pmic_battery_major;
}
init_waitqueue_head(&suspendq);
pmic_battery_class = class_create(THIS_MODULE, PMIC_BATTERY_STRING);
if (IS_ERR(pmic_battery_class)) {
printk(KERN_ERR "Error creating PMIC battery class./n");
ret = PTR_ERR(pmic_battery_class);
goto err_out1;
}
temp_class = class_device_create(pmic_battery_class, NULL,
MKDEV(pmic_battery_major, 0),
NULL, PMIC_BATTERY_STRING);
if (IS_ERR(temp_class)) {
printk(KERN_ERR "Error creating PMIC battery class device./n");
ret = PTR_ERR(temp_class);
goto err_out2;
}
pmic_batt_led_control(true);
pmic_batt_set_5k_pull(true);
printk(KERN_INFO "PMIC Battery successfully probed/n");
return ret;
err_out2:
class_destroy(pmic_battery_class);
err_out1:
unregister_chrdev(pmic_battery_major, PMIC_BATTERY_STRING);
return ret;
}
其中在mc13783/pmic_battery_defs.h有关于字符串的定义:
#define PMIC_BATTERY_STRING "pmic_battery"
可以看出,register_chrdev(0, PMIC_BATTERY_STRING, &pmic_battery_fops);注册了一个字符设备,名字为pmic_battery,同时指定了它的fileoperations结构体为pmic_battery_fops,关于该结构体定义同样子该c文件中,如下:
static struct file_operations pmic_battery_fops = {
.owner = THIS_MODULE,
.ioctl = pmic_battery_ioctl,
.open = pmic_battery_open,
.release = pmic_battery_release,
};
可以看出该设备驱动的用户层操作接口只有三个,还包括打开和关闭的两个必须函数,真正进行操作的函数只有pmic_battery_ioctl一个函数。
三、设备驱动pmic_battery_ioctl函数阅读
……..略()………
四、事件的注册分析
在代码里,看到了以下函数,是用来进行注册和取消注册的,如何使用还有待分析,如
下:
PMIC_STATUS mc13783_battery_event(t_batt_event event, void *callback, bool sub)
{
pmic_event_callback_t bat_callback;
type_event bat_event;
bat_callback.func = callback;
bat_callback.param = NULL;
switch (event) {
case BAT_IT_CHG_DET:
bat_event = EVENT_CHGDETI;
break;
case BAT_IT_CHG_OVERVOLT:
bat_event = EVENT_CHGOVI;
break;
case BAT_IT_CHG_REVERSE:
bat_event = EVENT_CHGREVI;
break;
case BAT_IT_CHG_SHORT_CIRCUIT:
bat_event = EVENT_CHGSHORTI;
break;
case BAT_IT_CCCV:
bat_event = EVENT_CCCVI;
break;
case BAT_IT_BELOW_THRESHOLD:
bat_event = EVENT_CHRGCURRI;
break;
default:
return PMIC_PARAMETER_ERROR;
}
if (sub == true) {
CHECK_ERROR(pmic_event_subscribe(bat_event, bat_callback));
} else {
CHECK_ERROR(pmic_event_unsubscribe(bat_event, bat_callback));
}
return 0;
}
/*!
* This function is used to subscribe on battery event IT.
*
* @param event type of event.
* @param callback event callback function.
*
* @return This function returns 0 if successful.
*/
PMIC_STATUS pmic_batt_event_subscribe(t_batt_event event, void *callback)
{
if (suspend_flag == 1)
return PMIC_ERROR;
return mc13783_battery_event(event, callback, true);
}
/*!
* This function is used to un subscribe on battery event IT.
*
* @param event type of event.
* @param callback event callback function.
*
* @return This function returns 0 if successful.
*/
PMIC_STATUS pmic_batt_event_unsubscribe(t_batt_event event, void *callback)
{
if (suspend_flag == 1)
return PMIC_ERROR;
return mc13783_battery_event(event, callback, false);
}