]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/ec.c
pc, pc64: more conservative pcirouting
[plan9front.git] / sys / src / 9 / pc / ec.c
1 /*
2  * embedded controller (usually at ports 0x66/0x62)
3  */
4 #include        "u.h"
5 #include        "../port/lib.h"
6 #include        "mem.h"
7 #include        "dat.h"
8 #include        "fns.h"
9 #include        "io.h"
10 #include        "../port/error.h"
11
12 enum {
13         /* registers */
14         EC_SC   = 0,
15         EC_DATA,
16
17         /* Embedded Controller Status, EC_SC (R) */
18         OBF     = 1<<0,
19         IBF     = 1<<1,
20         CMD     = 1<<3,
21         BURST   = 1<<4,
22         SCI_EVT = 1<<5,
23         SMI_EVT = 1<<6,
24
25         /* Embedded Controller Command Set */
26         RD_EC   = 0x80,
27         WR_EC   = 0x81,
28         BE_EC   = 0x82,
29         BD_EC   = 0x83,
30         QR_EC   = 0x84,
31 };
32
33 static struct {
34         Lock;
35         int     init;
36         int     port[2];        /* EC_SC and EC_DATA */
37 } ec;
38
39 static uchar
40 ecrr(int reg)
41 {
42         return inb(ec.port[reg]);
43 }
44 static void
45 ecwr(int reg, uchar val)
46 {
47         outb(ec.port[reg], val);
48 }
49
50 static int
51 ecwait(uchar mask, uchar val)
52 {
53         int i, s;
54
55         s = 0;
56         for(i=0; i<1000; i++){
57                 s = ecrr(EC_SC);
58                 if((s & mask) == val)
59                         return 0;
60                 delay(1);
61         }
62         print("ec: wait timeout status=%x pc=%#p\n", s, getcallerpc(&mask));
63         return -1;
64 }
65
66 int
67 ecinit(int cmdport, int dataport)
68 {
69         print("ec: cmd %X, data %X\n", cmdport, dataport);
70
71         if(ioalloc(cmdport, 1, 0, "ec.sc") < 0){
72                 print("ec: cant allocate cmd port %X\n", cmdport);
73                 return -1;
74         }
75         if(ioalloc(dataport, 1, 0, "ec.data") < 0){
76                 print("ec: cant allocate data port %X\n", dataport);
77                 iofree(cmdport);
78                 return -1;
79         }
80
81         lock(&ec);
82         ec.port[EC_SC] = cmdport;
83         ec.port[EC_DATA] = dataport;
84         ec.init = 1;
85         unlock(&ec);
86
87         return 0;
88 }
89
90 int
91 ecread(uchar addr)
92 {
93         int r;
94
95         r = -1;
96         lock(&ec);
97         if(!ec.init)
98                 goto out;
99         if(ecwait(IBF, 0))
100                 goto out;
101         ecwr(EC_SC, RD_EC);
102         if(ecwait(IBF, 0))
103                 goto out;
104         ecwr(EC_DATA, addr);
105         if(ecwait(OBF, OBF))
106                 goto out;
107         r = ecrr(EC_DATA);
108         ecwait(OBF, 0);
109 out:
110         unlock(&ec);
111         return r;
112 }
113
114 int
115 ecwrite(uchar addr, uchar val)
116 {
117         int r;
118
119         r = -1;
120         lock(&ec);
121         if(!ec.init)
122                 goto out;
123         if(ecwait(IBF, 0))
124                 goto out;
125         ecwr(EC_SC, WR_EC);
126         if(ecwait(IBF, 0))
127                 goto out;
128         ecwr(EC_DATA, addr);
129         if(ecwait(IBF, 0))
130                 goto out;
131         ecwr(EC_DATA, val);
132         if(ecwait(IBF, 0))
133                 goto out;
134         r = 0;
135 out:
136         unlock(&ec);
137         return r;
138 }