[RK3128][Android 6.0] RTC芯片PCF8563调试记录

硬件平台:RK3128

Android版本:6.0

Kernel版本:3.10.92

 

任务描述:

Rk3128 Android 6.0平台调试rtc芯片PCF8563,本以为很容易,结果碰到一些问题,在此记录下来。

 

一、添加设备信息

Dts中添加I2C设备:

    rtc@51 {

        compatible = "nxp,pcf8563";

        reg = <0x51>;

        irq_gpio = <&gpio0 GPIO_D4 IRQ_TYPE_EDGE_FALLING>;

    };

二、驱动调试

配置内核开关,使用内核默认驱动kernel/drivers/rtc/rtc-pcf8563.c。

 

I2C通信成功后,RTC就可以工作了。

 

但后来又遇到两个问题:


问题一、开机显示初始时间

通过查看开机日志发现如下错误:

low voltage detected, date/time is not reliable.

retrieved date/time is not valid.

出现第一条错误后,读取的时间有错误,校验不过,因此开机并不显示rtc中保存的时间,查看AT8563规格书(AT8563完全兼容PCF8563)发现这是VL位被置位。当VL为1时无法保证时间的准确,同样根据规格书提示,在检测到VL为1时,重新初始化寄存器时间值。

 

解决办法:

在驱动初始化时如果检测到VL=1,即重新初始化寄存器,同时把VL置0;

 

问题二、开机设置正确时间后,重启机器,时间仍为RTC中原始值,也就是说正确的时间并没有设置到RTC中,而RTC一直走着一个错误的时间,并在开机时显示。

 

分析过程:

通过查看日志发现在系统时间更改后,pcf8563_set_datetime并未执行,也就是说正确的时间并没有写入到RTC中,再往前跟发现alarm_set_rtc中alarmtimer_get_rtcdev出了问题。即没有获取到设备,而设备就是rtcdev这个全局变量。

 

然后祭出我们的度娘大法,找到了http://bbs.csdn.net/topics/391882411 

这个帖子,帖子里已经说的很清楚了。

 

根本原因:

根据帖子描述,rtc注册到alarmtimer_rtc_add_device这一步时有两个判断条件:

static int alarmtimer_rtc_add_device(struct device *dev,
struct class_interface *class_intf)
{
unsigned long flags;
struct rtc_device *rtc = to_rtc_device(dev);
 
if (rtcdev)
return -EBUSY;
 
if (!rtc->ops->set_alarm)
return -1;
if (!device_may_wakeup(rtc->dev.parent))
return -1;
 
spin_lock_irqsave(&rtcdev_lock, flags);
if (!rtcdev) {
rtcdev = rtc;
/* hold a reference so it doesn't go away */
get_device(dev);
}
spin_unlock_irqrestore(&rtcdev_lock, flags);
return 0;
}


首先,pcf8563驱动中没有实现set_alarm,所以此处直接返回。

其次,实现了set_alarm后,第二条仍然不能通过。

所以,rtc设备并没有赋值给rtcdev,设置时间时当然也就获取不到了。

 

解决办法:

1、实现set_alarm函数,此项目并不需要alarm功能,随便写个空函数即可。

2、在pcf8563_probe中添加device_init_wakeup(&client->dev, true);

device_init_wakeup是设置该设备能不能唤醒设备,我们这里设为true。

 

 

总结:

没想到小小的RTC也几经波折,内核修炼之路任重道远...

你可能感兴趣的:(Rockchip)