1 #include <lunaix/fs/twifs.h>
2 #include <lunaix/fs/twimap.h>
3 #include <lunaix/mm/valloc.h>
4 #include <lunaix/status.h>
5 #include <lunaix/syslog.h>
9 const struct hwrtc_potens* sysrtc = NULL;
11 static DEFINE_LLIST(rtcs);
16 hwrtc_walltime(datetime_t* dt)
18 sysrtc->ops->get_walltime(sysrtc, dt);
21 static inline struct hwrtc_potens*
22 __rtc_potens(struct device* wrapper)
24 struct potens_meta* pot;
25 pot = device_get_potens(wrapper, potens(HWRTC));
26 return ({ assert(pot); get_potens(pot, struct hwrtc_potens); });
30 __hwrtc_ioctl(struct device* dev, u32_t req, va_list args)
32 struct hwrtc_potens* pot;
33 struct hwrtc_potens_ops* ops;
34 struct device* rtcdev;
36 rtcdev = (struct device*) dev->underlay;
37 pot = __rtc_potens(rtcdev);
42 ops->set_proactive(pot, false);
45 ops->set_proactive(pot, true);
48 datetime_t* dt = va_arg(args, datetime_t*);
49 ops->set_walltime(pot, dt);
52 ticks_t* freq = va_arg(args, ticks_t*);
58 return ops->chfreq(pot, *freq);
61 *freq = pot->base_freq;
65 return rtcdev->ops.exec_cmd(dev, req, args);
72 __hwrtc_read(struct device* dev, void* buf, size_t offset, size_t len)
74 struct hwrtc_potens* pot;
76 pot = __rtc_potens((struct device*)dev->underlay);
77 *((ticks_t*)buf) = pot->live;
79 return sizeof(ticks_t);
82 static struct devclass proxy_rtc_clas = DEVCLASS(LUNAIX, TIME, RTC);
85 __hwrtc_create_proxy(struct hwrtc_potens* pot, struct device* raw_rtcdev)
89 dev = device_allocsys(NULL, raw_rtcdev);
91 dev->ops.exec_cmd = __hwrtc_ioctl;
92 dev->ops.read = __hwrtc_read;
94 register_device_var(dev, &proxy_rtc_clas, "rtc");
100 hwrtc_attach_potens(struct device* raw_rtcdev, struct hwrtc_potens_ops* ops)
102 struct hwrtc_potens* hwpot;
104 if (!potens_check_unique(raw_rtcdev, potens(HWRTC)))
109 hwpot = new_potens(potens(HWRTC), struct hwrtc_potens);
112 device_grant_potens(raw_rtcdev, potens_meta(hwpot));
113 llist_append(&rtcs, &hwpot->rtc_potentes);
115 __hwrtc_create_proxy(hwpot, raw_rtcdev);
123 assert(!llist_empty(&rtcs));
125 sysrtc = list_entry(rtcs.next, struct hwrtc_potens, rtc_potentes);
127 if (!sysrtc->ops->calibrate) {
131 int err = sysrtc->ops->calibrate(sysrtc);
133 FATAL("failed to calibrate rtc. name='%s', err=%d",
134 potens_dev(sysrtc)->name_val, err);
139 __hwrtc_readinfo(struct twimap* mapping)
141 struct hwrtc_potens* pot;
142 struct device* owner;
144 pot = twimap_data(mapping, struct hwrtc_potens*);
145 owner = pot->pot_meta.owner;
147 twimap_printf(mapping, "device: %x.%x\n",
148 owner->ident.fn_grp, owner->ident.unique);
150 twimap_printf(mapping, "frequency: %dHz\n", pot->base_freq);
151 twimap_printf(mapping, "ticks count: %d\n", pot->live);
152 twimap_printf(mapping, "ticking: %s\n",
153 (pot->state & RTC_STATE_MASKED) ? "no" : "yes");
156 pot->ops->get_walltime(pot, &dt);
159 mapping, "recorded date: %d/%d/%d\n", dt.year, dt.month, dt.day);
161 mapping, "recorded time: %d:%d:%d\n", dt.hour, dt.minute, dt.second);
162 twimap_printf(mapping, "recorded weekday: %d\n", dt.weekday);
166 hwrtc_twifs_export(struct hwrtc_potens* pot)
168 const char* name = pot->rtc_proxy->name_val;
169 struct twimap* rtc_mapping = twifs_mapping(NULL, pot, name);
170 rtc_mapping->read = __hwrtc_readinfo;
174 hwrtc_twifs_export_all()
176 struct hwrtc_potens *pos, *next;
177 llist_for_each(pos, next, &rtcs, rtc_potentes)
179 hwrtc_twifs_export(pos);
182 EXPORT_TWIFS_PLUGIN(rtc_fsexport, hwrtc_twifs_export_all);