vald_acpi.c revision 1.4 1 1.4 jruoho /* $NetBSD: vald_acpi.c,v 1.4 2010/04/15 07:02:24 jruoho Exp $ */
2 1.1 jruoho
3 1.1 jruoho /*-
4 1.1 jruoho * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 1.1 jruoho * All rights reserved.
6 1.1 jruoho *
7 1.1 jruoho * This code is derived from software contributed to The NetBSD Foundation
8 1.1 jruoho * by Masanori Kanaoka.
9 1.1 jruoho *
10 1.1 jruoho * Redistribution and use in source and binary forms, with or without
11 1.1 jruoho * modification, are permitted provided that the following conditions
12 1.1 jruoho * are met:
13 1.1 jruoho * 1. Redistributions of source code must retain the above copyright
14 1.1 jruoho * notice, this list of conditions and the following disclaimer.
15 1.1 jruoho * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 jruoho * notice, this list of conditions and the following disclaimer in the
17 1.1 jruoho * documentation and/or other materials provided with the distribution.
18 1.1 jruoho *
19 1.1 jruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 jruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 jruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 jruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 jruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 jruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 jruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 jruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 jruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 jruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 jruoho * POSSIBILITY OF SUCH DAMAGE.
30 1.1 jruoho */
31 1.1 jruoho
32 1.1 jruoho /*
33 1.1 jruoho * Copyright 2001 Bill Sommerfeld.
34 1.1 jruoho * All rights reserved.
35 1.1 jruoho *
36 1.1 jruoho * Redistribution and use in source and binary forms, with or without
37 1.1 jruoho * modification, are permitted provided that the following conditions
38 1.1 jruoho * are met:
39 1.1 jruoho * 1. Redistributions of source code must retain the above copyright
40 1.1 jruoho * notice, this list of conditions and the following disclaimer.
41 1.1 jruoho * 2. Redistributions in binary form must reproduce the above copyright
42 1.1 jruoho * notice, this list of conditions and the following disclaimer in the
43 1.1 jruoho * documentation and/or other materials provided with the distribution.
44 1.1 jruoho * 3. All advertising materials mentioning features or use of this software
45 1.1 jruoho * must display the following acknowledgement:
46 1.1 jruoho * This product includes software developed for the NetBSD Project by
47 1.1 jruoho * Wasabi Systems, Inc.
48 1.1 jruoho * 4. The name of Wasabi Systems, Inc. may not be used to endorse
49 1.1 jruoho * or promote products derived from this software without specific prior
50 1.1 jruoho * written permission.
51 1.1 jruoho *
52 1.1 jruoho * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
53 1.1 jruoho * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
54 1.1 jruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
55 1.1 jruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
56 1.1 jruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
57 1.1 jruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
58 1.1 jruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59 1.1 jruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60 1.1 jruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61 1.1 jruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 1.1 jruoho * POSSIBILITY OF SUCH DAMAGE.
63 1.1 jruoho */
64 1.1 jruoho
65 1.1 jruoho /*
66 1.1 jruoho * ACPI VALD Driver for Toshiba Libretto L3.
67 1.1 jruoho * This driver is based on acpibat driver.
68 1.1 jruoho */
69 1.1 jruoho
70 1.1 jruoho /*
71 1.1 jruoho * Obtain information of Toshiba "GHCI" Method from next URL.
72 1.1 jruoho * http://www.buzzard.org.uk/toshiba/docs.html
73 1.1 jruoho * http://memebeam.org/toys/ToshibaAcpiDriver
74 1.1 jruoho */
75 1.1 jruoho
76 1.1 jruoho #include <sys/cdefs.h>
77 1.4 jruoho __KERNEL_RCSID(0, "$NetBSD: vald_acpi.c,v 1.4 2010/04/15 07:02:24 jruoho Exp $");
78 1.1 jruoho
79 1.1 jruoho #include <sys/param.h>
80 1.1 jruoho #include <sys/systm.h>
81 1.1 jruoho #include <sys/device.h>
82 1.1 jruoho
83 1.1 jruoho #include <dev/acpi/acpica.h>
84 1.1 jruoho #include <dev/acpi/acpireg.h>
85 1.1 jruoho #include <dev/acpi/acpivar.h>
86 1.1 jruoho
87 1.1 jruoho #define _COMPONENT ACPI_RESOURCE_COMPONENT
88 1.1 jruoho ACPI_MODULE_NAME ("vald_acpi")
89 1.1 jruoho
90 1.1 jruoho #define GHCI_WORDS 6
91 1.1 jruoho #define GHCI_FIFO_EMPTY 0x8c00
92 1.1 jruoho #define GHCI_NOT_SUPPORT 0x8000
93 1.1 jruoho
94 1.1 jruoho #define GHCI_BACKLIGHT 0x0002
95 1.1 jruoho #define GHCI_ACADAPTOR 0x0003
96 1.1 jruoho #define GHCI_FAN 0x0004
97 1.1 jruoho #define GHCI_SYSTEM_EVENT_FIFO 0x0016
98 1.1 jruoho #define GHCI_DISPLAY_DEVICE 0x001C
99 1.1 jruoho #define GHCI_HOTKEY_EVENT 0x001E
100 1.1 jruoho
101 1.1 jruoho #define GHCI_ON 0x0001
102 1.1 jruoho #define GHCI_OFF 0x0000
103 1.1 jruoho #define GHCI_ENABLE 0x0001
104 1.1 jruoho #define GHCI_DISABLE 0x0000
105 1.1 jruoho
106 1.1 jruoho #define GHCI_CRT 0x0002
107 1.1 jruoho #define GHCI_LCD 0x0001
108 1.1 jruoho
109 1.1 jruoho
110 1.1 jruoho struct vald_acpi_softc {
111 1.1 jruoho device_t sc_dev; /* base device glue */
112 1.1 jruoho struct acpi_devnode *sc_node; /* our ACPI devnode */
113 1.1 jruoho int sc_flags; /* see below */
114 1.1 jruoho
115 1.1 jruoho ACPI_HANDLE lcd_handle; /* lcd handle */
116 1.1 jruoho int *lcd_level; /* lcd brightness table */
117 1.1 jruoho int lcd_num; /* size of lcd brightness table */
118 1.1 jruoho int lcd_index; /* index of lcd brightness table */
119 1.1 jruoho
120 1.1 jruoho ACPI_INTEGER sc_ac_status; /* AC adaptor status when attach */
121 1.1 jruoho };
122 1.1 jruoho
123 1.1 jruoho static const char * const vald_acpi_hids[] = {
124 1.1 jruoho "TOS6200",
125 1.1 jruoho NULL
126 1.1 jruoho };
127 1.1 jruoho
128 1.1 jruoho #define LIBRIGHT_HOLD 0x00
129 1.1 jruoho #define LIBRIGHT_UP 0x01
130 1.1 jruoho #define LIBRIGHT_DOWN 0x02
131 1.1 jruoho
132 1.1 jruoho static int vald_acpi_match(device_t, cfdata_t, void *);
133 1.1 jruoho static void vald_acpi_attach(device_t, device_t, void *);
134 1.1 jruoho
135 1.1 jruoho static void vald_acpi_event(void *);
136 1.3 jruoho static void vald_acpi_notify_handler(ACPI_HANDLE, uint32_t, void *);
137 1.1 jruoho
138 1.1 jruoho #define ACPI_NOTIFY_ValdStatusChanged 0x80
139 1.1 jruoho
140 1.1 jruoho
141 1.3 jruoho static ACPI_STATUS vald_acpi_ghci_get(struct vald_acpi_softc *, uint32_t,
142 1.3 jruoho uint32_t *, uint32_t *);
143 1.3 jruoho static ACPI_STATUS vald_acpi_ghci_set(struct vald_acpi_softc *, uint32_t,
144 1.3 jruoho uint32_t, uint32_t *);
145 1.1 jruoho
146 1.3 jruoho static ACPI_STATUS vald_acpi_libright_get_bus(ACPI_HANDLE, uint32_t,
147 1.3 jruoho void *, void **);
148 1.1 jruoho static void vald_acpi_libright_get(struct vald_acpi_softc *);
149 1.1 jruoho static void vald_acpi_libright_set(struct vald_acpi_softc *, int);
150 1.1 jruoho
151 1.1 jruoho static void vald_acpi_video_switch(struct vald_acpi_softc *);
152 1.1 jruoho static void vald_acpi_fan_switch(struct vald_acpi_softc *);
153 1.1 jruoho
154 1.3 jruoho static ACPI_STATUS vald_acpi_bcm_set(ACPI_HANDLE, uint32_t);
155 1.3 jruoho static ACPI_STATUS vald_acpi_dssx_set(uint32_t);
156 1.1 jruoho
157 1.1 jruoho CFATTACH_DECL_NEW(vald_acpi, sizeof(struct vald_acpi_softc),
158 1.1 jruoho vald_acpi_match, vald_acpi_attach, NULL, NULL);
159 1.1 jruoho
160 1.1 jruoho /*
161 1.1 jruoho * vald_acpi_match:
162 1.1 jruoho *
163 1.1 jruoho * Autoconfiguration `match' routine.
164 1.1 jruoho */
165 1.1 jruoho static int
166 1.1 jruoho vald_acpi_match(device_t parent, cfdata_t match, void *aux)
167 1.1 jruoho {
168 1.1 jruoho struct acpi_attach_args *aa = aux;
169 1.1 jruoho
170 1.1 jruoho if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
171 1.1 jruoho return (0);
172 1.1 jruoho
173 1.1 jruoho return (acpi_match_hid(aa->aa_node->ad_devinfo, vald_acpi_hids));
174 1.1 jruoho }
175 1.1 jruoho
176 1.1 jruoho /*
177 1.1 jruoho * vald_acpi_attach:
178 1.1 jruoho *
179 1.1 jruoho * Autoconfiguration `attach' routine.
180 1.1 jruoho */
181 1.1 jruoho static void
182 1.1 jruoho vald_acpi_attach(device_t parent, device_t self, void *aux)
183 1.1 jruoho {
184 1.1 jruoho struct vald_acpi_softc *sc = device_private(self);
185 1.1 jruoho struct acpi_attach_args *aa = aux;
186 1.1 jruoho ACPI_STATUS rv;
187 1.3 jruoho uint32_t value, result;
188 1.1 jruoho
189 1.1 jruoho aprint_naive(": Toshiba VALD\n");
190 1.1 jruoho aprint_normal(": Toshiba VALD\n");
191 1.1 jruoho
192 1.1 jruoho sc->sc_node = aa->aa_node;
193 1.1 jruoho sc->sc_dev = self;
194 1.1 jruoho
195 1.1 jruoho /* Get AC adaptor status via _PSR. */
196 1.1 jruoho rv = acpi_eval_integer(ACPI_ROOT_OBJECT, "\\_SB_.ADP1._PSR",
197 1.1 jruoho &sc->sc_ac_status);
198 1.1 jruoho if (ACPI_FAILURE(rv))
199 1.1 jruoho aprint_error_dev(self, "Unable to evaluate _PSR: %s\n",
200 1.1 jruoho AcpiFormatException(rv));
201 1.1 jruoho else
202 1.1 jruoho aprint_verbose_dev(self, "AC adaptor %sconnected\n",
203 1.1 jruoho (sc->sc_ac_status == 0 ? "not ": ""));
204 1.1 jruoho
205 1.1 jruoho /* Get LCD backlight status. */
206 1.1 jruoho rv = vald_acpi_ghci_get(sc, GHCI_BACKLIGHT, &value, &result);
207 1.1 jruoho if (ACPI_SUCCESS(rv)) {
208 1.1 jruoho if (result != 0)
209 1.1 jruoho aprint_error_dev(self, "can't get backlight status error=%d\n",
210 1.1 jruoho result);
211 1.1 jruoho else
212 1.1 jruoho aprint_verbose_dev(self, "LCD backlight %s\n",
213 1.1 jruoho ((value == GHCI_ON) ? "on" : "off"));
214 1.1 jruoho }
215 1.1 jruoho
216 1.1 jruoho /* Enable SystemEventFIFO,HotkeyEvent */
217 1.1 jruoho rv = vald_acpi_ghci_set(sc, GHCI_SYSTEM_EVENT_FIFO, GHCI_ENABLE,
218 1.1 jruoho &result);
219 1.1 jruoho if (ACPI_SUCCESS(rv) && result != 0)
220 1.1 jruoho aprint_error_dev(self, "can't enable SystemEventFIFO error=%d\n",
221 1.1 jruoho result);
222 1.1 jruoho
223 1.1 jruoho rv = vald_acpi_ghci_set(sc, GHCI_HOTKEY_EVENT, GHCI_ENABLE, &result);
224 1.1 jruoho if (ACPI_SUCCESS(rv) && result != 0)
225 1.1 jruoho aprint_error_dev(self, "can't enable HotkeyEvent error=%d\n",
226 1.1 jruoho result);
227 1.1 jruoho
228 1.1 jruoho /* Check SystemFIFO events. */
229 1.1 jruoho vald_acpi_event(sc);
230 1.1 jruoho
231 1.1 jruoho /* Get LCD brightness level via _BCL. */
232 1.1 jruoho vald_acpi_libright_get(sc);
233 1.1 jruoho
234 1.1 jruoho /* Set LCD brightness level via _BCM. */
235 1.1 jruoho vald_acpi_libright_set(sc, LIBRIGHT_HOLD);
236 1.1 jruoho
237 1.1 jruoho /* enable vald notify */
238 1.4 jruoho rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "ENAB", NULL, NULL);
239 1.4 jruoho
240 1.4 jruoho if (ACPI_SUCCESS(rv))
241 1.4 jruoho (void)acpi_register_notify(sc->sc_node,
242 1.4 jruoho vald_acpi_notify_handler);
243 1.1 jruoho }
244 1.1 jruoho
245 1.1 jruoho /*
246 1.1 jruoho * vald_acpi_notify_handler:
247 1.1 jruoho *
248 1.1 jruoho * Notify handler.
249 1.1 jruoho */
250 1.1 jruoho static void
251 1.3 jruoho vald_acpi_notify_handler(ACPI_HANDLE handle, uint32_t notify, void *context)
252 1.1 jruoho {
253 1.4 jruoho struct vald_acpi_softc *sc;
254 1.4 jruoho device_t self = context;
255 1.4 jruoho
256 1.4 jruoho sc = device_private(self);
257 1.1 jruoho
258 1.1 jruoho switch (notify) {
259 1.1 jruoho
260 1.1 jruoho case ACPI_NOTIFY_ValdStatusChanged:
261 1.1 jruoho (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, vald_acpi_event, sc);
262 1.1 jruoho break;
263 1.1 jruoho
264 1.1 jruoho default:
265 1.1 jruoho aprint_error_dev(sc->sc_dev,
266 1.1 jruoho "unknown notify 0x%02X\n", notify);
267 1.1 jruoho break;
268 1.1 jruoho }
269 1.1 jruoho }
270 1.1 jruoho
271 1.1 jruoho /*
272 1.1 jruoho * vald_acpi_event:
273 1.1 jruoho *
274 1.1 jruoho * Check hotkey event and do it, if event occur.
275 1.1 jruoho */
276 1.1 jruoho static void
277 1.1 jruoho vald_acpi_event(void *arg)
278 1.1 jruoho {
279 1.1 jruoho struct vald_acpi_softc *sc = arg;
280 1.1 jruoho ACPI_STATUS rv;
281 1.3 jruoho uint32_t value, result;
282 1.1 jruoho
283 1.1 jruoho while(1) {
284 1.1 jruoho rv = vald_acpi_ghci_get(sc, GHCI_SYSTEM_EVENT_FIFO, &value,
285 1.1 jruoho &result);
286 1.1 jruoho if (ACPI_SUCCESS(rv) && result == 0) {
287 1.1 jruoho
288 1.1 jruoho switch (value) {
289 1.1 jruoho case 0x1c3: /* Fn + F9 */
290 1.1 jruoho break;
291 1.1 jruoho case 0x1c2: /* Fn + F8 */
292 1.1 jruoho vald_acpi_fan_switch(sc);
293 1.1 jruoho break;
294 1.1 jruoho case 0x1c1: /* Fn + F7 */
295 1.1 jruoho vald_acpi_libright_set(sc, LIBRIGHT_UP);
296 1.1 jruoho break;
297 1.1 jruoho case 0x1c0: /* Fn + F6 */
298 1.1 jruoho vald_acpi_libright_set(sc, LIBRIGHT_DOWN);
299 1.1 jruoho break;
300 1.1 jruoho case 0x1bf: /* Fn + F5 */
301 1.1 jruoho vald_acpi_video_switch(sc);
302 1.1 jruoho break;
303 1.1 jruoho default:
304 1.1 jruoho break;
305 1.1 jruoho }
306 1.1 jruoho }
307 1.1 jruoho if (ACPI_FAILURE(rv) || result == GHCI_FIFO_EMPTY)
308 1.1 jruoho break;
309 1.1 jruoho }
310 1.1 jruoho }
311 1.1 jruoho
312 1.1 jruoho /*
313 1.1 jruoho * vald_acpi_ghci_get:
314 1.1 jruoho *
315 1.1 jruoho * Get value via "GHCI" Method.
316 1.1 jruoho */
317 1.1 jruoho static ACPI_STATUS
318 1.1 jruoho vald_acpi_ghci_get(struct vald_acpi_softc *sc,
319 1.3 jruoho uint32_t reg, uint32_t *value, uint32_t *result)
320 1.1 jruoho {
321 1.1 jruoho ACPI_STATUS rv;
322 1.1 jruoho ACPI_OBJECT Arg[GHCI_WORDS];
323 1.1 jruoho ACPI_OBJECT_LIST ArgList;
324 1.1 jruoho ACPI_OBJECT *param, *PrtElement;
325 1.1 jruoho ACPI_BUFFER buf;
326 1.1 jruoho int i;
327 1.1 jruoho
328 1.1 jruoho for (i = 0; i < GHCI_WORDS; i++) {
329 1.1 jruoho Arg[i].Type = ACPI_TYPE_INTEGER;
330 1.1 jruoho Arg[i].Integer.Value = 0;
331 1.1 jruoho }
332 1.1 jruoho
333 1.1 jruoho Arg[0].Integer.Value = 0xfe00;
334 1.1 jruoho Arg[1].Integer.Value = reg;
335 1.1 jruoho Arg[2].Integer.Value = 0;
336 1.1 jruoho
337 1.1 jruoho ArgList.Count = GHCI_WORDS;
338 1.1 jruoho ArgList.Pointer = Arg;
339 1.1 jruoho
340 1.1 jruoho buf.Pointer = NULL;
341 1.1 jruoho buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
342 1.1 jruoho
343 1.1 jruoho rv = AcpiEvaluateObject(sc->sc_node->ad_handle,
344 1.1 jruoho "GHCI", &ArgList, &buf);
345 1.1 jruoho if (ACPI_FAILURE(rv)) {
346 1.1 jruoho aprint_error_dev(sc->sc_dev, "failed to evaluate GHCI: %s\n",
347 1.1 jruoho AcpiFormatException(rv));
348 1.1 jruoho return (rv);
349 1.1 jruoho }
350 1.1 jruoho
351 1.1 jruoho *result = GHCI_NOT_SUPPORT;
352 1.1 jruoho *value = 0;
353 1.2 jruoho param = buf.Pointer;
354 1.1 jruoho if (param->Type == ACPI_TYPE_PACKAGE) {
355 1.1 jruoho PrtElement = param->Package.Elements;
356 1.1 jruoho if (PrtElement->Type == ACPI_TYPE_INTEGER)
357 1.1 jruoho *result = PrtElement->Integer.Value;
358 1.1 jruoho PrtElement++;
359 1.1 jruoho PrtElement++;
360 1.1 jruoho if (PrtElement->Type == ACPI_TYPE_INTEGER)
361 1.1 jruoho *value = PrtElement->Integer.Value;
362 1.1 jruoho }
363 1.1 jruoho
364 1.1 jruoho if (buf.Pointer)
365 1.1 jruoho ACPI_FREE(buf.Pointer);
366 1.1 jruoho return (rv);
367 1.1 jruoho }
368 1.1 jruoho
369 1.1 jruoho /*
370 1.1 jruoho * vald_acpi_ghci_set:
371 1.1 jruoho *
372 1.1 jruoho * Set value via "GHCI" Method.
373 1.1 jruoho */
374 1.1 jruoho static ACPI_STATUS
375 1.1 jruoho vald_acpi_ghci_set(struct vald_acpi_softc *sc,
376 1.3 jruoho uint32_t reg, uint32_t value, uint32_t *result)
377 1.1 jruoho {
378 1.1 jruoho ACPI_STATUS rv;
379 1.1 jruoho ACPI_OBJECT Arg[GHCI_WORDS];
380 1.1 jruoho ACPI_OBJECT_LIST ArgList;
381 1.1 jruoho ACPI_OBJECT *param, *PrtElement;
382 1.1 jruoho ACPI_BUFFER buf;
383 1.1 jruoho int i;
384 1.1 jruoho
385 1.1 jruoho
386 1.1 jruoho for (i = 0; i < GHCI_WORDS; i++) {
387 1.1 jruoho Arg[i].Type = ACPI_TYPE_INTEGER;
388 1.1 jruoho Arg[i].Integer.Value = 0;
389 1.1 jruoho }
390 1.1 jruoho
391 1.1 jruoho Arg[0].Integer.Value = 0xff00;
392 1.1 jruoho Arg[1].Integer.Value = reg;
393 1.1 jruoho Arg[2].Integer.Value = value;
394 1.1 jruoho
395 1.1 jruoho ArgList.Count = GHCI_WORDS;
396 1.1 jruoho ArgList.Pointer = Arg;
397 1.1 jruoho
398 1.1 jruoho buf.Pointer = NULL;
399 1.1 jruoho buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
400 1.1 jruoho
401 1.1 jruoho rv = AcpiEvaluateObject(sc->sc_node->ad_handle,
402 1.1 jruoho "GHCI", &ArgList, &buf);
403 1.1 jruoho if (ACPI_FAILURE(rv)) {
404 1.1 jruoho aprint_error_dev(sc->sc_dev, "failed to evaluate GHCI: %s\n",
405 1.1 jruoho AcpiFormatException(rv));
406 1.1 jruoho return (rv);
407 1.1 jruoho }
408 1.1 jruoho
409 1.1 jruoho *result = GHCI_NOT_SUPPORT;
410 1.2 jruoho param = buf.Pointer;
411 1.1 jruoho if (param->Type == ACPI_TYPE_PACKAGE) {
412 1.1 jruoho PrtElement = param->Package.Elements;
413 1.1 jruoho if (PrtElement->Type == ACPI_TYPE_INTEGER)
414 1.1 jruoho *result = PrtElement->Integer.Value;
415 1.1 jruoho }
416 1.1 jruoho
417 1.1 jruoho if (buf.Pointer)
418 1.1 jruoho ACPI_FREE(buf.Pointer);
419 1.1 jruoho return (rv);
420 1.1 jruoho }
421 1.1 jruoho
422 1.1 jruoho /*
423 1.1 jruoho * vald_acpi_libright_get_bus:
424 1.1 jruoho *
425 1.1 jruoho * Get LCD brightness level via "_BCL" Method,
426 1.1 jruoho * and save this handle.
427 1.1 jruoho */
428 1.1 jruoho static ACPI_STATUS
429 1.3 jruoho vald_acpi_libright_get_bus(ACPI_HANDLE handle, uint32_t level,
430 1.1 jruoho void *context, void **status)
431 1.1 jruoho {
432 1.1 jruoho struct vald_acpi_softc *sc = context;
433 1.1 jruoho ACPI_STATUS rv;
434 1.1 jruoho ACPI_BUFFER buf;
435 1.1 jruoho ACPI_OBJECT *param, *PrtElement;
436 1.1 jruoho int i, *pi;
437 1.1 jruoho
438 1.1 jruoho rv = acpi_eval_struct(handle, "_BCL", &buf);
439 1.1 jruoho if (ACPI_FAILURE(rv))
440 1.1 jruoho return (AE_OK);
441 1.1 jruoho
442 1.1 jruoho sc->lcd_handle = handle;
443 1.2 jruoho param = buf.Pointer;
444 1.1 jruoho if (param->Type == ACPI_TYPE_PACKAGE) {
445 1.1 jruoho printf("_BCL retrun: %d packages\n", param->Package.Count);
446 1.1 jruoho
447 1.1 jruoho sc->lcd_num = param->Package.Count;
448 1.1 jruoho sc->lcd_level = ACPI_ALLOCATE(sizeof(int) * sc->lcd_num);
449 1.1 jruoho if (sc->lcd_level == NULL) {
450 1.1 jruoho if (buf.Pointer)
451 1.1 jruoho ACPI_FREE(buf.Pointer);
452 1.1 jruoho return (AE_NO_MEMORY);
453 1.1 jruoho }
454 1.1 jruoho
455 1.1 jruoho PrtElement = param->Package.Elements;
456 1.1 jruoho pi = sc->lcd_level;
457 1.1 jruoho for (i = 0; i < param->Package.Count; i++) {
458 1.1 jruoho if (PrtElement->Type == ACPI_TYPE_INTEGER) {
459 1.1 jruoho *pi = (unsigned)PrtElement->Integer.Value;
460 1.1 jruoho PrtElement++;
461 1.1 jruoho pi++;
462 1.1 jruoho }
463 1.1 jruoho }
464 1.1 jruoho if (sc->sc_ac_status == 1) /* AC adaptor on when attach */
465 1.1 jruoho sc->lcd_index = sc->lcd_num -1; /* MAX Brightness */
466 1.1 jruoho else
467 1.1 jruoho sc->lcd_index = 3;
468 1.1 jruoho
469 1.1 jruoho #ifdef ACPI_DEBUG
470 1.1 jruoho pi = sc->lcd_level;
471 1.1 jruoho printf("\t Full Power Level: %d\n", *pi);
472 1.1 jruoho printf("\t on Battery Level: %d\n", *(pi+1));
473 1.1 jruoho printf("\t Possible Level: ");
474 1.1 jruoho for (i = 2;i < sc->lcd_num; i++)
475 1.1 jruoho printf(" %d", *(pi+i));
476 1.1 jruoho printf("\n");
477 1.1 jruoho #endif
478 1.1 jruoho }
479 1.1 jruoho
480 1.1 jruoho if (buf.Pointer)
481 1.1 jruoho ACPI_FREE(buf.Pointer);
482 1.1 jruoho return (AE_OK);
483 1.1 jruoho }
484 1.1 jruoho
485 1.1 jruoho /*
486 1.1 jruoho * vald_acpi_libright_get:
487 1.1 jruoho *
488 1.1 jruoho * Search node that have "_BCL" Method.
489 1.1 jruoho */
490 1.1 jruoho static void
491 1.1 jruoho vald_acpi_libright_get(struct vald_acpi_softc *sc)
492 1.1 jruoho {
493 1.1 jruoho ACPI_HANDLE parent;
494 1.1 jruoho ACPI_STATUS rv;
495 1.1 jruoho
496 1.1 jruoho aprint_verbose_dev(sc->sc_dev, "get LCD brightness via _BCL\n");
497 1.1 jruoho
498 1.1 jruoho #ifdef ACPI_DEBUG
499 1.1 jruoho printf("acpi_libright_get: start\n");
500 1.1 jruoho #endif
501 1.1 jruoho rv = AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &parent);
502 1.1 jruoho if (ACPI_FAILURE(rv))
503 1.1 jruoho return;
504 1.1 jruoho
505 1.1 jruoho AcpiWalkNamespace(ACPI_TYPE_DEVICE, parent, 100,
506 1.1 jruoho vald_acpi_libright_get_bus, NULL, sc, NULL);
507 1.1 jruoho }
508 1.1 jruoho
509 1.1 jruoho /*
510 1.1 jruoho * vald_acpi_libright_set:
511 1.1 jruoho *
512 1.1 jruoho * Figure up next status and set it.
513 1.1 jruoho */
514 1.1 jruoho static void
515 1.1 jruoho vald_acpi_libright_set(struct vald_acpi_softc *sc, int UpDown)
516 1.1 jruoho {
517 1.3 jruoho uint32_t backlight, backlight_new, result, bright;
518 1.1 jruoho ACPI_STATUS rv;
519 1.1 jruoho int *pi;
520 1.1 jruoho
521 1.1 jruoho /* Skip,if it does not support _BCL. */
522 1.1 jruoho if (sc->lcd_handle == NULL)
523 1.1 jruoho return;
524 1.1 jruoho
525 1.1 jruoho /* Get LCD backlight status. */
526 1.1 jruoho rv = vald_acpi_ghci_get(sc, GHCI_BACKLIGHT, &backlight, &result);
527 1.1 jruoho if (ACPI_FAILURE(rv) || result != 0)
528 1.1 jruoho return;
529 1.1 jruoho
530 1.1 jruoho /* Figure up next status. */
531 1.1 jruoho backlight_new = backlight;
532 1.1 jruoho if (UpDown == LIBRIGHT_UP) {
533 1.1 jruoho if (backlight == 1)
534 1.1 jruoho sc->lcd_index++;
535 1.1 jruoho else {
536 1.1 jruoho /* backlight on */
537 1.1 jruoho backlight_new = 1;
538 1.1 jruoho sc->lcd_index = 2;
539 1.1 jruoho }
540 1.1 jruoho } else if (UpDown == LIBRIGHT_DOWN) {
541 1.1 jruoho if ((backlight == 1) && (sc->lcd_index > 2))
542 1.1 jruoho sc->lcd_index--;
543 1.1 jruoho else {
544 1.1 jruoho /* backlight off */
545 1.1 jruoho backlight_new = 0;
546 1.1 jruoho sc->lcd_index = 2;
547 1.1 jruoho }
548 1.1 jruoho }
549 1.1 jruoho
550 1.1 jruoho /* Check index value. */
551 1.1 jruoho if (sc->lcd_index < 2)
552 1.1 jruoho sc->lcd_index = 2; /* index Minium Value */
553 1.1 jruoho if (sc->lcd_index >= sc->lcd_num)
554 1.1 jruoho sc->lcd_index = sc->lcd_num - 1;
555 1.1 jruoho
556 1.1 jruoho /* Set LCD backlight,if status is changed. */
557 1.1 jruoho if (backlight_new != backlight) {
558 1.1 jruoho rv = vald_acpi_ghci_set(sc, GHCI_BACKLIGHT, backlight_new,
559 1.1 jruoho &result);
560 1.1 jruoho if (ACPI_SUCCESS(rv) && result != 0)
561 1.1 jruoho aprint_error_dev(sc->sc_dev, "can't set LCD backlight %s error=%x\n",
562 1.1 jruoho ((backlight_new == 1) ? "on" : "off"), result);
563 1.1 jruoho }
564 1.1 jruoho
565 1.1 jruoho if (backlight_new == 1) {
566 1.1 jruoho
567 1.1 jruoho pi = sc->lcd_level;
568 1.1 jruoho bright = *(pi + sc->lcd_index);
569 1.1 jruoho
570 1.1 jruoho rv = vald_acpi_bcm_set(sc->lcd_handle, bright);
571 1.1 jruoho if (ACPI_FAILURE(rv))
572 1.1 jruoho aprint_error_dev(sc->sc_dev, "unable to evaluate _BCM: %s\n",
573 1.1 jruoho AcpiFormatException(rv));
574 1.1 jruoho } else {
575 1.1 jruoho bright = 0;
576 1.1 jruoho }
577 1.1 jruoho #ifdef ACPI_DEBUG
578 1.1 jruoho printf("LCD bright");
579 1.1 jruoho printf(" %s", ((UpDown == LIBRIGHT_UP) ? "up":""));
580 1.1 jruoho printf("%s\n", ((UpDown == LIBRIGHT_DOWN) ? "down":""));
581 1.1 jruoho printf("\t acpi_libright_set: Set brightness to %d%%\n", bright);
582 1.1 jruoho #endif
583 1.1 jruoho }
584 1.1 jruoho
585 1.1 jruoho /*
586 1.1 jruoho * vald_acpi_video_switch:
587 1.1 jruoho *
588 1.1 jruoho * Get video status(LCD/CRT) and set new video status.
589 1.1 jruoho */
590 1.1 jruoho static void
591 1.1 jruoho vald_acpi_video_switch(struct vald_acpi_softc *sc)
592 1.1 jruoho {
593 1.1 jruoho ACPI_STATUS rv;
594 1.3 jruoho uint32_t value, result;
595 1.1 jruoho
596 1.1 jruoho /* Get video status. */
597 1.1 jruoho rv = vald_acpi_ghci_get(sc, GHCI_DISPLAY_DEVICE, &value, &result);
598 1.1 jruoho if (ACPI_FAILURE(rv))
599 1.1 jruoho return;
600 1.1 jruoho if (result != 0) {
601 1.1 jruoho aprint_error_dev(sc->sc_dev, "can't get video status error=%x\n",
602 1.1 jruoho result);
603 1.1 jruoho return;
604 1.1 jruoho }
605 1.1 jruoho
606 1.1 jruoho #ifdef ACPI_DEBUG
607 1.1 jruoho printf("Toggle LCD/CRT\n");
608 1.1 jruoho printf("\t Before switch, video status: %s",
609 1.1 jruoho (((value & GHCI_LCD) == GHCI_LCD) ? "LCD" : ""));
610 1.1 jruoho printf("%s\n", (((value & GHCI_CRT) == GHCI_CRT) ? "CRT": ""));
611 1.1 jruoho #endif
612 1.1 jruoho
613 1.1 jruoho /* Toggle LCD/CRT */
614 1.1 jruoho if (value & GHCI_LCD) {
615 1.1 jruoho value &= ~GHCI_LCD;
616 1.1 jruoho value |= GHCI_CRT;
617 1.1 jruoho } else if (value & GHCI_CRT){
618 1.1 jruoho value &= ~GHCI_CRT;
619 1.1 jruoho value |= GHCI_LCD;
620 1.1 jruoho }
621 1.1 jruoho
622 1.1 jruoho rv = vald_acpi_dssx_set(value);
623 1.1 jruoho if (ACPI_FAILURE(rv))
624 1.1 jruoho aprint_error_dev(sc->sc_dev, "unable to evaluate DSSX: %s\n",
625 1.1 jruoho AcpiFormatException(rv));
626 1.1 jruoho
627 1.1 jruoho }
628 1.1 jruoho
629 1.1 jruoho /*
630 1.1 jruoho * vald_acpi_bcm_set:
631 1.1 jruoho *
632 1.1 jruoho * Set LCD brightness via "_BCM" Method.
633 1.1 jruoho */
634 1.1 jruoho static ACPI_STATUS
635 1.3 jruoho vald_acpi_bcm_set(ACPI_HANDLE handle, uint32_t bright)
636 1.1 jruoho {
637 1.1 jruoho ACPI_STATUS rv;
638 1.1 jruoho ACPI_OBJECT Arg;
639 1.1 jruoho ACPI_OBJECT_LIST ArgList;
640 1.1 jruoho
641 1.1 jruoho ArgList.Count = 1;
642 1.1 jruoho ArgList.Pointer = &Arg;
643 1.1 jruoho
644 1.1 jruoho Arg.Type = ACPI_TYPE_INTEGER;
645 1.1 jruoho Arg.Integer.Value = bright;
646 1.1 jruoho
647 1.1 jruoho rv = AcpiEvaluateObject(handle, "_BCM", &ArgList, NULL);
648 1.1 jruoho return (rv);
649 1.1 jruoho }
650 1.1 jruoho
651 1.1 jruoho /*
652 1.1 jruoho * vald_acpi_dssx_set:
653 1.1 jruoho *
654 1.1 jruoho * Set value via "\\_SB_.VALX.DSSX" Method.
655 1.1 jruoho */
656 1.1 jruoho static ACPI_STATUS
657 1.3 jruoho vald_acpi_dssx_set(uint32_t value)
658 1.1 jruoho {
659 1.1 jruoho return acpi_eval_set_integer(NULL, "\\_SB_.VALX.DSSX", value);
660 1.1 jruoho }
661 1.1 jruoho
662 1.1 jruoho /*
663 1.1 jruoho * vald_acpi_fan_switch:
664 1.1 jruoho *
665 1.1 jruoho * Get FAN status and set new FAN status.
666 1.1 jruoho */
667 1.1 jruoho static void
668 1.1 jruoho vald_acpi_fan_switch(struct vald_acpi_softc *sc)
669 1.1 jruoho {
670 1.1 jruoho ACPI_STATUS rv;
671 1.3 jruoho uint32_t value, result;
672 1.1 jruoho
673 1.1 jruoho /* Get FAN status */
674 1.1 jruoho rv = vald_acpi_ghci_get(sc, GHCI_FAN, &value, &result);
675 1.1 jruoho if (ACPI_FAILURE(rv))
676 1.1 jruoho return;
677 1.1 jruoho if (result != 0) {
678 1.1 jruoho aprint_error_dev(sc->sc_dev, "can't get FAN status error=%d\n",
679 1.1 jruoho result);
680 1.1 jruoho return;
681 1.1 jruoho }
682 1.1 jruoho
683 1.1 jruoho #ifdef ACPI_DEBUG
684 1.1 jruoho printf("Toggle FAN on/off\n");
685 1.1 jruoho printf("\t Before toggle, FAN status %s\n",
686 1.1 jruoho (value == GHCI_OFF ? "off" : "on"));
687 1.1 jruoho #endif
688 1.1 jruoho
689 1.1 jruoho /* Toggle FAN on/off */
690 1.1 jruoho if (value == GHCI_OFF)
691 1.1 jruoho value = GHCI_ON;
692 1.1 jruoho else
693 1.1 jruoho value = GHCI_OFF;
694 1.1 jruoho
695 1.1 jruoho /* Set FAN new status. */
696 1.1 jruoho rv = vald_acpi_ghci_set(sc, GHCI_FAN, value, &result);
697 1.1 jruoho if (ACPI_FAILURE(rv))
698 1.1 jruoho return;
699 1.1 jruoho if (result != 0) {
700 1.1 jruoho aprint_error_dev(sc->sc_dev, "can't set FAN status error=%d\n",
701 1.1 jruoho result);
702 1.1 jruoho return;
703 1.1 jruoho }
704 1.1 jruoho
705 1.1 jruoho #ifdef ACPI_DEBUG
706 1.1 jruoho printf("\t After toggle, FAN status %s\n",
707 1.1 jruoho (value == GHCI_OFF ? "off" : "on"));
708 1.1 jruoho #endif
709 1.1 jruoho }
710