分享

[z]PMIC Battery Driver

 techres 2012-07-28

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);

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多