1 /*
2 * raspberry pi doesn't have a realtime clock
3 * fake a crude approximation from the kernel build time
4 */
5
6 #include "u.h"
7 #include "../port/lib.h"
8 #include "mem.h"
9 #include "dat.h"
10 #include "fns.h"
11 #include "../port/error.h"
12
13 enum{
14 Qdir = 0,
15 Qrtc,
16 };
17
18 Dirtab rtcdir[]={
19 ".", {Qdir, 0, QTDIR}, 0, 0555,
20 "rtc", {Qrtc, 0}, 0, 0664,
21 };
22
23 extern ulong kerndate;
24
25 static ulong rtcsecs;
26
27 static void
rtctick(void)28 rtctick(void)
29 {
30 rtcsecs++;
31 }
32
33 static void
rtcinit(void)34 rtcinit(void)
35 {
36 rtcsecs = kerndate;
37 addclock0link(rtctick, 1000);
38 }
39
40 static long
rtcread(Chan * c,void * a,long n,vlong offset)41 rtcread(Chan *c, void *a, long n, vlong offset)
42 {
43 if(c->qid.type & QTDIR)
44 return devdirread(c, a, n, rtcdir, nelem(rtcdir), devgen);
45
46 switch((ulong)c->qid.path){
47 case Qrtc:
48 return readnum((ulong)offset, a, n, rtcsecs, 12);
49 }
50 error(Ebadarg);
51 return 0;
52 }
53
54 static long
rtcwrite(Chan * c,void * a,long n,vlong)55 rtcwrite(Chan*c, void *a, long n, vlong)
56 {
57 char b[13];
58 ulong i;
59
60 switch((ulong)c->qid.path){
61 case Qrtc:
62 if(n >= sizeof(b))
63 error(Ebadarg);
64 strncpy(b, (char*)a, n);
65 i = strtol(b, 0, 0);
66 if(i <= 0)
67 error(Ebadarg);
68 rtcsecs = i;
69 return n;
70 }
71 error(Eperm);
72 return 0;
73 }
74
75 static Chan*
rtcattach(char * spec)76 rtcattach(char* spec)
77 {
78 return devattach('r', spec);
79 }
80
81 static Walkqid*
rtcwalk(Chan * c,Chan * nc,char ** name,int nname)82 rtcwalk(Chan* c, Chan *nc, char** name, int nname)
83 {
84 return devwalk(c, nc, name, nname, rtcdir, nelem(rtcdir), devgen);
85 }
86
87 static int
rtcstat(Chan * c,uchar * dp,int n)88 rtcstat(Chan* c, uchar* dp, int n)
89 {
90 return devstat(c, dp, n, rtcdir, nelem(rtcdir), devgen);
91 }
92
93 static Chan*
rtcopen(Chan * c,int omode)94 rtcopen(Chan* c, int omode)
95 {
96 return devopen(c, omode, rtcdir, nelem(rtcdir), devgen);
97 }
98
99 static void
rtcclose(Chan *)100 rtcclose(Chan*)
101 {
102 }
103
104 Dev fakertcdevtab = {
105 'r',
106 "rtc",
107
108 devreset,
109 rtcinit,
110 devshutdown,
111 rtcattach,
112 rtcwalk,
113 rtcstat,
114 rtcopen,
115 devcreate,
116 rtcclose,
117 rtcread,
118 devbread,
119 rtcwrite,
120 devbwrite,
121 devremove,
122 devwstat,
123 };
124
125