Bug Summary

File:dev/isa/aps.c
Warning:line 308, column 2
Value stored to 'ioh' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name aps.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/isa/aps.c
1/* $OpenBSD: aps.c,v 1.27 2022/01/09 05:42:42 jsg Exp $ */
2/*
3 * Copyright (c) 2005 Jonathan Gray <jsg@openbsd.org>
4 * Copyright (c) 2008 Can Erkin Acar <canacar@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * A driver for the ThinkPad Active Protection System based on notes from
21 * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html
22 */
23
24#include <sys/param.h>
25#include <sys/systm.h>
26#include <sys/device.h>
27#include <sys/kernel.h>
28#include <sys/sensors.h>
29#include <sys/timeout.h>
30#include <machine/bus.h>
31#include <sys/event.h>
32
33#include <dev/isa/isavar.h>
34
35#ifdef __i386__
36#include "apm.h"
37#include <machine/acpiapm.h>
38#include <machine/biosvar.h>
39#include <machine/apmvar.h>
40#endif
41
42#if defined(APSDEBUG)
43#define DPRINTF(x) do { printf x; } while (0)
44#else
45#define DPRINTF(x)
46#endif
47
48
49/*
50 * EC interface on Thinkpad Laptops, from Linux HDAPS driver notes.
51 * From Renesas H8S/2140B Group Hardware Manual
52 * http://documentation.renesas.com/eng/products/mpumcu/rej09b0300_2140bhm.pdf
53 *
54 * EC uses LPC Channel 3 registers TWR0..15
55 */
56
57/* STR3 status register */
58#define APS_STR30x04 0x04
59
60#define APS_STR3_IBF3B0x80 0x80 /* Input buffer full (host->slave) */
61#define APS_STR3_OBF3B0x40 0x40 /* Output buffer full (slave->host)*/
62#define APS_STR3_MWMF0x20 0x20 /* Master write mode */
63#define APS_STR3_SWMF0x10 0x10 /* Slave write mode */
64
65
66/* Base address of TWR registers */
67#define APS_TWR_BASE0x10 0x10
68#define APS_TWR_RET0x1f 0x1f
69
70/* TWR registers */
71#define APS_CMD0x00 0x00
72#define APS_ARG10x01 0x01
73#define APS_ARG20x02 0x02
74#define APS_ARG30x03 0x03
75#define APS_RET0x0f 0x0f
76
77/* Sensor values */
78#define APS_STATE0x01 0x01
79#define APS_XACCEL0x02 0x02
80#define APS_YACCEL0x04 0x04
81#define APS_TEMP0x06 0x06
82#define APS_XVAR0x07 0x07
83#define APS_YVAR0x09 0x09
84#define APS_TEMP20x0b 0x0b
85#define APS_UNKNOWN0x0c 0x0c
86#define APS_INPUT0x0d 0x0d
87
88/* write masks for I/O, send command + 0-3 arguments*/
89#define APS_WRITE_00x0001 0x0001
90#define APS_WRITE_10x0003 0x0003
91#define APS_WRITE_20x0007 0x0007
92#define APS_WRITE_30x000f 0x000f
93
94/* read masks for I/O, read 0-3 values (skip command byte) */
95#define APS_READ_00x0000 0x0000
96#define APS_READ_10x0002 0x0002
97#define APS_READ_20x0006 0x0006
98#define APS_READ_30x000e 0x000e
99
100#define APS_READ_RET0x8000 0x8000
101#define APS_READ_ALL0xffff 0xffff
102
103/* Bit definitions for APS_INPUT value */
104#define APS_INPUT_KB(1 << 5) (1 << 5)
105#define APS_INPUT_MS(1 << 6) (1 << 6)
106#define APS_INPUT_LIDOPEN(1 << 7) (1 << 7)
107
108#define APS_ADDR_SIZE0x1f 0x1f
109
110struct sensor_rec {
111 u_int8_t state;
112 u_int16_t x_accel;
113 u_int16_t y_accel;
114 u_int8_t temp1;
115 u_int16_t x_var;
116 u_int16_t y_var;
117 u_int8_t temp2;
118 u_int8_t unk;
119 u_int8_t input;
120};
121
122#define APS_NUM_SENSORS9 9
123
124#define APS_SENSOR_XACCEL0 0
125#define APS_SENSOR_YACCEL1 1
126#define APS_SENSOR_XVAR2 2
127#define APS_SENSOR_YVAR3 3
128#define APS_SENSOR_TEMP14 4
129#define APS_SENSOR_TEMP25 5
130#define APS_SENSOR_KBACT6 6
131#define APS_SENSOR_MSACT7 7
132#define APS_SENSOR_LIDOPEN8 8
133
134struct aps_softc {
135 struct device sc_dev;
136
137 bus_space_tag_t aps_iot;
138 bus_space_handle_t aps_ioh;
139
140 struct ksensor sensors[APS_NUM_SENSORS9];
141 struct ksensordev sensordev;
142 void (*refresh_sensor_data)(struct aps_softc *);
143
144 struct sensor_rec aps_data;
145};
146
147int aps_match(struct device *, void *, void *);
148void aps_attach(struct device *, struct device *, void *);
149int aps_activate(struct device *, int);
150
151int aps_init(bus_space_tag_t, bus_space_handle_t);
152int aps_read_data(struct aps_softc *);
153void aps_refresh_sensor_data(struct aps_softc *);
154void aps_refresh(void *);
155int aps_do_io(bus_space_tag_t, bus_space_handle_t,
156 unsigned char *, int, int);
157
158struct cfattach aps_ca = {
159 sizeof(struct aps_softc),
160 aps_match, aps_attach, NULL((void *)0), aps_activate
161};
162
163struct cfdriver aps_cd = {
164 NULL((void *)0), "aps", DV_DULL
165};
166
167struct timeout aps_timeout;
168
169
170
171/* properly communicate with the controller, writing a set of memory
172 * locations and reading back another set */
173int
174aps_do_io(bus_space_tag_t iot, bus_space_handle_t ioh,
175 unsigned char *buf, int wmask, int rmask)
176{
177 int bp, stat, n;
178
179 DPRINTF(("aps_do_io: CMD: 0x%02x, wmask: 0x%04x, rmask: 0x%04x\n",
180 buf[0], wmask, rmask));
181
182 /* write init byte using arbitration */
183 for (n = 0; n < 100; n++) {
184 stat = bus_space_read_1(iot, ioh, APS_STR3)((iot)->read_1((ioh), (0x04)));
185 if (stat & (APS_STR3_OBF3B0x40 | APS_STR3_SWMF0x10)) {
186 bus_space_read_1(iot, ioh, APS_TWR_RET)((iot)->read_1((ioh), (0x1f)));
187 continue;
188 }
189 bus_space_write_1(iot, ioh, APS_TWR_BASE, buf[0])((iot)->write_1((ioh), (0x10), (buf[0])));
190 stat = bus_space_read_1(iot, ioh, APS_STR3)((iot)->read_1((ioh), (0x04)));
191 if (stat & (APS_STR3_MWMF0x20))
192 break;
193 delay(1)(*delay_func)(1);
194 }
195
196 if (n == 100) {
197 DPRINTF(("aps_do_io: Failed to get bus\n"));
198 return (1);
199 }
200
201 /* write data bytes, init already sent */
202 /* make sure last bye is always written as this will trigger slave */
203 wmask |= APS_READ_RET0x8000;
204 buf[APS_RET0x0f] = 0x01;
205
206 for (n = 1, bp = 2; n < 16; bp <<= 1, n++) {
207 if (wmask & bp) {
208 bus_space_write_1(iot, ioh, APS_TWR_BASE + n, buf[n])((iot)->write_1((ioh), (0x10 + n), (buf[n])));
209 DPRINTF(("aps_do_io: write %2d 0x%02x\n", n, buf[n]));
210 }
211 }
212
213 for (n = 0; n < 100; n++) {
214 stat = bus_space_read_1(iot, ioh, APS_STR3)((iot)->read_1((ioh), (0x04)));
215 if (stat & (APS_STR3_OBF3B0x40))
216 break;
217 delay(5 * 100)(*delay_func)(5 * 100);
218 }
219
220 if (n == 100) {
221 DPRINTF(("aps_do_io: timeout waiting response\n"));
222 return (1);
223 }
224 /* wait for data available */
225 /* make sure to read the final byte to clear status */
226 rmask |= APS_READ_RET0x8000;
227
228 /* read cmd and data bytes */
229 for (n = 0, bp = 1; n < 16; bp <<= 1, n++) {
230 if (rmask & bp) {
231 buf[n] = bus_space_read_1(iot, ioh, APS_TWR_BASE + n)((iot)->read_1((ioh), (0x10 + n)));
232 DPRINTF(("aps_do_io: read %2d 0x%02x\n", n, buf[n]));
233 }
234 }
235
236 return (0);
237}
238
239int
240aps_match(struct device *parent, void *match, void *aux)
241{
242 struct isa_attach_args *ia = aux;
243 bus_space_tag_t iot = ia->ia_iot;
244 bus_space_handle_t ioh;
245 int iobase = ia->ipa_io[0].base;
246 u_int8_t cr;
247 unsigned char iobuf[16];
248
249 if (bus_space_map(iot, iobase, APS_ADDR_SIZE0x1f, 0, &ioh)) {
250 DPRINTF(("aps: can't map i/o space\n"));
251 return (0);
252 }
253 /* get APS mode */
254 iobuf[APS_CMD0x00] = 0x13;
255 if (aps_do_io(iot, ioh, iobuf, APS_WRITE_00x0001, APS_READ_10x0002)) {
256 bus_space_unmap(iot, ioh, APS_ADDR_SIZE0x1f);
257 return (0);
258 }
259
260 /*
261 * Observed values from Linux driver:
262 * 0x01: T42
263 * 0x02: chip already initialised
264 * 0x03: T41
265 * 0x05: T61
266 */
267
268 cr = iobuf[APS_ARG10x01];
269 DPRINTF(("aps: state register 0x%x\n", cr));
270
271 if (aps_init(iot, ioh)) {
272 bus_space_unmap(iot, ioh, APS_ADDR_SIZE0x1f);
273 return (0);
274 }
275
276 bus_space_unmap(iot, ioh, APS_ADDR_SIZE0x1f);
277
278 if (iobuf[APS_RET0x0f] != 0 || cr < 1 || cr > 5) {
279 DPRINTF(("aps0: unsupported state %d\n", cr));
280 return (0);
281 }
282
283 ia->ipa_nio = 1;
284 ia->ipa_io[0].length = APS_ADDR_SIZE0x1f;
285 ia->ipa_nmem = 0;
286 ia->ipa_nirq = 0;
287 ia->ipa_ndrq = 0;
288 return (1);
289}
290
291void
292aps_attach(struct device *parent, struct device *self, void *aux)
293{
294 struct aps_softc *sc = (void *)self;
295 int iobase, i;
296 bus_space_tag_t iot;
297 bus_space_handle_t ioh;
298 struct isa_attach_args *ia = aux;
299
300 iobase = ia->ipa_io[0].base;
301 iot = sc->aps_iot = ia->ia_iot;
302
303 if (bus_space_map(iot, iobase, APS_ADDR_SIZE0x1f, 0, &sc->aps_ioh)) {
304 printf(": can't map i/o space\n");
305 return;
306 }
307
308 ioh = sc->aps_ioh;
Value stored to 'ioh' is never read
309
310 printf("\n");
311
312 sc->sensors[APS_SENSOR_XACCEL0].type = SENSOR_INTEGER;
313 snprintf(sc->sensors[APS_SENSOR_XACCEL0].desc,
314 sizeof(sc->sensors[APS_SENSOR_XACCEL0].desc), "X_ACCEL");
315
316 sc->sensors[APS_SENSOR_YACCEL1].type = SENSOR_INTEGER;
317 snprintf(sc->sensors[APS_SENSOR_YACCEL1].desc,
318 sizeof(sc->sensors[APS_SENSOR_YACCEL1].desc), "Y_ACCEL");
319
320 sc->sensors[APS_SENSOR_TEMP14].type = SENSOR_TEMP;
321 sc->sensors[APS_SENSOR_TEMP25].type = SENSOR_TEMP;
322
323 sc->sensors[APS_SENSOR_XVAR2].type = SENSOR_INTEGER;
324 snprintf(sc->sensors[APS_SENSOR_XVAR2].desc,
325 sizeof(sc->sensors[APS_SENSOR_XVAR2].desc), "X_VAR");
326
327 sc->sensors[APS_SENSOR_YVAR3].type = SENSOR_INTEGER;
328 snprintf(sc->sensors[APS_SENSOR_YVAR3].desc,
329 sizeof(sc->sensors[APS_SENSOR_YVAR3].desc), "Y_VAR");
330
331 sc->sensors[APS_SENSOR_KBACT6].type = SENSOR_INDICATOR;
332 snprintf(sc->sensors[APS_SENSOR_KBACT6].desc,
333 sizeof(sc->sensors[APS_SENSOR_KBACT6].desc), "Keyboard Active");
334
335 sc->sensors[APS_SENSOR_MSACT7].type = SENSOR_INDICATOR;
336 snprintf(sc->sensors[APS_SENSOR_MSACT7].desc,
337 sizeof(sc->sensors[APS_SENSOR_MSACT7].desc), "Mouse Active");
338
339 sc->sensors[APS_SENSOR_LIDOPEN8].type = SENSOR_INDICATOR;
340 snprintf(sc->sensors[APS_SENSOR_LIDOPEN8].desc,
341 sizeof(sc->sensors[APS_SENSOR_LIDOPEN8].desc), "Lid Open");
342
343 /* stop hiding and report to the authorities */
344 strlcpy(sc->sensordev.xname, sc->sc_dev.dv_xname,
345 sizeof(sc->sensordev.xname));
346 for (i = 0; i < APS_NUM_SENSORS9 ; i++) {
347 sensor_attach(&sc->sensordev, &sc->sensors[i]);
348 }
349 sensordev_install(&sc->sensordev);
350
351 /* Refresh sensor data every 0.5 seconds */
352 timeout_set(&aps_timeout, aps_refresh, sc);
353 timeout_add_msec(&aps_timeout, 500);
354}
355
356int
357aps_init(bus_space_tag_t iot, bus_space_handle_t ioh)
358{
359 unsigned char iobuf[16];
360
361
362 /* command 0x17/0x81: check EC */
363 iobuf[APS_CMD0x00] = 0x17;
364 iobuf[APS_ARG10x01] = 0x81;
365
366 if (aps_do_io(iot, ioh, iobuf, APS_WRITE_10x0003, APS_READ_30x000e))
367 return (1);
368
369 if (iobuf[APS_RET0x0f] != 0 ||iobuf[APS_ARG30x03] != 0)
370 return (2);
371
372 /* Test values from the Linux driver */
373 if ((iobuf[APS_ARG10x01] != 0 || iobuf[APS_ARG20x02] != 0x60) &&
374 (iobuf[APS_ARG10x01] != 1 || iobuf[APS_ARG20x02] != 0))
375 return (3);
376
377 /* command 0x14: set power */
378 iobuf[APS_CMD0x00] = 0x14;
379 iobuf[APS_ARG10x01] = 0x01;
380
381 if (aps_do_io(iot, ioh, iobuf, APS_WRITE_10x0003, APS_READ_00x0000))
382 return (4);
383
384 if (iobuf[APS_RET0x0f] != 0)
385 return (5);
386
387 /* command 0x10: set config (sample rate and order) */
388 iobuf[APS_CMD0x00] = 0x10;
389 iobuf[APS_ARG10x01] = 0xc8;
390 iobuf[APS_ARG20x02] = 0x00;
391 iobuf[APS_ARG30x03] = 0x02;
392
393 if (aps_do_io(iot, ioh, iobuf, APS_WRITE_30x000f, APS_READ_00x0000))
394 return (6);
395
396 if (iobuf[APS_RET0x0f] != 0)
397 return (7);
398
399 /* command 0x11: refresh data */
400 iobuf[APS_CMD0x00] = 0x11;
401 if (aps_do_io(iot, ioh, iobuf, APS_WRITE_00x0001, APS_READ_10x0002))
402 return (8);
403
404 return (0);
405}
406
407int
408aps_read_data(struct aps_softc *sc)
409{
410 bus_space_tag_t iot = sc->aps_iot;
411 bus_space_handle_t ioh = sc->aps_ioh;
412 unsigned char iobuf[16];
413
414 /* command 0x11: refresh data */
415 iobuf[APS_CMD0x00] = 0x11;
416 if (aps_do_io(iot, ioh, iobuf, APS_WRITE_00x0001, APS_READ_ALL0xffff))
417 return (1);
418
419 sc->aps_data.state = iobuf[APS_STATE0x01];
420 sc->aps_data.x_accel = iobuf[APS_XACCEL0x02] + 256 * iobuf[APS_XACCEL0x02 + 1];
421 sc->aps_data.y_accel = iobuf[APS_YACCEL0x04] + 256 * iobuf[APS_YACCEL0x04 + 1];
422 sc->aps_data.temp1 = iobuf[APS_TEMP0x06];
423 sc->aps_data.x_var = iobuf[APS_XVAR0x07] + 256 * iobuf[APS_XVAR0x07 + 1];
424 sc->aps_data.y_var = iobuf[APS_YVAR0x09] + 256 * iobuf[APS_YVAR0x09 + 1];
425 sc->aps_data.temp2 = iobuf[APS_TEMP20x0b];
426 sc->aps_data.input = iobuf[APS_INPUT0x0d];
427
428 return (0);
429}
430
431void
432aps_refresh_sensor_data(struct aps_softc *sc)
433{
434 int64_t temp;
435 int i;
436#if NAPM > 0
437 extern int lid_action;
438 extern int apm_lidclose;
439#endif
440
441 if (aps_read_data(sc))
442 return;
443
444 for (i = 0; i < APS_NUM_SENSORS9; i++) {
445 sc->sensors[i].flags &= ~SENSOR_FINVALID0x0001;
446 }
447
448 sc->sensors[APS_SENSOR_XACCEL0].value = sc->aps_data.x_accel;
449 sc->sensors[APS_SENSOR_YACCEL1].value = sc->aps_data.y_accel;
450
451 /* convert to micro (mu) degrees */
452 temp = sc->aps_data.temp1 * 1000000;
453 /* convert to kelvin */
454 temp += 273150000;
455 sc->sensors[APS_SENSOR_TEMP14].value = temp;
456
457 /* convert to micro (mu) degrees */
458 temp = sc->aps_data.temp2 * 1000000;
459 /* convert to kelvin */
460 temp += 273150000;
461 sc->sensors[APS_SENSOR_TEMP25].value = temp;
462
463 sc->sensors[APS_SENSOR_XVAR2].value = sc->aps_data.x_var;
464 sc->sensors[APS_SENSOR_YVAR3].value = sc->aps_data.y_var;
465 sc->sensors[APS_SENSOR_KBACT6].value =
466 (sc->aps_data.input & APS_INPUT_KB(1 << 5)) ? 1 : 0;
467 sc->sensors[APS_SENSOR_MSACT7].value =
468 (sc->aps_data.input & APS_INPUT_MS(1 << 6)) ? 1 : 0;
469#if NAPM > 0
470 if (lid_action &&
471 (sc->sensors[APS_SENSOR_LIDOPEN8].value == 1) &&
472 (sc->aps_data.input & APS_INPUT_LIDOPEN(1 << 7)) == 0)
473 /* Inform APM that the lid has closed */
474 apm_lidclose = 1;
475#endif
476 sc->sensors[APS_SENSOR_LIDOPEN8].value =
477 (sc->aps_data.input & APS_INPUT_LIDOPEN(1 << 7)) ? 1 : 0;
478}
479
480void
481aps_refresh(void *arg)
482{
483 struct aps_softc *sc = (struct aps_softc *)arg;
484
485 aps_refresh_sensor_data(sc);
486 timeout_add_msec(&aps_timeout, 500);
487}
488
489int
490aps_activate(struct device *self, int act)
491{
492 struct aps_softc *sc = (struct aps_softc *)self;
493 bus_space_tag_t iot = sc->aps_iot;
494 bus_space_handle_t ioh = sc->aps_ioh;
495 unsigned char iobuf[16];
496
497 /* check if we bombed during attach */
498 if (!timeout_initialized(&aps_timeout)((&aps_timeout)->to_flags & 0x04))
499 return (0);
500
501 switch (act) {
502 case DVACT_SUSPEND3:
503 timeout_del(&aps_timeout);
504 break;
505 case DVACT_RESUME4:
506 /*
507 * Redo the init sequence on resume, because APS is
508 * as forgetful as it is deaf.
509 */
510
511 /* get APS mode */
512 iobuf[APS_CMD0x00] = 0x13;
513 aps_do_io(iot, ioh, iobuf, APS_WRITE_00x0001, APS_READ_10x0002);
514
515 aps_init(iot, ioh);
516 timeout_add_msec(&aps_timeout, 500);
517 break;
518 }
519 return (0);
520}