2 * Copyright (c) 2006 Takanori Watanabe
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
32 #include <sys/kernel.h>
35 #include <contrib/dev/acpica/include/acpi.h>
38 #include <sys/module.h>
39 #include <dev/acpica/acpivar.h>
40 #include <sys/sysctl.h>
41 #include <sys/malloc.h>
42 #include <sys/sysctl.h>
44 #define _COMPONENT ACPI_OEM
45 ACPI_MODULE_NAME("AIBOOST")
48 struct acpi_aiboost_element{
50 char desc[DESCSTRLEN];
52 ACPI_SERIAL_DECL(aiboost, "ACPI AIBOOST");
54 struct acpi_aiboost_component{
56 struct acpi_aiboost_element elem[1];
59 struct acpi_aiboost_softc {
61 struct acpi_aiboost_component *temp;
62 struct acpi_aiboost_component *volt;
63 struct acpi_aiboost_component *fan;
66 static int acpi_aiboost_probe(device_t dev);
67 static int acpi_aiboost_attach(device_t dev);
68 static int acpi_aiboost_detach(device_t dev);
70 static device_method_t acpi_aiboost_methods[] = {
71 /* Device interface */
72 DEVMETHOD(device_probe, acpi_aiboost_probe),
73 DEVMETHOD(device_attach, acpi_aiboost_attach),
74 DEVMETHOD(device_detach, acpi_aiboost_detach),
79 static driver_t acpi_aiboost_driver = {
82 sizeof(struct acpi_aiboost_softc),
85 static devclass_t acpi_aiboost_devclass;
87 DRIVER_MODULE(acpi_aiboost, acpi, acpi_aiboost_driver, acpi_aiboost_devclass,
89 MODULE_DEPEND(acpi_aiboost, acpi, 1, 1, 1);
90 static char *abs_id[] = {"ATK0110", NULL};
92 /*VSIF, RVLT, SVLT, TSIF, RTMP, STMP FSIF, RFAN, SFAN */
94 static ACPI_STATUS acpi_aiboost_getcomponent(device_t dev, char *name, struct acpi_aiboost_component **comp)
96 ACPI_BUFFER buf, buf2;
97 ACPI_OBJECT *o,*elem,*subobj;
99 struct acpi_aiboost_component *c = NULL;
104 buf.Length = ACPI_ALLOCATE_BUFFER;
107 status = AcpiEvaluateObject(acpi_get_handle(dev), name, NULL, &buf);
109 if(ACPI_FAILURE(status))
113 if(o->Type != ACPI_TYPE_PACKAGE)
116 elem = o->Package.Elements;
117 if(elem->Type != ACPI_TYPE_INTEGER)
120 c = malloc(sizeof(struct acpi_aiboost_component)
121 + sizeof(struct acpi_aiboost_element)
122 * (elem->Integer.Value -1),
123 M_DEVBUF, M_ZERO|M_WAITOK);
125 c->num = elem->Integer.Value;
127 for(i = 1 ; i < o->Package.Count; i++){
128 elem = &o->Package.Elements[i];
129 if (elem->Type == ACPI_TYPE_ANY) {
131 buf2.Length = ACPI_ALLOCATE_BUFFER;
133 status = AcpiEvaluateObject(elem->Reference.Handle,
135 if (ACPI_FAILURE(status)){
136 printf("FETCH OBJECT\n");
139 subobj = buf2.Pointer;
140 } else if (elem->Type == ACPI_TYPE_PACKAGE)
143 printf("NO PACKAGE\n");
146 if(ACPI_FAILURE(acpi_PkgInt32(subobj,0, &c->elem[i -1].id))){
147 printf("ID FAILED\n");
150 status = acpi_PkgStr(subobj, 1, c->elem[i - 1].desc,
151 sizeof(c->elem[i - 1].desc));
152 if(ACPI_FAILURE(status)){
154 c->elem[i - 1].desc[DESCSTRLEN-1] = 0;
156 printf("DESC FAILED %d\n", i-1);
162 AcpiOsFree(buf2.Pointer);
168 AcpiOsFree(buf.Pointer);
173 printf("BAD DATA\n");
175 AcpiOsFree(buf.Pointer);
177 AcpiOsFree(buf2.Pointer);
184 acpi_aiboost_get_value(ACPI_HANDLE handle, char *path, UINT32 number)
186 ACPI_OBJECT arg1, *ret;
187 ACPI_OBJECT_LIST args;
189 buf.Length = ACPI_ALLOCATE_BUFFER;
193 arg1.Type = ACPI_TYPE_INTEGER;
194 arg1.Integer.Value = number;
196 args.Pointer = &arg1;
198 if(ACPI_FAILURE(AcpiEvaluateObject(handle, path, &args, &buf))){
203 val = (ret->Type == ACPI_TYPE_INTEGER)? ret->Integer.Value : -1;
205 AcpiOsFree(buf.Pointer);
210 static int acpi_aiboost_temp_sysctl(SYSCTL_HANDLER_ARGS)
213 int function = oidp->oid_arg2;
215 ACPI_SERIAL_BEGIN(aiboost);
216 val = acpi_aiboost_get_value(acpi_get_handle(dev), "RTMP",function );
217 error = sysctl_handle_int(oidp, &val, 0 , req);
218 ACPI_SERIAL_END(aiboost);
223 static int acpi_aiboost_volt_sysctl(SYSCTL_HANDLER_ARGS)
226 int function = oidp->oid_arg2;
228 ACPI_SERIAL_BEGIN(aiboost);
229 val = acpi_aiboost_get_value(acpi_get_handle(dev), "RVLT", function);
230 error = sysctl_handle_int(oidp, &val, 0 , req);
231 ACPI_SERIAL_END(aiboost);
236 static int acpi_aiboost_fan_sysctl(SYSCTL_HANDLER_ARGS)
239 int function = oidp->oid_arg2;
241 ACPI_SERIAL_BEGIN(aiboost);
242 val = acpi_aiboost_get_value(acpi_get_handle(dev), "RFAN", function);
243 error = sysctl_handle_int(oidp, &val, 0 , req);
244 ACPI_SERIAL_END(aiboost);
250 acpi_aiboost_probe(device_t dev)
254 if (ACPI_ID_PROBE(device_get_parent(dev), dev, abs_id)) {
255 device_set_desc(dev, "ASUStek AIBOOSTER");
262 acpi_aiboost_attach(device_t dev)
264 struct acpi_aiboost_softc *sc;
265 char nambuf[]="tempXXX";
268 sc = device_get_softc(dev);
269 if(ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "TSIF", &sc->temp)))
271 for(i= 0; i < sc->temp->num; i++){
272 sprintf(nambuf,"temp%d", i);
273 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
274 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
276 CTLTYPE_INT|CTLFLAG_RD, dev,
277 sc->temp->elem[i].id,
278 acpi_aiboost_temp_sysctl,
279 "I", sc->temp->elem[i].desc);
281 if(ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "VSIF", &sc->volt)))
284 for(i= 0; i < sc->volt->num; i++){
285 sprintf(nambuf,"volt%d", i);
286 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
287 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
289 CTLTYPE_INT|CTLFLAG_RD, dev,
290 sc->volt->elem[i].id,
291 acpi_aiboost_volt_sysctl,
292 "I", sc->volt->elem[i].desc);
295 if(ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "FSIF", &sc->fan)))
298 for(i= 0; i < sc->fan->num; i++){
299 sprintf(nambuf,"fan%d", i);
300 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
301 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
303 CTLTYPE_INT|CTLFLAG_RD, dev,
305 acpi_aiboost_fan_sysctl,
306 "I", sc->fan->elem[i].desc);
316 acpi_aiboost_detach(device_t dev)
318 struct acpi_aiboost_softc *sc = device_get_softc(dev);
321 free(sc->temp, M_DEVBUF);
323 free(sc->volt, M_DEVBUF);
325 free(sc->fan, M_DEVBUF);
331 acpi_aiboost_suspend(device_t dev)
333 struct acpi_aiboost_softc *sc = device_get_softc(dev);
338 acpi_aiboost_resume(device_t dev)