This source file includes following definitions.
- it_match
- it_attach
- it_readreg
- it_writereg
- it_setup_volt
- it_setup_temp
- it_setup_fan
- it_generic_stemp
- it_generic_svolt
- it_generic_fanrpm
- it_refresh_sensor_data
- it_refresh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/device.h>
31 #include <sys/kernel.h>
32 #include <sys/sensors.h>
33 #include <machine/bus.h>
34
35 #include <dev/isa/isareg.h>
36 #include <dev/isa/isavar.h>
37
38 #include <dev/isa/itvar.h>
39
40 #if defined(ITDEBUG)
41 #define DPRINTF(x) do { printf x; } while (0)
42 #else
43 #define DPRINTF(x)
44 #endif
45
46
47
48
49
50
51
52
53 #define RFACT_NONE 10000
54 #define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y))
55
56 int it_match(struct device *, void *, void *);
57 void it_attach(struct device *, struct device *, void *);
58 u_int8_t it_readreg(struct it_softc *, int);
59 void it_writereg(struct it_softc *, int, int);
60 void it_setup_volt(struct it_softc *, int, int);
61 void it_setup_temp(struct it_softc *, int, int);
62 void it_setup_fan(struct it_softc *, int, int);
63
64 void it_generic_stemp(struct it_softc *, struct ksensor *);
65 void it_generic_svolt(struct it_softc *, struct ksensor *);
66 void it_generic_fanrpm(struct it_softc *, struct ksensor *);
67
68 void it_refresh_sensor_data(struct it_softc *);
69 void it_refresh(void *);
70
71 struct cfattach it_ca = {
72 sizeof(struct it_softc),
73 it_match,
74 it_attach
75 };
76
77 struct cfdriver it_cd = {
78 NULL, "it", DV_DULL
79 };
80
81 const int it_vrfact[] = {
82 RFACT_NONE,
83 RFACT_NONE,
84 RFACT_NONE,
85 RFACT(68, 100),
86 RFACT(30, 10),
87 RFACT(21, 10),
88 RFACT(83, 20),
89 RFACT(68, 100),
90 RFACT_NONE
91 };
92
93 int
94 it_match(struct device *parent, void *match, void *aux)
95 {
96 bus_space_tag_t iot;
97 bus_space_handle_t ioh;
98 struct isa_attach_args *ia = aux;
99 int iobase;
100 u_int8_t cr;
101
102 iot = ia->ia_iot;
103 iobase = ia->ipa_io[0].base;
104
105 if (bus_space_map(iot, iobase, 8, 0, &ioh)) {
106 DPRINTF(("it: can't map i/o space\n"));
107 return (0);
108 }
109
110
111 bus_space_write_1(iot, ioh, ITC_ADDR, ITD_CHIPID);
112 cr = bus_space_read_1(iot, ioh, ITC_DATA);
113 bus_space_unmap(iot, ioh, 8);
114 DPRINTF(("it: vendor id 0x%x\n", cr));
115 if (cr != IT_ID_IT87)
116 return (0);
117
118 ia->ipa_nio = 1;
119 ia->ipa_io[0].length = 8;
120 ia->ipa_nmem = 0;
121 ia->ipa_nirq = 0;
122 ia->ipa_ndrq = 0;
123
124 return (1);
125 }
126
127 void
128 it_attach(struct device *parent, struct device *self, void *aux)
129 {
130 struct it_softc *sc = (void *)self;
131 int iobase;
132 bus_space_tag_t iot;
133 struct isa_attach_args *ia = aux;
134 int i;
135 u_int8_t cr;
136
137 iobase = ia->ipa_io[0].base;
138 iot = sc->it_iot = ia->ia_iot;
139
140 if (bus_space_map(iot, iobase, 8, 0, &sc->it_ioh)) {
141 printf(": can't map i/o space\n");
142 return;
143 }
144
145 i = it_readreg(sc, ITD_CHIPID);
146 switch (i) {
147 case IT_ID_IT87:
148 printf(": IT87\n");
149 break;
150 }
151
152 sc->numsensors = IT_NUM_SENSORS;
153
154 it_setup_fan(sc, 0, 3);
155 it_setup_volt(sc, 3, 9);
156 it_setup_temp(sc, 12, 3);
157
158 if (sensor_task_register(sc, it_refresh, 5) == NULL) {
159 printf("%s: unable to register update task\n",
160 sc->sc_dev.dv_xname);
161 return;
162 }
163
164
165 cr = it_readreg(sc, ITD_CONFIG);
166 cr |= 0x01 | 0x08;
167 it_writereg(sc, ITD_CONFIG, cr);
168
169
170 strlcpy(sc->sensordev.xname, sc->sc_dev.dv_xname,
171 sizeof(sc->sensordev.xname));
172 for (i = 0; i < sc->numsensors; ++i)
173 sensor_attach(&sc->sensordev, &sc->sensors[i]);
174 sensordev_install(&sc->sensordev);
175 }
176
177 u_int8_t
178 it_readreg(struct it_softc *sc, int reg)
179 {
180 bus_space_write_1(sc->it_iot, sc->it_ioh, ITC_ADDR, reg);
181 return (bus_space_read_1(sc->it_iot, sc->it_ioh, ITC_DATA));
182 }
183
184 void
185 it_writereg(struct it_softc *sc, int reg, int val)
186 {
187 bus_space_write_1(sc->it_iot, sc->it_ioh, ITC_ADDR, reg);
188 bus_space_write_1(sc->it_iot, sc->it_ioh, ITC_DATA, val);
189 }
190
191 void
192 it_setup_volt(struct it_softc *sc, int start, int n)
193 {
194 int i;
195
196 for (i = 0; i < n; ++i) {
197 sc->sensors[start + i].type = SENSOR_VOLTS_DC;
198 }
199
200 snprintf(sc->sensors[start + 0].desc, sizeof(sc->sensors[0].desc),
201 "VCORE_A");
202 snprintf(sc->sensors[start + 1].desc, sizeof(sc->sensors[1].desc),
203 "VCORE_B");
204 snprintf(sc->sensors[start + 2].desc, sizeof(sc->sensors[2].desc),
205 "+3.3V");
206 snprintf(sc->sensors[start + 3].desc, sizeof(sc->sensors[3].desc),
207 "+5V");
208 snprintf(sc->sensors[start + 4].desc, sizeof(sc->sensors[4].desc),
209 "+12V");
210 snprintf(sc->sensors[start + 5].desc, sizeof(sc->sensors[5].desc),
211 "Unused");
212 snprintf(sc->sensors[start + 6].desc, sizeof(sc->sensors[6].desc),
213 "-12V");
214 snprintf(sc->sensors[start + 7].desc, sizeof(sc->sensors[7].desc),
215 "+5VSB");
216 snprintf(sc->sensors[start + 8].desc, sizeof(sc->sensors[8].desc),
217 "VBAT");
218 }
219
220 void
221 it_setup_temp(struct it_softc *sc, int start, int n)
222 {
223 int i;
224
225 for (i = 0; i < n; ++i)
226 sc->sensors[start + i].type = SENSOR_TEMP;
227 }
228
229 void
230 it_setup_fan(struct it_softc *sc, int start, int n)
231 {
232 int i;
233
234 for (i = 0; i < n; ++i)
235 sc->sensors[start + i].type = SENSOR_FANRPM;
236 }
237
238 void
239 it_generic_stemp(struct it_softc *sc, struct ksensor *sensors)
240 {
241 int i, sdata;
242
243 for (i = 0; i < 3; i++) {
244 sdata = it_readreg(sc, ITD_SENSORTEMPBASE + i);
245
246 sensors[i].value = sdata * 1000000 + 273150000;
247 }
248 }
249
250 void
251 it_generic_svolt(struct it_softc *sc, struct ksensor *sensors)
252 {
253 int i, sdata;
254
255 for (i = 0; i < 9; i++) {
256 sdata = it_readreg(sc, ITD_SENSORVOLTBASE + i);
257 DPRINTF(("sdata[volt%d] 0x%x\n", i, sdata));
258
259 sensors[i].value = (sdata << 4);
260
261 if (i == 5 || i == 6)
262 sensors[i].value = ((sdata << 4) - IT_VREF);
263
264 sensors[i].value *= it_vrfact[i];
265
266 sensors[i].value /= 10;
267 if (i == 5 || i == 6)
268 sensors[i].value += IT_VREF * 1000;
269 }
270 }
271
272 void
273 it_generic_fanrpm(struct it_softc *sc, struct ksensor *sensors)
274 {
275 int i, sdata, divisor, odivisor, ndivisor;
276
277 odivisor = ndivisor = divisor = it_readreg(sc, ITD_FAN);
278 for (i = 0; i < 3; i++, divisor >>= 3) {
279 sensors[i].flags &= ~SENSOR_FINVALID;
280 if ((sdata = it_readreg(sc, ITD_SENSORFANBASE + i)) == 0xff) {
281 sensors[i].flags |= SENSOR_FINVALID;
282 if (i == 2)
283 ndivisor ^= 0x40;
284 else {
285 ndivisor &= ~(7 << (i * 3));
286 ndivisor |= ((divisor + 1) & 7) << (i * 3);
287 }
288 } else if (sdata == 0) {
289 sensors[i].value = 0;
290 } else {
291 if (i == 2)
292 divisor = divisor & 1 ? 3 : 1;
293 sensors[i].value = 1350000 / (sdata << (divisor & 7));
294 }
295 }
296 if (ndivisor != odivisor)
297 it_writereg(sc, ITD_FAN, ndivisor);
298 }
299
300
301
302
303
304 void
305 it_refresh_sensor_data(struct it_softc *sc)
306 {
307
308 it_generic_stemp(sc, &sc->sensors[12]);
309 it_generic_svolt(sc, &sc->sensors[3]);
310 it_generic_fanrpm(sc, &sc->sensors[0]);
311 }
312
313 void
314 it_refresh(void *arg)
315 {
316 struct it_softc *sc = (struct it_softc *)arg;
317
318 it_refresh_sensor_data(sc);
319 }