xref: /DragonOS/kernel/src/driver/rtc/class.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
1da152319SLoGin use alloc::{
2da152319SLoGin     string::ToString,
3da152319SLoGin     sync::{Arc, Weak},
4da152319SLoGin };
5*2eab6dd7S曾俊 use log::info;
6da152319SLoGin use system_error::SystemError;
7da152319SLoGin use unified_init::macros::unified_init;
8da152319SLoGin 
9da152319SLoGin use crate::{
10da152319SLoGin     driver::base::{
11da152319SLoGin         class::{class_manager, Class},
12da152319SLoGin         device::{device_manager, sys_dev_char_kset},
13da152319SLoGin         kobject::KObject,
14da152319SLoGin         subsys::SubSysPrivate,
15da152319SLoGin     },
16da152319SLoGin     init::initcall::INITCALL_SUBSYS,
176fc066acSJomo     time::{timekeeping::do_settimeofday64, PosixTimeSpec},
18da152319SLoGin };
19da152319SLoGin 
20da152319SLoGin use super::{interface::rtc_read_time, register_default_rtc, sysfs::RtcGeneralDevice};
21da152319SLoGin 
22da152319SLoGin /// `/sys/class/rtc` 的 class 实例
23da152319SLoGin static mut CLASS_RTC_INSTANCE: Option<Arc<RtcClass>> = None;
24da152319SLoGin 
25da152319SLoGin /// 获取 `/sys/class/rtc` 的 class 实例
26da152319SLoGin #[inline(always)]
27da152319SLoGin #[allow(dead_code)]
sys_class_rtc_instance() -> Option<&'static Arc<RtcClass>>28da152319SLoGin pub fn sys_class_rtc_instance() -> Option<&'static Arc<RtcClass>> {
29da152319SLoGin     unsafe { CLASS_RTC_INSTANCE.as_ref() }
30da152319SLoGin }
31da152319SLoGin 
32da152319SLoGin /// 初始化帧缓冲区子系统
33da152319SLoGin #[unified_init(INITCALL_SUBSYS)]
fbmem_init() -> Result<(), SystemError>34da152319SLoGin pub fn fbmem_init() -> Result<(), SystemError> {
35da152319SLoGin     let rtc_class = RtcClass::new();
36da152319SLoGin     class_manager().class_register(&(rtc_class.clone() as Arc<dyn Class>))?;
37da152319SLoGin 
38da152319SLoGin     unsafe {
39da152319SLoGin         CLASS_RTC_INSTANCE = Some(rtc_class);
40da152319SLoGin     }
41da152319SLoGin 
42da152319SLoGin     return Ok(());
43da152319SLoGin }
44da152319SLoGin 
45da152319SLoGin /// `/sys/class/rtc` 类
46da152319SLoGin #[derive(Debug)]
47da152319SLoGin pub struct RtcClass {
48da152319SLoGin     subsystem: SubSysPrivate,
49da152319SLoGin }
50da152319SLoGin 
51da152319SLoGin impl RtcClass {
52da152319SLoGin     const NAME: &'static str = "rtc";
new() -> Arc<Self>53da152319SLoGin     pub fn new() -> Arc<Self> {
54da152319SLoGin         let r = Self {
55da152319SLoGin             subsystem: SubSysPrivate::new(Self::NAME.to_string(), None, None, &[]),
56da152319SLoGin         };
57da152319SLoGin         let r = Arc::new(r);
58da152319SLoGin         r.subsystem()
59da152319SLoGin             .set_class(Some(Arc::downgrade(&r) as Weak<dyn Class>));
60da152319SLoGin 
61da152319SLoGin         return r;
62da152319SLoGin     }
63da152319SLoGin }
64da152319SLoGin 
65da152319SLoGin impl Class for RtcClass {
name(&self) -> &'static str66da152319SLoGin     fn name(&self) -> &'static str {
67da152319SLoGin         return Self::NAME;
68da152319SLoGin     }
69da152319SLoGin 
dev_kobj(&self) -> Option<Arc<dyn KObject>>70da152319SLoGin     fn dev_kobj(&self) -> Option<Arc<dyn KObject>> {
71da152319SLoGin         Some(sys_dev_char_kset() as Arc<dyn KObject>)
72da152319SLoGin     }
73da152319SLoGin 
set_dev_kobj(&self, _kobj: Arc<dyn KObject>)74da152319SLoGin     fn set_dev_kobj(&self, _kobj: Arc<dyn KObject>) {
75da152319SLoGin         unimplemented!("RtcClass::set_dev_kobj");
76da152319SLoGin     }
77da152319SLoGin 
subsystem(&self) -> &SubSysPrivate78da152319SLoGin     fn subsystem(&self) -> &SubSysPrivate {
79da152319SLoGin         return &self.subsystem;
80da152319SLoGin     }
81da152319SLoGin }
82da152319SLoGin 
83da152319SLoGin /// 注册rtc通用设备
rtc_register_device(dev: &Arc<RtcGeneralDevice>) -> Result<(), SystemError>84da152319SLoGin pub(super) fn rtc_register_device(dev: &Arc<RtcGeneralDevice>) -> Result<(), SystemError> {
85da152319SLoGin     device_manager().add_device(dev.clone())?;
86da152319SLoGin     register_default_rtc(dev.clone());
87da152319SLoGin     // 把硬件时间同步到系统时间
88da152319SLoGin     rtc_hctosys(dev);
89da152319SLoGin     return Ok(());
90da152319SLoGin }
91da152319SLoGin 
rtc_hctosys(dev: &Arc<RtcGeneralDevice>)92da152319SLoGin fn rtc_hctosys(dev: &Arc<RtcGeneralDevice>) {
93da152319SLoGin     let r = rtc_read_time(dev);
94da152319SLoGin     if let Err(e) = r {
95da152319SLoGin         dev.set_hc2sys_result(Err(e));
96da152319SLoGin         return;
97da152319SLoGin     }
98da152319SLoGin 
99da152319SLoGin     let time = r.unwrap();
1006fc066acSJomo     let timespec64: PosixTimeSpec = time.into();
101da152319SLoGin     let r = do_settimeofday64(timespec64);
102da152319SLoGin     dev.set_hc2sys_result(r);
103da152319SLoGin 
104*2eab6dd7S曾俊     info!(
105da152319SLoGin         "Setting system clock to {} {} UTC ({})",
106da152319SLoGin         time.date_string(),
107da152319SLoGin         time.time_string(),
108da152319SLoGin         timespec64.tv_sec
109da152319SLoGin     );
110da152319SLoGin }
111