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