1 /* $NetBSD: valz_acpi.c,v 1.9 2021/01/29 15:49:55 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Masanori Kanaoka. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright 2001 Bill Sommerfeld. 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed for the NetBSD Project by 47 * Wasabi Systems, Inc. 48 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 49 * or promote products derived from this software without specific prior 50 * written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 62 * POSSIBILITY OF SUCH DAMAGE. 63 */ 64 65 /* 66 * ACPI VALZ Driver for Toshiba dynabook R63/PS 67 * This driver is based on vald_acpi.c 68 */ 69 70 /* 71 * Obtain information of Toshiba "GHCI" Method from next URL. 72 * http://www.buzzard.me.uk/toshiba/docs.html 73 * http://memebeam.org/toys/ToshibaAcpiDriver 74 */ 75 76 #include <sys/cdefs.h> 77 __KERNEL_RCSID(0, "$NetBSD: valz_acpi.c,v 1.9 2021/01/29 15:49:55 thorpej Exp $"); 78 79 #include <sys/param.h> 80 #include <sys/systm.h> 81 #include <sys/device.h> 82 83 #include <dev/acpi/acpica.h> 84 #include <dev/acpi/acpireg.h> 85 #include <dev/acpi/acpivar.h> 86 87 #define _COMPONENT ACPI_RESOURCE_COMPONENT 88 ACPI_MODULE_NAME ("valz_acpi") 89 90 #define METHOD_HCI "GHCI" 91 #define METHOD_HCI_ENABLE "ENAB" 92 93 /* Operations */ 94 /* Get */ 95 #define HCI_GET 0xfe00 96 #define SCI_CHECK 0xf000 97 #define SCI_GET 0xf300 98 99 /* Set */ 100 #define HCI_SET 0xff00 101 #define SCI_OPEN 0xf100 102 #define SCI_CLOSE 0xf200 103 #define SCI_SET 0xf400 104 105 /* Return codes */ 106 #define HCI_SUCCESS 0x0000 107 #define HCI_FAILURE 0x1000 108 #define HCI_NOT_SUPPORTED 0x8000 109 #define HCI_INPUT_ERROR 0x8300 110 #define HCI_FIFO_EMPTY 0x8c00 111 112 #define SCI_OPENCLOSE_OK 0x0044 113 #define SCI_NOT_SUPPORTED 0x8000 114 #define SCI_ALREADY_OPEN 0x8100 115 #define SCI_NOT_OPEN 0x8200 116 #define SCI_NOT_PRESENT 0x8600 117 118 /* Functions */ 119 #define HCI_LCD_BACKLIGHT 0x0002 120 #define HCI_ACADAPTOR 0x0003 121 #define HCI_SYSTEM_EVENT_FIFO 0x0016 122 #define HCI_KBD_BACKLIGHT 0x0017 123 #define HCI_DISPLAY_DEV 0x001c 124 #define HCI_HOTKEY_EVENT 0x001e 125 #define HCI_LCD_BRIGHTNESS 0x002a 126 #define HCI_CPU_SPEED 0x0032 127 128 #define SCI_USB_OFF_CHARGE 0x0150 129 #define SCI_TOUCHPAD 0x050e 130 #define SCI_KBD_BACKLIGHT_STS 0x015c 131 #define SCI_KBD_BACKLIGHT 0x0095 132 133 #define SCI_KBD_BL_TIME_SHIFT 0x10 134 135 /* Field definitions */ 136 #define HCI_LCD_BRIGHTNESS_BITS 3 137 #define HCI_LCD_BRIGHTNESS_SFT (16 - HCI_LCD_BRIGHTNESS_BITS) 138 #define HCI_LCD_BRIGHTNESS_MIN 0 139 #define HCI_LCD_BRIGHTNESS_MAX 7 140 #define HCI_VIDEO_DEVICE_FLG 0x0100 141 #define HCI_CPU_SPEED_BITS 3 142 #define HCI_CPU_SPEED_SFT (16 - HCI_CPU_SPEED_BITS) 143 #define HCI_CPU_SPEED_MAX ((1 << HCI_CPU_SPEED_BITS) - 1) 144 145 /* Key press/release events */ 146 147 /* Key press/release events */ 148 #define FN_RELEASE_OFFSET 0x80 149 # if 0 150 /* Not used */ 151 #define FN_PRESS 0x01ff 152 #define FN_RELEASE 0x0100 153 # endif 154 #define FN_ESC_PRESS 0x0101 155 #define FN_ESC_RELEASE (FN_ESC_PRESS + FN_RELEASE_OFFSET) 156 #define FN_F1_PRESS 0x013b 157 #define FN_F1_RELEASE (FN_F1_PRESS + FN_RELEASE_OFFSET) 158 #define FN_F2_PRESS 0x013c 159 #define FN_F2_RELEASE (FN_F2_PRESS + FN_RELEASE_OFFSET) 160 #define FN_F3_PRESS 0x013d 161 #define FN_F3_RELEASE (FN_F3_PRESS + FN_RELEASE_OFFSET) 162 #define FN_F4_PRESS 0x013e 163 #define FN_F4_RELEASE (FN_F4_PRESS + FN_RELEASE_OFFSET) 164 #define FN_F5_PRESS 0x013f 165 #define FN_F5_RELEASE (FN_F5_PRESS + FN_RELEASE_OFFSET) 166 #define FN_F6_PRESS 0x0140 167 #define FN_F6_RELEASE (FN_F6_PRESS + FN_RELEASE_OFFSET) 168 #define FN_F7_PRESS 0x0141 169 #define FN_F7_RELEASE (FN_F7_PRESS + FN_RELEASE_OFFSET) 170 #define FN_F8_PRESS 0x0142 171 #define FN_F8_RELEASE (FN_F8_PRESS + FN_RELEASE_OFFSET) 172 #define FN_F9_PRESS 0x0143 173 #define FN_F9_RELEASE (FN_F9_PRESS + FN_RELEASE_OFFSET) 174 /* Toggle, they are controlled by hardware */ 175 #define FN_F10_ON 0x1bb0 176 #define FN_F10_OFF 0x1bb1 177 #define FN_F11_ON 0x1bb2 178 #define FN_F11_OFF 0x1bb3 179 /* Fn+F12 does not emit keycode */ 180 /* dynabook R63/PS does not have KANJI keytop print */ 181 #define FN_KNJ_PRESS 0x0129 182 #define FN_KNJ_RELEASE (FN_KNJ_PRESS + FN_RELEASE_OFFSET) 183 #define FN_1_PRESS 0x0102 184 #define FN_1_RELEASE (FN_1_PRESS + FN_RELEASE_OFFSET) 185 #define FN_2_PRESS 0x0103 186 #define FN_2_RELEASE (FN_2_PRESS + FN_RELEASE_OFFSET) 187 /* Fn+3 and Fn+4 do not emit keybode */ 188 #define FN_Z_PRESS 0x012c 189 #define FN_Z_RELEASE (FN_1_PRESS + FN_RELEASE_OFFSET) 190 #define FN_SPACE_PRESS 0x0139 191 #define FN_SPACE_RELEASE (FN_1_PRESS + FN_RELEASE_OFFSET) 192 #define FN_TAB_PRESS 0x010f 193 #define FN_TAB_RELEASE (FN_TAB_PRESS + FN_RELEASE_OFFSET) 194 #define FN_CAPS_PRESS 0x013a 195 #define FN_CAPS_RELEASE (FN_CAPS_PRESS + FN_RELEASE_OFFSET) 196 #define FN_BACKSPACE_PRESS 0x010e 197 #define FN_BACKSPACE_RELEASE (FN_BACKSPACE_PRESS + FN_RELEASE_OFFSET) 198 #define FN_INS_PRESS 0x0152 199 #define FN_INS_RELEASE (FN_INS_PRESS + FN_RELEASE_OFFSET) 200 #define FN_DEL_PRESS 0x0153 201 #define FN_DEL_RELEASE (FN_DEL_PRESS + FN_RELEASE_OFFSET) 202 #define FN_PRTSC_PRESS 0x0137 203 #define FN_PRTSC_RELEASE (FN_PRTSC_PRESS + FN_RELEASE_OFFSET) 204 205 /* HCI register definitions */ 206 #define HCI_WORDS 6 /* number of registers */ 207 #define HCI_REG_AX 0 /* Operation -> return value */ 208 #define HCI_REG_BX 1 /* Function */ 209 #define HCI_REG_CX 2 /* Argument (in or out) */ 210 #define HCI_REG_DX 3 /* unused */ 211 #define HCI_REG_SI 4 /* unused */ 212 #define HCI_REG_DI 5 /* unused */ 213 214 #define HCI_ON 0x0001 215 #define HCI_OFF 0x0000 216 #define HCI_ENABLE 0x0001 217 #define HCI_DISABLE 0x0000 218 219 #define HCI_LCD 0x1 220 #define HCI_CRT 0x2 221 #define HCI_TV 0x4 222 223 #define SCI_KBD_BL_MODE_MASK 0x1f 224 #define SCI_KBD_BL_TIMO_SFT 0x10 225 #define SCI_KBD_BL_MODE_AUTO 0x2 226 #define SCI_KBD_BL_MODE_ON 0x8 227 #define SCI_KBD_BL_MODE_OFF 0x10 228 229 struct valz_acpi_softc { 230 device_t sc_dev; /* base device glue */ 231 struct acpi_devnode *sc_node; /* our ACPI devnode */ 232 }; 233 234 static const struct device_compatible_entry compat_data[] = { 235 { .compat = "TOS6208" }, 236 DEVICE_COMPAT_EOL 237 }; 238 239 static int valz_acpi_match(device_t, cfdata_t, void *); 240 static void valz_acpi_attach(device_t, device_t, void *); 241 242 static void valz_acpi_event(void *); 243 static void valz_acpi_notify_handler(ACPI_HANDLE, uint32_t, void *); 244 245 #define ACPI_NOTIFY_ValzHotkeyPressed 0x80 246 #define ACPI_NOTIFY_ValzLidClosed 0x8f 247 #define ACPI_NOTIFY_ValzKbdBLChanges 0x92 248 249 /* HCI manipulation */ 250 static ACPI_STATUS hci_op(struct valz_acpi_softc *, 251 uint32_t *, uint32_t *); 252 static ACPI_STATUS valz_acpi_hci_get(struct valz_acpi_softc *, uint32_t, 253 uint32_t, uint32_t *, uint32_t *); 254 static ACPI_STATUS valz_acpi_hci_set(struct valz_acpi_softc *, uint32_t, 255 uint32_t, uint32_t, uint32_t *); 256 257 static ACPI_STATUS sci_open(struct valz_acpi_softc *); 258 static ACPI_STATUS sci_close(struct valz_acpi_softc *); 259 260 static ACPI_STATUS valz_acpi_touchpad_toggle(struct valz_acpi_softc *); 261 static ACPI_STATUS valz_acpi_lcd_backlight_toggle( 262 struct valz_acpi_softc *sc); 263 264 CFATTACH_DECL_NEW(valz_acpi, sizeof(struct valz_acpi_softc), 265 valz_acpi_match, valz_acpi_attach, NULL, NULL); 266 267 /* 268 * valz_acpi_match: 269 * 270 * Autoconfiguration `match' routine. 271 */ 272 static int 273 valz_acpi_match(device_t parent, cfdata_t match, void *aux) 274 { 275 struct acpi_attach_args *aa = aux; 276 277 return acpi_compatible_match(aa, compat_data); 278 } 279 280 /* 281 * valz_acpi_attach: 282 * 283 * Autoconfiguration `attach' routine. 284 */ 285 static void 286 valz_acpi_attach(device_t parent, device_t self, void *aux) 287 { 288 struct valz_acpi_softc *sc = device_private(self); 289 struct acpi_attach_args *aa = aux; 290 ACPI_STATUS rv; 291 292 aprint_naive(": Toshiba VALZ\n"); 293 aprint_normal(": Toshiba VALZ\n"); 294 295 sc->sc_node = aa->aa_node; 296 sc->sc_dev = self; 297 298 /* enable valz notify */ 299 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, METHOD_HCI_ENABLE, 300 NULL, NULL); 301 if (ACPI_FAILURE(rv)) { 302 aprint_error("Cannot enable VALZ.\n"); 303 } else { 304 (void)acpi_register_notify(sc->sc_node, 305 valz_acpi_notify_handler); 306 } 307 } 308 309 /* 310 * valz_acpi_notify_handler: 311 * 312 * Notify handler. 313 */ 314 static void 315 valz_acpi_notify_handler(ACPI_HANDLE handle, uint32_t notify, void *context) 316 { 317 struct valz_acpi_softc *sc; 318 device_t self = context; 319 320 sc = device_private(self); 321 322 switch (notify) { 323 case ACPI_NOTIFY_ValzHotkeyPressed: 324 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, valz_acpi_event, sc); 325 break; 326 327 case ACPI_NOTIFY_ValzLidClosed: 328 /* Lid closed */ 329 break; 330 331 case ACPI_NOTIFY_ValzKbdBLChanges: 332 /* Keyboard backlight mode changed */ 333 break; 334 335 default: 336 aprint_debug_dev(sc->sc_dev, 337 "unknown notify 0x%02X\n", notify); 338 break; 339 } 340 } 341 342 /* 343 * valz_acpi_event: 344 * 345 * Check hotkey event and do it, if event occur. 346 */ 347 static void 348 valz_acpi_event(void *arg) 349 { 350 struct valz_acpi_softc *sc = arg; 351 ACPI_STATUS rv; 352 uint32_t value, result; 353 354 for (;;) { 355 rv = valz_acpi_hci_get(sc, HCI_GET, HCI_SYSTEM_EVENT_FIFO, 356 &value, &result); 357 if (ACPI_SUCCESS(rv) && result == 0) { 358 switch (value) { 359 case FN_F9_PRESS: 360 valz_acpi_touchpad_toggle(sc); 361 break; 362 case FN_TAB_PRESS: 363 valz_acpi_lcd_backlight_toggle(sc); 364 break; 365 366 default: 367 /* Many unused buttons */ 368 aprint_debug("Pressed: 0x%x\n", value); 369 break; 370 } 371 } 372 if (ACPI_FAILURE(rv) || result == HCI_NOT_SUPPORTED || 373 result == HCI_FIFO_EMPTY) 374 break; 375 } 376 } 377 378 /* 379 * HCI/SCI operation 380 */ 381 static ACPI_STATUS 382 hci_op(struct valz_acpi_softc *sc, uint32_t *input, uint32_t *output) 383 { 384 ACPI_STATUS rv; 385 ACPI_OBJECT Arg[HCI_WORDS]; 386 ACPI_OBJECT_LIST ArgList; 387 ACPI_OBJECT *param, *PrtElement; 388 ACPI_BUFFER buf; 389 int i; 390 391 for (i = 0; i < HCI_WORDS; i++) { 392 Arg[i].Type = ACPI_TYPE_INTEGER; 393 Arg[i].Integer.Value = 0; 394 } 395 396 for (i = 0; i < HCI_WORDS; i++) { 397 Arg[i].Integer.Value = input[i]; 398 } 399 400 ArgList.Count = HCI_WORDS; 401 ArgList.Pointer = Arg; 402 403 buf.Pointer = NULL; 404 buf.Length = ACPI_ALLOCATE_BUFFER; 405 406 rv = AcpiEvaluateObjectTyped(sc->sc_node->ad_handle, 407 METHOD_HCI, &ArgList, &buf, ACPI_TYPE_PACKAGE); 408 if (ACPI_FAILURE(rv)) { 409 aprint_error_dev(sc->sc_dev, "failed to evaluate GHCI: %s\n", 410 AcpiFormatException(rv)); 411 return rv; 412 } 413 414 param = (ACPI_OBJECT *)buf.Pointer; 415 PrtElement = param->Package.Elements; 416 for (i = 0; i < HCI_WORDS; i++) { 417 output[i] = PrtElement[i].Type == ACPI_TYPE_INTEGER ? 418 PrtElement[i].Integer.Value : 0; 419 } 420 421 ACPI_FREE(buf.Pointer); 422 423 return rv; 424 } 425 426 /* 427 * valz_acpi_hci_get: 428 * 429 * Get value via "GHCI" Method. 430 */ 431 static ACPI_STATUS 432 valz_acpi_hci_get(struct valz_acpi_softc *sc, uint32_t function, 433 uint32_t reg, uint32_t *value, uint32_t *result) 434 { 435 ACPI_STATUS rv; 436 437 uint32_t input[HCI_WORDS]; 438 uint32_t output[HCI_WORDS]; 439 440 input[HCI_REG_AX] = function; 441 input[HCI_REG_BX] = reg; 442 input[HCI_REG_CX] = 0; 443 input[HCI_REG_DX] = 0; 444 input[HCI_REG_SI] = 0; 445 input[HCI_REG_DI] = 0; 446 447 rv = hci_op(sc, input, output); 448 449 *result = output[HCI_REG_AX]; 450 *value = output[HCI_REG_CX]; 451 452 return rv; 453 } 454 455 /* 456 * valz_acpi_hci_set: 457 * 458 * Set value via "GHCI" Method. 459 */ 460 static ACPI_STATUS 461 valz_acpi_hci_set(struct valz_acpi_softc *sc, uint32_t function, 462 uint32_t reg, uint32_t value, uint32_t *result) 463 { 464 ACPI_STATUS rv; 465 466 uint32_t input[HCI_WORDS]; 467 uint32_t output[HCI_WORDS]; 468 469 input[HCI_REG_AX] = function; 470 input[HCI_REG_BX] = reg; 471 input[HCI_REG_CX] = value; 472 input[HCI_REG_DX] = 0; 473 input[HCI_REG_SI] = 0; 474 input[HCI_REG_DI] = 0; 475 476 rv = hci_op(sc, input, output); 477 478 *result = output[HCI_REG_AX]; 479 480 return rv; 481 } 482 483 /* 484 * Open SCI 485 */ 486 static ACPI_STATUS 487 sci_open(struct valz_acpi_softc *sc) 488 { 489 ACPI_STATUS rv; 490 uint32_t result; 491 492 rv = valz_acpi_hci_set(sc, SCI_OPEN, 0, 0, &result); 493 if (ACPI_FAILURE(rv)) { 494 aprint_error("SCI: ACPI set error\n"); 495 } else { 496 switch (result) { 497 case SCI_OPENCLOSE_OK: 498 aprint_debug("Opening SCI\n"); 499 break; 500 case SCI_ALREADY_OPEN: 501 aprint_error("SCI already open\n"); 502 break; 503 case SCI_NOT_SUPPORTED: 504 aprint_error("SCI is not supported\n"); 505 break; 506 case SCI_NOT_PRESENT: 507 aprint_error("SCI is not present\n"); 508 break; 509 default: 510 aprint_error("SCI: undefined behavior\n"); 511 break; 512 } 513 } 514 515 return rv; 516 } 517 518 /* 519 * Close SCI 520 */ 521 static ACPI_STATUS 522 sci_close(struct valz_acpi_softc *sc) 523 { 524 ACPI_STATUS rv; 525 uint32_t result; 526 527 rv = valz_acpi_hci_set(sc, SCI_CLOSE, 0, 0, &result); 528 if (ACPI_FAILURE(rv)) { 529 aprint_error("SCI: ACPI set error\n"); 530 } else { 531 switch (result) { 532 case SCI_OPENCLOSE_OK: 533 aprint_debug("Closing SCI\n"); 534 break; 535 case SCI_NOT_OPEN: 536 aprint_error("SCI is not opened\n"); 537 break; 538 case SCI_NOT_SUPPORTED: 539 aprint_error("SCI is not supported\n"); 540 break; 541 case SCI_NOT_PRESENT: 542 aprint_error("SCI is not present\n"); 543 break; 544 default: 545 aprint_error("SCI: undefined behavior\n"); 546 break; 547 } 548 } 549 550 return rv; 551 } 552 553 /* 554 * Enable/disable touchpad and trackpoint with HCI_ENABLE/HCI_DISABLE 555 */ 556 static ACPI_STATUS 557 valz_acpi_touchpad_toggle(struct valz_acpi_softc *sc) 558 { 559 ACPI_STATUS rv; 560 uint32_t result, status, value; 561 562 rv = sci_open(sc); 563 if (ACPI_FAILURE(rv)) 564 aprint_error_dev(sc->sc_dev, 565 "Cannot open SCI: %s\n", 566 AcpiFormatException(rv)); 567 568 rv = valz_acpi_hci_get(sc, SCI_GET, SCI_TOUCHPAD, &value, &result); 569 if (ACPI_FAILURE(rv)) 570 aprint_error_dev(sc->sc_dev, 571 "Cannot get SCI touchpad status: %s\n", 572 AcpiFormatException(rv)); 573 574 switch (value) { 575 case HCI_ENABLE: 576 status = HCI_DISABLE; 577 break; 578 case HCI_DISABLE: 579 status = HCI_ENABLE; 580 break; 581 default: 582 status = HCI_ENABLE; 583 break; 584 } 585 586 rv = valz_acpi_hci_set(sc, SCI_SET, SCI_TOUCHPAD, status, &result); 587 if (ACPI_FAILURE(rv)) 588 aprint_error_dev(sc->sc_dev, 589 "Cannot set SCI touchpad status: %s\n", 590 AcpiFormatException(rv)); 591 592 rv = sci_close(sc); 593 if (ACPI_FAILURE(rv)) 594 aprint_error_dev(sc->sc_dev, 595 "Cannot close SCI: %s\n", 596 AcpiFormatException(rv)); 597 598 return rv; 599 } 600 601 /* 602 * Enable/disable LCD backlight with HCI_ENABLE/HCI_DISABLE 603 */ 604 static ACPI_STATUS 605 valz_acpi_lcd_backlight_toggle(struct valz_acpi_softc *sc) 606 { 607 ACPI_STATUS rv; 608 uint32_t result, status, value; 609 610 rv = valz_acpi_hci_get(sc, HCI_GET, HCI_LCD_BACKLIGHT, &value, &result); 611 if (ACPI_FAILURE(rv)) 612 aprint_error_dev(sc->sc_dev, 613 "Cannot get HCI LCD backlight status: %s\n", 614 AcpiFormatException(rv)); 615 616 switch (value) { 617 case HCI_ON: 618 status = HCI_OFF; 619 break; 620 case HCI_OFF: 621 status = HCI_ON; 622 break; 623 default: 624 status = HCI_ON; 625 break; 626 } 627 628 rv = valz_acpi_hci_set(sc, HCI_SET, HCI_LCD_BACKLIGHT, status, &result); 629 if (ACPI_FAILURE(rv)) 630 aprint_error_dev(sc->sc_dev, 631 "Cannot set HCI LCD backlight status: %s\n", 632 AcpiFormatException(rv)); 633 634 return rv; 635 } 636