转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静 <xianjimli at hotmail dot com>
DA9034是一个集成了电源管理、音频设备、触摸屏控制器和能用A/D|D/A转换的多功能芯片。最近读了一下相关驱动程序,这里记些笔记,不成体系,作为备忘而已。有兴趣的朋友可以一起讨论。
充电驱动程序原理如下:注册中断事件PMIC_EVENT_CHARGER | PMIC_EVENT_VBUS,在有充电器和USB线插入的时候,驱动程序可以感知,然后启动或关闭充电。
充电驱动是一个platform device,在littleton.c中定义:
static struct platform_device micco_charger_device = {
.name = "micco-charger",
.id = -1,
};
充电驱动程序在drivers/char/micco_charger.c里:
static struct platform_driver charger_driver = {
.driver = {
.name = "micco-charger",
},
.probe = charger_probe,
.remove = charger_remove,
};
在函数charger_probe里:
先注册了一个mics设置,不过里的操作都空的,似乎没有什么用处。作者是本意可能是用它来读取充电状态的。
ret = misc_register(&charger_miscdev);
if (ret < 0)
return ret;
static struct file_operations charger_fops = {
.owner = THIS_MODULE,
.open = charger_open,
.release = charger_release,
.write = charger_write,
.read = charger_read,
};
static struct miscdevice charger_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "micco_charger",
.fops = &charger_fops,
};
然后注册中断处理函数,从前面的笔记中,我们知道所有的DA9034都会这样做。
/* Charger should handle EVENT_CHARGER and VBUS */
ret = pmic_callback_register((PMIC_EVENT_CHARGER | PMIC_EVENT_VBUS),
micco_charger_interrupt);
最后初始化DA9034相关的寄存器:
micco_read(MICCO_IRQ_MASK_A, &val);
val &= ~0x78;
micco_write(MICCO_IRQ_MASK_A, val);
...
在函数里micco_charger_interrupt根据中断事件做相应处理:
if (event & (PMIC_EVENT_TBAT | PMIC_EVENT_REV_IOVER | PMIC_EVENT_IOVER)) {
stop_charging();
} else if (event & PMIC_EVENT_CHDET) {
...
start_charging();
...
} else if (event & PMIC_EVENT_VBUS) {
/* USB cable detected */
...
start_charging();
...
开始充电和停止充电,只是设置相应寄存器:
static void stop_charging(void)
{
u8 val;
micco_read(MICCO_CHARGE_CONTROL, &val);
val &= ~0x80;
micco_write(MICCO_CHARGE_CONTROL, val);
return;
}
static void start_charging(void)
{
micco_write(MICCO_CHARGE_CONTROL, 0xAA);
return;
}