NXP

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

2019-07-12 12:25发布

硬件平台: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也几经波折,内核修炼之路任重道远...