This source file includes following definitions.
- aps_match
- aps_attach
- aps_init
- aps_mem_read_1
- aps_read_data
- aps_refresh_sensor_data
- aps_refresh
- aps_power
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/device.h>
26 #include <sys/kernel.h>
27 #include <sys/sensors.h>
28 #include <sys/timeout.h>
29 #include <machine/bus.h>
30
31 #include <dev/isa/isareg.h>
32 #include <dev/isa/isavar.h>
33
34 #if defined(APSDEBUG)
35 #define DPRINTF(x) do { printf x; } while (0)
36 #else
37 #define DPRINTF(x)
38 #endif
39
40 #define APS_ACCEL_STATE 0x04
41 #define APS_INIT 0x10
42 #define APS_STATE 0x11
43 #define APS_XACCEL 0x12
44 #define APS_YACCEL 0x14
45 #define APS_TEMP 0x16
46 #define APS_XVAR 0x17
47 #define APS_YVAR 0x19
48 #define APS_TEMP2 0x1b
49 #define APS_UNKNOWN 0x1c
50 #define APS_INPUT 0x1d
51 #define APS_CMD 0x1f
52
53 #define APS_STATE_NEWDATA 0x50
54
55 #define APS_CMD_START 0x01
56
57 #define APS_INPUT_KB (1 << 5)
58 #define APS_INPUT_MS (1 << 6)
59 #define APS_INPUT_LIDOPEN (1 << 7)
60
61 #define APS_ADDR_SIZE 0x1f
62
63 struct sensor_rec {
64 u_int8_t state;
65 u_int16_t x_accel;
66 u_int16_t y_accel;
67 u_int8_t temp1;
68 u_int16_t x_var;
69 u_int16_t y_var;
70 u_int8_t temp2;
71 u_int8_t unk;
72 u_int8_t input;
73 };
74
75 #define APS_NUM_SENSORS 9
76
77 #define APS_SENSOR_XACCEL 0
78 #define APS_SENSOR_YACCEL 1
79 #define APS_SENSOR_XVAR 2
80 #define APS_SENSOR_YVAR 3
81 #define APS_SENSOR_TEMP1 4
82 #define APS_SENSOR_TEMP2 5
83 #define APS_SENSOR_KBACT 6
84 #define APS_SENSOR_MSACT 7
85 #define APS_SENSOR_LIDOPEN 8
86
87 struct aps_softc {
88 struct device sc_dev;
89
90 bus_space_tag_t aps_iot;
91 bus_space_handle_t aps_ioh;
92
93 struct ksensor sensors[APS_NUM_SENSORS];
94 struct ksensordev sensordev;
95 void (*refresh_sensor_data)(struct aps_softc *);
96
97 struct sensor_rec aps_data;
98 };
99
100 int aps_match(struct device *, void *, void *);
101 void aps_attach(struct device *, struct device *, void *);
102
103 int aps_init(bus_space_tag_t, bus_space_handle_t);
104 u_int8_t aps_mem_read_1(bus_space_tag_t, bus_space_handle_t, int, u_int8_t);
105 int aps_read_data(struct aps_softc *);
106 void aps_refresh_sensor_data(struct aps_softc *sc);
107 void aps_refresh(void *);
108 void aps_power(int, void *);
109
110 struct cfattach aps_ca = {
111 sizeof(struct aps_softc),
112 aps_match,
113 aps_attach
114 };
115
116 struct cfdriver aps_cd = {
117 NULL, "aps", DV_DULL
118 };
119
120 struct timeout aps_timeout;
121
122 int
123 aps_match(struct device *parent, void *match, void *aux)
124 {
125 bus_space_tag_t iot;
126 bus_space_handle_t ioh;
127 struct isa_attach_args *ia = aux;
128 int iobase, i;
129 u_int8_t cr;
130
131 iot = ia->ia_iot;
132 iobase = ia->ipa_io[0].base;
133
134 if (bus_space_map(iot, iobase, APS_ADDR_SIZE, 0, &ioh)) {
135 DPRINTF(("aps: can't map i/o space\n"));
136 return (0);
137 }
138
139
140 bus_space_write_1(iot, ioh, APS_INIT, 0x13);
141 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
142
143
144 bus_space_read_1(iot, ioh, APS_CMD);
145 bus_space_write_1(iot, ioh, APS_INIT, 0x13);
146 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
147
148 if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00)) {
149 bus_space_unmap(iot, ioh, APS_ADDR_SIZE);
150 return (0);
151 }
152
153
154
155
156
157
158
159 for (i = 0; i < 10; i++) {
160 cr = bus_space_read_1(iot, ioh, APS_STATE);
161 if (cr > 0 && cr < 6)
162 break;
163 delay(5 * 1000);
164 }
165
166 bus_space_unmap(iot, ioh, APS_ADDR_SIZE);
167 DPRINTF(("aps: state register 0x%x\n", cr));
168 if (cr < 1 || cr > 5) {
169 DPRINTF(("aps0: unsupported state %d\n", cr));
170 return (0);
171 }
172
173 ia->ipa_nio = 1;
174 ia->ipa_io[0].length = APS_ADDR_SIZE;
175 ia->ipa_nmem = 0;
176 ia->ipa_nirq = 0;
177 ia->ipa_ndrq = 0;
178
179 return (1);
180 }
181
182 void
183 aps_attach(struct device *parent, struct device *self, void *aux)
184 {
185 struct aps_softc *sc = (void *)self;
186 int iobase, i;
187 bus_space_tag_t iot;
188 bus_space_handle_t ioh;
189 struct isa_attach_args *ia = aux;
190
191 iobase = ia->ipa_io[0].base;
192 iot = sc->aps_iot = ia->ia_iot;
193
194 if (bus_space_map(iot, iobase, APS_ADDR_SIZE, 0, &sc->aps_ioh)) {
195 printf(": can't map i/o space\n");
196 return;
197 }
198
199 ioh = sc->aps_ioh;
200
201 printf("\n");
202
203 if (!aps_init(iot, ioh))
204 goto out;
205
206 sc->sensors[APS_SENSOR_XACCEL].type = SENSOR_INTEGER;
207 snprintf(sc->sensors[APS_SENSOR_XACCEL].desc,
208 sizeof(sc->sensors[APS_SENSOR_XACCEL].desc), "X_ACCEL");
209
210 sc->sensors[APS_SENSOR_YACCEL].type = SENSOR_INTEGER;
211 snprintf(sc->sensors[APS_SENSOR_YACCEL].desc,
212 sizeof(sc->sensors[APS_SENSOR_YACCEL].desc), "Y_ACCEL");
213
214 sc->sensors[APS_SENSOR_TEMP1].type = SENSOR_TEMP;
215 sc->sensors[APS_SENSOR_TEMP2].type = SENSOR_TEMP;
216
217 sc->sensors[APS_SENSOR_XVAR].type = SENSOR_INTEGER;
218 snprintf(sc->sensors[APS_SENSOR_XVAR].desc,
219 sizeof(sc->sensors[APS_SENSOR_XVAR].desc), "X_VAR");
220
221 sc->sensors[APS_SENSOR_YVAR].type = SENSOR_INTEGER;
222 snprintf(sc->sensors[APS_SENSOR_YVAR].desc,
223 sizeof(sc->sensors[APS_SENSOR_YVAR].desc), "Y_VAR");
224
225 sc->sensors[APS_SENSOR_KBACT].type = SENSOR_INDICATOR;
226 snprintf(sc->sensors[APS_SENSOR_KBACT].desc,
227 sizeof(sc->sensors[APS_SENSOR_KBACT].desc), "Keyboard Active");
228
229 sc->sensors[APS_SENSOR_MSACT].type = SENSOR_INDICATOR;
230 snprintf(sc->sensors[APS_SENSOR_MSACT].desc,
231 sizeof(sc->sensors[APS_SENSOR_MSACT].desc), "Mouse Active");
232
233 sc->sensors[APS_SENSOR_LIDOPEN].type = SENSOR_INDICATOR;
234 snprintf(sc->sensors[APS_SENSOR_LIDOPEN].desc,
235 sizeof(sc->sensors[APS_SENSOR_LIDOPEN].desc), "Lid Open");
236
237
238 strlcpy(sc->sensordev.xname, sc->sc_dev.dv_xname,
239 sizeof(sc->sensordev.xname));
240 for (i = 0; i < APS_NUM_SENSORS ; i++) {
241 sensor_attach(&sc->sensordev, &sc->sensors[i]);
242 }
243 sensordev_install(&sc->sensordev);
244
245 powerhook_establish(aps_power, (void *)sc);
246
247
248 timeout_set(&aps_timeout, aps_refresh, sc);
249 timeout_add(&aps_timeout, (5 * hz) / 10);
250 return;
251 out:
252 printf("%s: failed to initialise\n", sc->sc_dev.dv_xname);
253 return;
254 }
255
256 int
257 aps_init(bus_space_tag_t iot, bus_space_handle_t ioh)
258 {
259 bus_space_write_1(iot, ioh, APS_INIT, 0x17);
260 bus_space_write_1(iot, ioh, APS_STATE, 0x81);
261 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
262 if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00))
263 return (0);
264 if (!aps_mem_read_1(iot, ioh, APS_STATE, 0x00))
265 return (0);
266 if (!aps_mem_read_1(iot, ioh, APS_XACCEL, 0x60))
267 return (0);
268 if (!aps_mem_read_1(iot, ioh, APS_XACCEL + 1, 0x00))
269 return (0);
270 bus_space_write_1(iot, ioh, APS_INIT, 0x14);
271 bus_space_write_1(iot, ioh, APS_STATE, 0x01);
272 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
273 if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00))
274 return (0);
275 bus_space_write_1(iot, ioh, APS_INIT, 0x10);
276 bus_space_write_1(iot, ioh, APS_STATE, 0xc8);
277 bus_space_write_1(iot, ioh, APS_XACCEL, 0x00);
278 bus_space_write_1(iot, ioh, APS_XACCEL + 1, 0x02);
279 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
280 if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00))
281 return (0);
282
283 bus_space_write_1(iot, ioh, APS_INIT, 0x11);
284 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
285 if (!aps_mem_read_1(iot, ioh, APS_ACCEL_STATE, 0x50))
286 return (0);
287 if (!aps_mem_read_1(iot, ioh, APS_STATE, 0x00))
288 return (0);
289
290 return (1);
291 }
292
293 u_int8_t
294 aps_mem_read_1(bus_space_tag_t iot, bus_space_handle_t ioh, int reg,
295 u_int8_t val)
296 {
297 int i;
298 u_int8_t cr;
299
300 for (i = 0; i < 10; i++) {
301 cr = bus_space_read_1(iot, ioh, reg);
302 if (cr == val)
303 return (1);
304 delay(5 * 1000);
305 }
306 DPRINTF(("aps: reg 0x%x not val 0x%x!\n", reg, val));
307 return (0);
308 }
309
310 int
311 aps_read_data(struct aps_softc *sc)
312 {
313 bus_space_tag_t iot = sc->aps_iot;
314 bus_space_handle_t ioh = sc->aps_ioh;
315
316 sc->aps_data.state = bus_space_read_1(iot, ioh, APS_STATE);
317 sc->aps_data.x_accel = bus_space_read_2(iot, ioh, APS_XACCEL);
318 sc->aps_data.y_accel = bus_space_read_2(iot, ioh, APS_YACCEL);
319 sc->aps_data.temp1 = bus_space_read_1(iot, ioh, APS_TEMP);
320 sc->aps_data.x_var = bus_space_read_2(iot, ioh, APS_XVAR);
321 sc->aps_data.y_var = bus_space_read_2(iot, ioh, APS_YVAR);
322 sc->aps_data.temp2 = bus_space_read_1(iot, ioh, APS_TEMP2);
323 sc->aps_data.input = bus_space_read_1(iot, ioh, APS_INPUT);
324
325 return (1);
326 }
327
328 void
329 aps_refresh_sensor_data(struct aps_softc *sc)
330 {
331 bus_space_tag_t iot = sc->aps_iot;
332 bus_space_handle_t ioh = sc->aps_ioh;
333 int64_t temp;
334 int i;
335
336
337 bus_space_write_1(iot, ioh, APS_INIT, 0x11);
338 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
339 if (!aps_mem_read_1(iot, ioh, APS_ACCEL_STATE, 0x50))
340 return;
341 aps_read_data(sc);
342 bus_space_write_1(iot, ioh, APS_INIT, 0x11);
343 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
344
345
346 bus_space_read_1(iot, ioh, APS_CMD);
347 bus_space_read_1(iot, ioh, APS_ACCEL_STATE);
348
349 for (i = 0; i < APS_NUM_SENSORS; i++) {
350 sc->sensors[i].flags &= ~SENSOR_FINVALID;
351 }
352
353 sc->sensors[APS_SENSOR_XACCEL].value = sc->aps_data.x_accel;
354 sc->sensors[APS_SENSOR_YACCEL].value = sc->aps_data.y_accel;
355
356
357 temp = sc->aps_data.temp1 * 1000000;
358
359 temp += 273150000;
360 sc->sensors[APS_SENSOR_TEMP1].value = temp;
361
362
363 temp = sc->aps_data.temp2 * 1000000;
364
365 temp += 273150000;
366 sc->sensors[APS_SENSOR_TEMP2].value = temp;
367
368 sc->sensors[APS_SENSOR_XVAR].value = sc->aps_data.x_var;
369 sc->sensors[APS_SENSOR_YVAR].value = sc->aps_data.y_var;
370 sc->sensors[APS_SENSOR_KBACT].value =
371 (sc->aps_data.input & APS_INPUT_KB) ? 1 : 0;
372 sc->sensors[APS_SENSOR_MSACT].value =
373 (sc->aps_data.input & APS_INPUT_MS) ? 1 : 0;
374 sc->sensors[APS_SENSOR_LIDOPEN].value =
375 (sc->aps_data.input & APS_INPUT_LIDOPEN) ? 1 : 0;
376 }
377
378 void
379 aps_refresh(void *arg)
380 {
381 struct aps_softc *sc = (struct aps_softc *)arg;
382
383 aps_refresh_sensor_data(sc);
384 timeout_add(&aps_timeout, (5 * hz) / 10);
385 }
386
387 void
388 aps_power(int why, void *arg)
389 {
390 struct aps_softc *sc = (struct aps_softc *)arg;
391 bus_space_tag_t iot = sc->aps_iot;
392 bus_space_handle_t ioh = sc->aps_ioh;
393
394 if (why != PWR_RESUME) {
395 if (timeout_pending(&aps_timeout))
396 timeout_del(&aps_timeout);
397 } else {
398
399
400
401
402 bus_space_write_1(iot, ioh, APS_INIT, 0x13);
403 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
404 bus_space_read_1(iot, ioh, APS_CMD);
405 bus_space_write_1(iot, ioh, APS_INIT, 0x13);
406 bus_space_write_1(iot, ioh, APS_CMD, 0x01);
407
408 if (aps_mem_read_1(iot, ioh, APS_CMD, 0x00) &&
409 aps_init(iot, ioh))
410 timeout_add(&aps_timeout, (5 * hz) / 10);
411 else
412 printf("aps: failed to wake up\n");
413 }
414 }
415