xref: /freebsd/sys/dev/acpi_support/atk0110.c (revision a8cd03934180f9f92e786912ad148560706e0973)
1bbe4a97dSRui Paulo /*	$NetBSD: atk0110.c,v 1.4 2010/02/11 06:54:57 cnst Exp $	*/
2bbe4a97dSRui Paulo /*	$OpenBSD: atk0110.c,v 1.1 2009/07/23 01:38:16 cnst Exp $	*/
3bbe4a97dSRui Paulo 
4bbe4a97dSRui Paulo /*
5bbe4a97dSRui Paulo  * Copyright (c) 2009, 2010 Constantine A. Murenin <cnst++@FreeBSD.org>
6bbe4a97dSRui Paulo  *
7bbe4a97dSRui Paulo  * Permission to use, copy, modify, and distribute this software for any
8bbe4a97dSRui Paulo  * purpose with or without fee is hereby granted, provided that the above
9bbe4a97dSRui Paulo  * copyright notice and this permission notice appear in all copies.
10bbe4a97dSRui Paulo  *
11bbe4a97dSRui Paulo  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12bbe4a97dSRui Paulo  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13bbe4a97dSRui Paulo  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14bbe4a97dSRui Paulo  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15bbe4a97dSRui Paulo  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16bbe4a97dSRui Paulo  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17bbe4a97dSRui Paulo  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18bbe4a97dSRui Paulo  */
19bbe4a97dSRui Paulo 
20bbe4a97dSRui Paulo #include <sys/cdefs.h>
21bbe4a97dSRui Paulo __FBSDID("$FreeBSD$");
22bbe4a97dSRui Paulo 
23bbe4a97dSRui Paulo #include <machine/_inttypes.h>
24bbe4a97dSRui Paulo #include <sys/param.h>
25bbe4a97dSRui Paulo #include <sys/systm.h>
26bbe4a97dSRui Paulo #include <sys/kernel.h>
27bbe4a97dSRui Paulo #include <sys/bus.h>
28bbe4a97dSRui Paulo #include <sys/module.h>
29bbe4a97dSRui Paulo #include <sys/malloc.h>
30bbe4a97dSRui Paulo #include <sys/sysctl.h>
31bbe4a97dSRui Paulo 
32bbe4a97dSRui Paulo #include <contrib/dev/acpica/include/acpi.h>
33bbe4a97dSRui Paulo #include <dev/acpica/acpivar.h>
34bbe4a97dSRui Paulo 
35bbe4a97dSRui Paulo /*
36bbe4a97dSRui Paulo  * ASUSTeK AI Booster (ACPI ASOC ATK0110).
37bbe4a97dSRui Paulo  *
38bbe4a97dSRui Paulo  * This code was originally written for OpenBSD after the techniques
39bbe4a97dSRui Paulo  * described in the Linux's asus_atk0110.c and FreeBSD's Takanori Watanabe's
40bbe4a97dSRui Paulo  * acpi_aiboost.c were verified to be accurate on the actual hardware kindly
41bbe4a97dSRui Paulo  * provided by Sam Fourman Jr.  It was subsequently ported from OpenBSD to
42bbe4a97dSRui Paulo  * DragonFly BSD, to NetBSD's sysmon_envsys(9) and to FreeBSD's sysctl(9).
43bbe4a97dSRui Paulo  *
44bbe4a97dSRui Paulo  *				  -- Constantine A. Murenin <http://cnst.su/>
45bbe4a97dSRui Paulo  */
46bbe4a97dSRui Paulo 
47bbe4a97dSRui Paulo #define _COMPONENT	ACPI_OEM
48bbe4a97dSRui Paulo ACPI_MODULE_NAME("aibs");
49bbe4a97dSRui Paulo ACPI_SERIAL_DECL(aibs, "aibs");
50bbe4a97dSRui Paulo 
51bbe4a97dSRui Paulo #define AIBS_MORE_SENSORS
52bbe4a97dSRui Paulo #define AIBS_VERBOSE
53bbe4a97dSRui Paulo 
54bbe4a97dSRui Paulo enum aibs_type {
55bbe4a97dSRui Paulo 	AIBS_VOLT,
56bbe4a97dSRui Paulo 	AIBS_TEMP,
57bbe4a97dSRui Paulo 	AIBS_FAN
58bbe4a97dSRui Paulo };
59bbe4a97dSRui Paulo 
60bbe4a97dSRui Paulo struct aibs_sensor {
61bbe4a97dSRui Paulo 	ACPI_INTEGER	v;
62bbe4a97dSRui Paulo 	ACPI_INTEGER	i;
63bbe4a97dSRui Paulo 	ACPI_INTEGER	l;
64bbe4a97dSRui Paulo 	ACPI_INTEGER	h;
65bbe4a97dSRui Paulo 	enum aibs_type	t;
66bbe4a97dSRui Paulo };
67bbe4a97dSRui Paulo 
68bbe4a97dSRui Paulo struct aibs_softc {
69*a8cd0393SAdrian Chadd 	device_t		sc_dev;
70bbe4a97dSRui Paulo 	ACPI_HANDLE		sc_ah;
71bbe4a97dSRui Paulo 
72bbe4a97dSRui Paulo 	struct aibs_sensor	*sc_asens_volt;
73bbe4a97dSRui Paulo 	struct aibs_sensor	*sc_asens_temp;
74bbe4a97dSRui Paulo 	struct aibs_sensor	*sc_asens_fan;
75bbe4a97dSRui Paulo };
76bbe4a97dSRui Paulo 
77bbe4a97dSRui Paulo static int aibs_probe(device_t);
78bbe4a97dSRui Paulo static int aibs_attach(device_t);
79bbe4a97dSRui Paulo static int aibs_detach(device_t);
80bbe4a97dSRui Paulo static int aibs_sysctl(SYSCTL_HANDLER_ARGS);
81bbe4a97dSRui Paulo 
82bbe4a97dSRui Paulo static void aibs_attach_sif(struct aibs_softc *, enum aibs_type);
83bbe4a97dSRui Paulo 
84bbe4a97dSRui Paulo static device_method_t aibs_methods[] = {
85bbe4a97dSRui Paulo 	DEVMETHOD(device_probe,		aibs_probe),
86bbe4a97dSRui Paulo 	DEVMETHOD(device_attach,	aibs_attach),
87bbe4a97dSRui Paulo 	DEVMETHOD(device_detach,	aibs_detach),
88bbe4a97dSRui Paulo 	{ NULL, NULL }
89bbe4a97dSRui Paulo };
90bbe4a97dSRui Paulo 
91bbe4a97dSRui Paulo static driver_t aibs_driver = {
92bbe4a97dSRui Paulo 	"aibs",
93bbe4a97dSRui Paulo 	aibs_methods,
94bbe4a97dSRui Paulo 	sizeof(struct aibs_softc)
95bbe4a97dSRui Paulo };
96bbe4a97dSRui Paulo 
97bbe4a97dSRui Paulo static devclass_t aibs_devclass;
98bbe4a97dSRui Paulo 
99bbe4a97dSRui Paulo DRIVER_MODULE(aibs, acpi, aibs_driver, aibs_devclass, NULL, NULL);
100bbdf953eSKevin Lo MODULE_DEPEND(aibs, acpi, 1, 1, 1);
101bbe4a97dSRui Paulo 
102bbe4a97dSRui Paulo static char* aibs_hids[] = {
103bbe4a97dSRui Paulo 	"ATK0110",
104bbe4a97dSRui Paulo 	NULL
105bbe4a97dSRui Paulo };
106bbe4a97dSRui Paulo 
107bbe4a97dSRui Paulo static int
108bbe4a97dSRui Paulo aibs_probe(device_t dev)
109bbe4a97dSRui Paulo {
110bbe4a97dSRui Paulo 	if (acpi_disabled("aibs") ||
111bbe4a97dSRui Paulo 	    ACPI_ID_PROBE(device_get_parent(dev), dev, aibs_hids) == NULL)
112bbe4a97dSRui Paulo 		return ENXIO;
113bbe4a97dSRui Paulo 
114bbe4a97dSRui Paulo 	device_set_desc(dev, "ASUSTeK AI Booster (ACPI ASOC ATK0110)");
115bbe4a97dSRui Paulo 	return 0;
116bbe4a97dSRui Paulo }
117bbe4a97dSRui Paulo 
118bbe4a97dSRui Paulo static int
119bbe4a97dSRui Paulo aibs_attach(device_t dev)
120bbe4a97dSRui Paulo {
121bbe4a97dSRui Paulo 	struct aibs_softc *sc = device_get_softc(dev);
122bbe4a97dSRui Paulo 
123bbe4a97dSRui Paulo 	sc->sc_dev = dev;
124bbe4a97dSRui Paulo 	sc->sc_ah = acpi_get_handle(dev);
125bbe4a97dSRui Paulo 
126bbe4a97dSRui Paulo 	aibs_attach_sif(sc, AIBS_VOLT);
127bbe4a97dSRui Paulo 	aibs_attach_sif(sc, AIBS_TEMP);
128bbe4a97dSRui Paulo 	aibs_attach_sif(sc, AIBS_FAN);
129bbe4a97dSRui Paulo 
130bbe4a97dSRui Paulo 	return 0;
131bbe4a97dSRui Paulo }
132bbe4a97dSRui Paulo 
133bbe4a97dSRui Paulo static void
134bbe4a97dSRui Paulo aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st)
135bbe4a97dSRui Paulo {
136bbe4a97dSRui Paulo 	ACPI_STATUS		s;
137bbe4a97dSRui Paulo 	ACPI_BUFFER		b;
138bbe4a97dSRui Paulo 	ACPI_OBJECT		*bp, *o;
139bbe4a97dSRui Paulo 	int			i, n;
140bbe4a97dSRui Paulo 	const char		*node;
141bbe4a97dSRui Paulo 	char			name[] = "?SIF";
142bbe4a97dSRui Paulo 	struct aibs_sensor	*as;
143bbe4a97dSRui Paulo 	struct sysctl_oid	*so;
144bbe4a97dSRui Paulo 
145bbe4a97dSRui Paulo 	switch (st) {
146bbe4a97dSRui Paulo 	case AIBS_VOLT:
147bbe4a97dSRui Paulo 		node = "volt";
148bbe4a97dSRui Paulo 		name[0] = 'V';
149bbe4a97dSRui Paulo 		break;
150bbe4a97dSRui Paulo 	case AIBS_TEMP:
151bbe4a97dSRui Paulo 		node = "temp";
152bbe4a97dSRui Paulo 		name[0] = 'T';
153bbe4a97dSRui Paulo 		break;
154bbe4a97dSRui Paulo 	case AIBS_FAN:
155bbe4a97dSRui Paulo 		node = "fan";
156bbe4a97dSRui Paulo 		name[0] = 'F';
157bbe4a97dSRui Paulo 		break;
158bbe4a97dSRui Paulo 	default:
159bbe4a97dSRui Paulo 		return;
160bbe4a97dSRui Paulo 	}
161bbe4a97dSRui Paulo 
162bbe4a97dSRui Paulo 	b.Length = ACPI_ALLOCATE_BUFFER;
163bbe4a97dSRui Paulo 	s = AcpiEvaluateObjectTyped(sc->sc_ah, name, NULL, &b,
164bbe4a97dSRui Paulo 	    ACPI_TYPE_PACKAGE);
165bbe4a97dSRui Paulo 	if (ACPI_FAILURE(s)) {
166bbe4a97dSRui Paulo 		device_printf(sc->sc_dev, "%s not found\n", name);
167bbe4a97dSRui Paulo 		return;
168bbe4a97dSRui Paulo 	}
169bbe4a97dSRui Paulo 
170bbe4a97dSRui Paulo 	bp = b.Pointer;
171bbe4a97dSRui Paulo 	o = bp->Package.Elements;
172bbe4a97dSRui Paulo 	if (o[0].Type != ACPI_TYPE_INTEGER) {
173bbe4a97dSRui Paulo 		device_printf(sc->sc_dev, "%s[0]: invalid type\n", name);
174bbe4a97dSRui Paulo 		AcpiOsFree(b.Pointer);
175bbe4a97dSRui Paulo 		return;
176bbe4a97dSRui Paulo 	}
177bbe4a97dSRui Paulo 
178bbe4a97dSRui Paulo 	n = o[0].Integer.Value;
179bbe4a97dSRui Paulo 	if (bp->Package.Count - 1 < n) {
180bbe4a97dSRui Paulo 		device_printf(sc->sc_dev, "%s: invalid package\n", name);
181bbe4a97dSRui Paulo 		AcpiOsFree(b.Pointer);
182bbe4a97dSRui Paulo 		return;
183bbe4a97dSRui Paulo 	} else if (bp->Package.Count - 1 > n) {
184bbe4a97dSRui Paulo 		int on = n;
185bbe4a97dSRui Paulo 
186bbe4a97dSRui Paulo #ifdef AIBS_MORE_SENSORS
187bbe4a97dSRui Paulo 		n = bp->Package.Count - 1;
188bbe4a97dSRui Paulo #endif
189bbe4a97dSRui Paulo 		device_printf(sc->sc_dev, "%s: malformed package: %i/%i"
190bbe4a97dSRui Paulo 		    ", assume %i\n", name, on, bp->Package.Count - 1, n);
191bbe4a97dSRui Paulo 	}
192bbe4a97dSRui Paulo 	if (n < 1) {
193bbe4a97dSRui Paulo 		device_printf(sc->sc_dev, "%s: no members in the package\n",
194bbe4a97dSRui Paulo 		    name);
195bbe4a97dSRui Paulo 		AcpiOsFree(b.Pointer);
196bbe4a97dSRui Paulo 		return;
197bbe4a97dSRui Paulo 	}
198bbe4a97dSRui Paulo 
199bbe4a97dSRui Paulo 	as = malloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO);
200bbe4a97dSRui Paulo 	if (as == NULL) {
201bbe4a97dSRui Paulo 		device_printf(sc->sc_dev, "%s: malloc fail\n", name);
202bbe4a97dSRui Paulo 		AcpiOsFree(b.Pointer);
203bbe4a97dSRui Paulo 		return;
204bbe4a97dSRui Paulo 	}
205bbe4a97dSRui Paulo 	switch (st) {
206bbe4a97dSRui Paulo 	case AIBS_VOLT:
207bbe4a97dSRui Paulo 		sc->sc_asens_volt = as;
208bbe4a97dSRui Paulo 		break;
209bbe4a97dSRui Paulo 	case AIBS_TEMP:
210bbe4a97dSRui Paulo 		sc->sc_asens_temp = as;
211bbe4a97dSRui Paulo 		break;
212bbe4a97dSRui Paulo 	case AIBS_FAN:
213bbe4a97dSRui Paulo 		sc->sc_asens_fan = as;
214bbe4a97dSRui Paulo 		break;
215bbe4a97dSRui Paulo 	}
216bbe4a97dSRui Paulo 
217bbe4a97dSRui Paulo 	/* sysctl subtree for sensors of this type */
218bbe4a97dSRui Paulo 	so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev),
219bbe4a97dSRui Paulo 	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), st,
220bbe4a97dSRui Paulo 	    node, CTLFLAG_RD, NULL, NULL);
221bbe4a97dSRui Paulo 
222bbe4a97dSRui Paulo 	for (i = 0, o++; i < n; i++, o++) {
223bbe4a97dSRui Paulo 		ACPI_OBJECT	*oi;
224bbe4a97dSRui Paulo 		char		si[3];
225bbe4a97dSRui Paulo 		const char	*desc;
226bbe4a97dSRui Paulo 
227bbe4a97dSRui Paulo 		/* acpica5 automatically evaluates the referenced package */
228bbe4a97dSRui Paulo 		if (o[0].Type != ACPI_TYPE_PACKAGE) {
229bbe4a97dSRui Paulo 			device_printf(sc->sc_dev,
230bbe4a97dSRui Paulo 			    "%s: %i: not a package: %i type\n",
231bbe4a97dSRui Paulo 			    name, i, o[0].Type);
232bbe4a97dSRui Paulo 			continue;
233bbe4a97dSRui Paulo 		}
234bbe4a97dSRui Paulo 		oi = o[0].Package.Elements;
235bbe4a97dSRui Paulo 		if (o[0].Package.Count != 5 ||
236bbe4a97dSRui Paulo 		    oi[0].Type != ACPI_TYPE_INTEGER ||
237bbe4a97dSRui Paulo 		    oi[1].Type != ACPI_TYPE_STRING ||
238bbe4a97dSRui Paulo 		    oi[2].Type != ACPI_TYPE_INTEGER ||
239bbe4a97dSRui Paulo 		    oi[3].Type != ACPI_TYPE_INTEGER ||
240bbe4a97dSRui Paulo 		    oi[4].Type != ACPI_TYPE_INTEGER) {
241bbe4a97dSRui Paulo 			device_printf(sc->sc_dev,
242bbe4a97dSRui Paulo 			    "%s: %i: invalid package\n",
243bbe4a97dSRui Paulo 			    name, i);
244bbe4a97dSRui Paulo 			continue;
245bbe4a97dSRui Paulo 		}
246bbe4a97dSRui Paulo 		as[i].i = oi[0].Integer.Value;
247bbe4a97dSRui Paulo 		desc = oi[1].String.Pointer;
248bbe4a97dSRui Paulo 		as[i].l = oi[2].Integer.Value;
249bbe4a97dSRui Paulo 		as[i].h = oi[3].Integer.Value;
250bbe4a97dSRui Paulo 		as[i].t = st;
251bbe4a97dSRui Paulo #ifdef AIBS_VERBOSE
252bbe4a97dSRui Paulo 		device_printf(sc->sc_dev, "%c%i: "
253bbe4a97dSRui Paulo 		    "0x%08"PRIx64" %20s %5"PRIi64" / %5"PRIi64"  "
254bbe4a97dSRui Paulo 		    "0x%"PRIx64"\n",
255bbe4a97dSRui Paulo 		    name[0], i,
2560c10b85aSJung-uk Kim 		    (uint64_t)as[i].i, desc, (int64_t)as[i].l,
2570c10b85aSJung-uk Kim 		    (int64_t)as[i].h, (uint64_t)oi[4].Integer.Value);
258bbe4a97dSRui Paulo #endif
259bbe4a97dSRui Paulo 		snprintf(si, sizeof(si), "%i", i);
260bbe4a97dSRui Paulo 		SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev),
261f4f04709SMatthew D Fleming 		    SYSCTL_CHILDREN(so), i, si, CTLTYPE_INT | CTLFLAG_RD,
262bbe4a97dSRui Paulo 		    sc, st, aibs_sysctl, st == AIBS_TEMP ? "IK" : "I", desc);
263bbe4a97dSRui Paulo 	}
264bbe4a97dSRui Paulo 
265bbe4a97dSRui Paulo 	AcpiOsFree(b.Pointer);
266bbe4a97dSRui Paulo }
267bbe4a97dSRui Paulo 
268bbe4a97dSRui Paulo static int
269bbe4a97dSRui Paulo aibs_detach(device_t dev)
270bbe4a97dSRui Paulo {
271bbe4a97dSRui Paulo 	struct aibs_softc	*sc = device_get_softc(dev);
272bbe4a97dSRui Paulo 
273bbe4a97dSRui Paulo 	if (sc->sc_asens_volt != NULL)
274bbe4a97dSRui Paulo 		free(sc->sc_asens_volt, M_DEVBUF);
275bbe4a97dSRui Paulo 	if (sc->sc_asens_temp != NULL)
276bbe4a97dSRui Paulo 		free(sc->sc_asens_temp, M_DEVBUF);
277bbe4a97dSRui Paulo 	if (sc->sc_asens_fan != NULL)
278bbe4a97dSRui Paulo 		free(sc->sc_asens_fan, M_DEVBUF);
279bbe4a97dSRui Paulo 	return 0;
280bbe4a97dSRui Paulo }
281bbe4a97dSRui Paulo 
282bbe4a97dSRui Paulo #ifdef AIBS_VERBOSE
283bbe4a97dSRui Paulo #define ddevice_printf(x...) device_printf(x)
284bbe4a97dSRui Paulo #else
285bbe4a97dSRui Paulo #define ddevice_printf(x...)
286bbe4a97dSRui Paulo #endif
287bbe4a97dSRui Paulo 
288bbe4a97dSRui Paulo static int
289bbe4a97dSRui Paulo aibs_sysctl(SYSCTL_HANDLER_ARGS)
290bbe4a97dSRui Paulo {
291bbe4a97dSRui Paulo 	struct aibs_softc	*sc = arg1;
292bbe4a97dSRui Paulo 	enum aibs_type		st = arg2;
293bbe4a97dSRui Paulo 	int			i = oidp->oid_number;
294bbe4a97dSRui Paulo 	ACPI_STATUS		rs;
295bbe4a97dSRui Paulo 	ACPI_OBJECT		p, *bp;
296bbe4a97dSRui Paulo 	ACPI_OBJECT_LIST	mp;
297bbe4a97dSRui Paulo 	ACPI_BUFFER		b;
298bbe4a97dSRui Paulo 	char			*name;
299bbe4a97dSRui Paulo 	struct aibs_sensor	*as;
300bbe4a97dSRui Paulo 	ACPI_INTEGER		v, l, h;
301bbe4a97dSRui Paulo 	int			so[3];
302bbe4a97dSRui Paulo 
303bbe4a97dSRui Paulo 	switch (st) {
304bbe4a97dSRui Paulo 	case AIBS_VOLT:
305bbe4a97dSRui Paulo 		name = "RVLT";
306bbe4a97dSRui Paulo 		as = sc->sc_asens_volt;
307bbe4a97dSRui Paulo 		break;
308bbe4a97dSRui Paulo 	case AIBS_TEMP:
309bbe4a97dSRui Paulo 		name = "RTMP";
310bbe4a97dSRui Paulo 		as = sc->sc_asens_temp;
311bbe4a97dSRui Paulo 		break;
312bbe4a97dSRui Paulo 	case AIBS_FAN:
313bbe4a97dSRui Paulo 		name = "RFAN";
314bbe4a97dSRui Paulo 		as = sc->sc_asens_fan;
315bbe4a97dSRui Paulo 		break;
316bbe4a97dSRui Paulo 	default:
317bbe4a97dSRui Paulo 		return ENOENT;
318bbe4a97dSRui Paulo 	}
319bbe4a97dSRui Paulo 	if (as == NULL)
320bbe4a97dSRui Paulo 		return ENOENT;
321bbe4a97dSRui Paulo 	l = as[i].l;
322bbe4a97dSRui Paulo 	h = as[i].h;
323bbe4a97dSRui Paulo 	p.Type = ACPI_TYPE_INTEGER;
324bbe4a97dSRui Paulo 	p.Integer.Value = as[i].i;
325bbe4a97dSRui Paulo 	mp.Count = 1;
326bbe4a97dSRui Paulo 	mp.Pointer = &p;
327bbe4a97dSRui Paulo 	b.Length = ACPI_ALLOCATE_BUFFER;
328bbe4a97dSRui Paulo 	ACPI_SERIAL_BEGIN(aibs);
329bbe4a97dSRui Paulo 	rs = AcpiEvaluateObjectTyped(sc->sc_ah, name, &mp, &b,
330bbe4a97dSRui Paulo 	    ACPI_TYPE_INTEGER);
331bbe4a97dSRui Paulo 	if (ACPI_FAILURE(rs)) {
332bbe4a97dSRui Paulo 		ddevice_printf(sc->sc_dev,
333bbe4a97dSRui Paulo 		    "%s: %i: evaluation failed\n",
334bbe4a97dSRui Paulo 		    name, i);
335bbe4a97dSRui Paulo 		ACPI_SERIAL_END(aibs);
336bbe4a97dSRui Paulo 		return EIO;
337bbe4a97dSRui Paulo 	}
338bbe4a97dSRui Paulo 	bp = b.Pointer;
339bbe4a97dSRui Paulo 	v = bp->Integer.Value;
340bbe4a97dSRui Paulo 	AcpiOsFree(b.Pointer);
341bbe4a97dSRui Paulo 	ACPI_SERIAL_END(aibs);
342bbe4a97dSRui Paulo 
343bbe4a97dSRui Paulo 	switch (st) {
344bbe4a97dSRui Paulo 	case AIBS_VOLT:
345bbe4a97dSRui Paulo 		break;
346bbe4a97dSRui Paulo 	case AIBS_TEMP:
347bbe4a97dSRui Paulo 		v += 2732;
348bbe4a97dSRui Paulo 		l += 2732;
349bbe4a97dSRui Paulo 		h += 2732;
350bbe4a97dSRui Paulo 		break;
351bbe4a97dSRui Paulo 	case AIBS_FAN:
352bbe4a97dSRui Paulo 		break;
353bbe4a97dSRui Paulo 	}
354bbe4a97dSRui Paulo 	so[0] = v;
355bbe4a97dSRui Paulo 	so[1] = l;
356bbe4a97dSRui Paulo 	so[2] = h;
357bbe4a97dSRui Paulo 	return sysctl_handle_opaque(oidp, &so, sizeof(so), req);
358bbe4a97dSRui Paulo }
359