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{
51 char desc[DESCSTRLEN];
53 ACPI_SERIAL_DECL(aiboost, "ACPI AIBOOST");
55 struct acpi_aiboost_component{
57 struct acpi_aiboost_element elem[1];
60 struct acpi_aiboost_softc {
62 struct acpi_aiboost_component *temp;
63 struct acpi_aiboost_component *volt;
64 struct acpi_aiboost_component *fan;
67 static int acpi_aiboost_probe(device_t dev);
68 static int acpi_aiboost_attach(device_t dev);
69 static int acpi_aiboost_detach(device_t dev);
71 static device_method_t acpi_aiboost_methods[] = {
72 /* Device interface */
73 DEVMETHOD(device_probe, acpi_aiboost_probe),
74 DEVMETHOD(device_attach, acpi_aiboost_attach),
75 DEVMETHOD(device_detach, acpi_aiboost_detach),
80 static driver_t acpi_aiboost_driver = {
83 sizeof(struct acpi_aiboost_softc),
86 static devclass_t acpi_aiboost_devclass;
88 DRIVER_MODULE(acpi_aiboost, acpi, acpi_aiboost_driver, acpi_aiboost_devclass,
90 MODULE_DEPEND(acpi_aiboost, acpi, 1, 1, 1);
91 static char *abs_id[] = {"ATK0110", NULL};
93 /*VSIF, RVLT, SVLT, TSIF, RTMP, STMP FSIF, RFAN, SFAN */
95 static ACPI_STATUS acpi_aiboost_getcomponent(device_t dev, char *name, struct acpi_aiboost_component **comp)
97 ACPI_BUFFER buf, buf2;
98 ACPI_OBJECT *o,*elem,*subobj;
100 struct acpi_aiboost_component *c = NULL;
105 buf.Length = ACPI_ALLOCATE_BUFFER;
108 status = AcpiEvaluateObject(acpi_get_handle(dev), name, NULL, &buf);
110 if(ACPI_FAILURE(status))
114 if(o->Type != ACPI_TYPE_PACKAGE)
117 elem = o->Package.Elements;
118 if(elem->Type != ACPI_TYPE_INTEGER)
121 c = malloc(sizeof(struct acpi_aiboost_component)
122 + sizeof(struct acpi_aiboost_element)
123 * (elem->Integer.Value -1),
124 M_DEVBUF, M_ZERO|M_WAITOK);
126 c->num = elem->Integer.Value;
128 for(i = 1 ; i < o->Package.Count; i++){
129 elem = &o->Package.Elements[i];
130 if(elem->Type != ACPI_TYPE_ANY){
134 c->elem[ i - 1].h = elem->Reference.Handle;
137 buf2.Length = ACPI_ALLOCATE_BUFFER;
139 status = AcpiEvaluateObject(c->elem[i - 1].h, NULL, NULL,
141 if(ACPI_FAILURE(status)){
142 printf("FETCH OBJECT\n");
145 subobj = buf2.Pointer;
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);
166 AcpiOsFree(buf.Pointer);
171 printf("BAD DATA\n");
173 AcpiOsFree(buf.Pointer);
175 AcpiOsFree(buf2.Pointer);
182 acpi_aiboost_get_value(ACPI_HANDLE handle, char *path, UINT32 number)
184 ACPI_OBJECT arg1, *ret;
185 ACPI_OBJECT_LIST args;
187 buf.Length = ACPI_ALLOCATE_BUFFER;
191 arg1.Type = ACPI_TYPE_INTEGER;
192 arg1.Integer.Value = number;
194 args.Pointer = &arg1;
196 if(ACPI_FAILURE(AcpiEvaluateObject(handle, path, &args, &buf))){
201 val = (ret->Type == ACPI_TYPE_INTEGER)? ret->Integer.Value : -1;
203 AcpiOsFree(buf.Pointer);
208 static int acpi_aiboost_temp_sysctl(SYSCTL_HANDLER_ARGS)
211 int function = oidp->oid_arg2;
213 ACPI_SERIAL_BEGIN(aiboost);
214 val = acpi_aiboost_get_value(acpi_get_handle(dev), "RTMP",function );
215 error = sysctl_handle_int(oidp, &val, 0 , req);
216 ACPI_SERIAL_END(aiboost);
221 static int acpi_aiboost_volt_sysctl(SYSCTL_HANDLER_ARGS)
224 int function = oidp->oid_arg2;
226 ACPI_SERIAL_BEGIN(aiboost);
227 val = acpi_aiboost_get_value(acpi_get_handle(dev), "RVLT", function);
228 error = sysctl_handle_int(oidp, &val, 0 , req);
229 ACPI_SERIAL_END(aiboost);
234 static int acpi_aiboost_fan_sysctl(SYSCTL_HANDLER_ARGS)
237 int function = oidp->oid_arg2;
239 ACPI_SERIAL_BEGIN(aiboost);
240 val = acpi_aiboost_get_value(acpi_get_handle(dev), "RFAN", function);
241 error = sysctl_handle_int(oidp, &val, 0 , req);
242 ACPI_SERIAL_END(aiboost);
248 acpi_aiboost_probe(device_t dev)
252 if (ACPI_ID_PROBE(device_get_parent(dev), dev, abs_id)) {
253 device_set_desc(dev, "ASUStek AIBOOSTER");
260 acpi_aiboost_attach(device_t dev)
262 struct acpi_aiboost_softc *sc;
263 char nambuf[]="tempXXX";
266 sc = device_get_softc(dev);
267 if(ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "TSIF", &sc->temp)))
269 for(i= 0; i < sc->temp->num; i++){
270 sprintf(nambuf,"temp%d", i);
271 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
272 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
274 CTLTYPE_INT|CTLFLAG_RD, dev,
275 sc->temp->elem[i].id,
276 acpi_aiboost_temp_sysctl,
277 "I", sc->temp->elem[i].desc);
279 if(ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "VSIF", &sc->volt)))
282 for(i= 0; i < sc->volt->num; i++){
283 sprintf(nambuf,"volt%d", i);
284 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
285 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
287 CTLTYPE_INT|CTLFLAG_RD, dev,
288 sc->volt->elem[i].id,
289 acpi_aiboost_volt_sysctl,
290 "I", sc->volt->elem[i].desc);
293 if(ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "FSIF", &sc->fan)))
296 for(i= 0; i < sc->fan->num; i++){
297 sprintf(nambuf,"fan%d", i);
298 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
299 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
301 CTLTYPE_INT|CTLFLAG_RD, dev,
303 acpi_aiboost_fan_sysctl,
304 "I", sc->fan->elem[i].desc);
314 acpi_aiboost_detach(device_t dev)
316 struct acpi_aiboost_softc *sc = device_get_softc(dev);
319 free(sc->temp, M_DEVBUF);
321 free(sc->volt, M_DEVBUF);
323 free(sc->fan, M_DEVBUF);
329 acpi_aiboost_suspend(device_t dev)
331 struct acpi_aiboost_softc *sc = device_get_softc(dev);
336 acpi_aiboost_resume(device_t dev)