refactor: make pci device driver loading passive, pci bus scanner will not load them...
[lunaix-os.git] / lunaix-os / hal / rtc / rtc_device.c
1 #include <lunaix/fs/twifs.h>
2 #include <lunaix/fs/twimap.h>
3 #include <lunaix/mm/valloc.h>
4 #include <lunaix/status.h>
5
6 #include <hal/hwrtc.h>
7
8 const struct hwrtc* sysrtc;
9 static int rtc_count = 0;
10
11 DEFINE_LLIST(rtcs);
12
13 void
14 hwrtc_walltime(datetime_t* dt)
15 {
16     sysrtc->get_walltime(sysrtc, dt);
17 }
18
19 static int
20 hwrtc_ioctl(struct device* dev, u32_t req, va_list args)
21 {
22     struct hwrtc* rtc = (struct hwrtc*)dev->underlay;
23     switch (req) {
24         case RTCIO_IMSK:
25             rtc->set_mask(rtc);
26             break;
27         case RTCIO_IUNMSK:
28             rtc->cls_mask(rtc);
29             break;
30         case RTCIO_SETDT:
31             datetime_t* dt = va_arg(args, datetime_t*);
32             rtc->set_walltime(rtc, dt);
33             break;
34         case RTCIO_SETFREQ:
35             ticks_t* freq = va_arg(args, ticks_t*);
36
37             if (!freq) {
38                 return EINVAL;
39             }
40             if (*freq) {
41                 return rtc->chfreq(rtc, *freq);
42             }
43
44             *freq = rtc->base_freq;
45
46             break;
47         default:
48             return EINVAL;
49     }
50
51     return 0;
52 }
53
54 static int
55 hwrtc_read(struct device* dev, void* buf, size_t offset, size_t len)
56 {
57     struct hwrtc* rtc = (struct hwrtc*)dev->underlay;
58     *((ticks_t*)buf) = rtc->get_counts(rtc);
59
60     return sizeof(ticks_t);
61 }
62
63 struct hwrtc*
64 hwrtc_alloc_new(char* name)
65 {
66     struct hwrtc* rtc_instance = valloc(sizeof(struct hwrtc));
67
68     if (!rtc_instance) {
69         return NULL;
70     }
71
72     llist_append(&rtcs, &rtc_instance->rtc_list);
73
74     rtc_instance->id = rtc_count++;
75     rtc_instance->name = name;
76     struct device* rtcdev = device_allocsys(NULL, rtc_instance);
77
78     rtcdev->ops.exec_cmd = hwrtc_ioctl;
79     rtcdev->ops.read = hwrtc_read;
80
81     rtc_instance->rtc_dev = rtcdev;
82
83     return rtc_instance;
84 }
85
86 void
87 hwrtc_register(struct devclass* class, struct hwrtc* rtc)
88 {
89     if (unlikely(!sysrtc)) {
90         sysrtc = rtc;
91     }
92
93     class->variant = rtc->id;
94     device_register(rtc->rtc_dev, class, "rtc%d", rtc->id);
95 }
96
97 static void
98 __hwrtc_readinfo(struct twimap* mapping)
99 {
100     struct hwrtc* rtc = twimap_data(mapping, struct hwrtc*);
101     twimap_printf(mapping, "name: %s\n", rtc->name);
102     twimap_printf(mapping, "frequency: %dHz\n", rtc->base_freq);
103     twimap_printf(mapping, "ticks count: %d\n", rtc->get_counts(rtc));
104     twimap_printf(
105       mapping, "ticking: %s\n", (rtc->state & RTC_STATE_MASKED) ? "no" : "yes");
106
107     datetime_t dt;
108     rtc->get_walltime(rtc, &dt);
109
110     twimap_printf(
111       mapping, "recorded date: %d/%d/%d\n", dt.year, dt.month, dt.day);
112     twimap_printf(
113       mapping, "recorded time: %d:%d:%d\n", dt.hour, dt.minute, dt.second);
114     twimap_printf(mapping, "recorded weekday: %d\n", dt.weekday);
115 }
116
117 static void
118 hwrtc_twifs_export(struct hwrtc* rtc)
119 {
120     const char* name = rtc->rtc_dev->name.value;
121     struct twimap* rtc_mapping = twifs_mapping(NULL, rtc, name);
122     rtc_mapping->read = __hwrtc_readinfo;
123 }
124
125 static void
126 hwrtc_twifs_export_all()
127 {
128     struct hwrtc *pos, *next;
129     llist_for_each(pos, next, &rtcs, rtc_list)
130     {
131         hwrtc_twifs_export(pos);
132     }
133 }
134 EXPORT_TWIFS_PLUGIN(rtc_fsexport, hwrtc_twifs_export_all);