1 /*
2 * programmable interrupt timer
3 */
4
5 #include "u.h"
6 #include "../port/lib.h"
7 #include "mem.h"
8 #include "dat.h"
9 #include "fns.h"
10 #include "io.h"
11 #include "ureg.h"
12
13 enum {
14 /* piscr */
15 PTE = 1<<0,
16 PITF = 1<<1,
17 PIE = 1<<2,
18 PS = 1<<7,
19 };
20
21 static void
pitinterrupt(Ureg *,void *)22 pitinterrupt(Ureg*, void*)
23 {
24 IMM *io;
25
26 io = m->iomem;
27 if(io->piscr & PS){
28 io->piscr |= PS; /* clear by writing 1 */
29 /* do whatever is required */
30 }
31 }
32
33 static void
pitreset(void)34 pitreset(void)
35 {
36 IMM *io;
37
38 io = ioplock();
39 io->piscrk = KEEP_ALIVE_KEY;
40 io->piscr = (PITlevel<<8) | PS | PITF;
41 if(0)
42 io->piscrk = ~KEEP_ALIVE_KEY;
43 /* piscrk is left unlocked for interrupt routine */
44 iopunlock();
45 intrenable(PITlevel, pitinterrupt, nil, BUSUNKNOWN, "pit");
46 }
47
48 static ulong
pitload(ulong usec)49 pitload(ulong usec)
50 {
51 IMM *io;
52 ulong v;
53
54 v = ((usec*m->oscclk)/512);
55 if(v == 0 || v >= (1<<16))
56 return 0; /* can't do */
57 io = ioplock();
58 io->pitck = KEEP_ALIVE_KEY;
59 io->pitc = (v-1)<<16;
60 io->pitck = ~KEEP_ALIVE_KEY;
61 io->piscrk = KEEP_ALIVE_KEY;
62 io->piscr = (PITlevel<<8) | PS | PIE | PITF | PTE;
63 if(0)
64 io->piscrk = ~KEEP_ALIVE_KEY;
65 /* piscrk is left unlocked for interrupt routine */
66 iopunlock();
67 return (v*512)/m->oscclk;
68 }
69