xref: /plan9-contrib/sys/src/9/bcm/devfakertc.c (revision 5d9de2d38d2503efca29e12e0e32036368a7a75f)
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