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