1 /* $NetBSD: valz_acpi.c,v 1.7 2015/10/05 15:57:50 christos 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.7 2015/10/05 15:57:50 christos 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 char * const valz_acpi_hids[] = { 235 "TOS6208", 236 NULL 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 if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE) 278 return (0); 279 280 return (acpi_match_hid(aa->aa_node->ad_devinfo, valz_acpi_hids)); 281 } 282 283 /* 284 * valz_acpi_attach: 285 * 286 * Autoconfiguration `attach' routine. 287 */ 288 static void 289 valz_acpi_attach(device_t parent, device_t self, void *aux) 290 { 291 struct valz_acpi_softc *sc = device_private(self); 292 struct acpi_attach_args *aa = aux; 293 ACPI_STATUS rv; 294 295 aprint_naive(": Toshiba VALZ\n"); 296 aprint_normal(": Toshiba VALZ\n"); 297 298 sc->sc_node = aa->aa_node; 299 sc->sc_dev = self; 300 301 /* enable valz notify */ 302 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, METHOD_HCI_ENABLE, 303 NULL, NULL); 304 if (ACPI_FAILURE(rv)) { 305 aprint_error("Cannot enable VALZ.\n"); 306 } else { 307 (void)acpi_register_notify(sc->sc_node, 308 valz_acpi_notify_handler); 309 } 310 } 311 312 /* 313 * valz_acpi_notify_handler: 314 * 315 * Notify handler. 316 */ 317 static void 318 valz_acpi_notify_handler(ACPI_HANDLE handle, uint32_t notify, void *context) 319 { 320 struct valz_acpi_softc *sc; 321 device_t self = context; 322 323 sc = device_private(self); 324 325 switch (notify) { 326 case ACPI_NOTIFY_ValzHotkeyPressed: 327 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, valz_acpi_event, sc); 328 break; 329 330 case ACPI_NOTIFY_ValzLidClosed: 331 /* Lid closed */ 332 break; 333 334 case ACPI_NOTIFY_ValzKbdBLChanges: 335 /* Keyboard backlight mode changed */ 336 break; 337 338 default: 339 aprint_error_dev(sc->sc_dev, 340 "unknown notify 0x%02X\n", notify); 341 break; 342 } 343 } 344 345 /* 346 * valz_acpi_event: 347 * 348 * Check hotkey event and do it, if event occur. 349 */ 350 static void 351 valz_acpi_event(void *arg) 352 { 353 struct valz_acpi_softc *sc = arg; 354 ACPI_STATUS rv; 355 uint32_t value, result; 356 357 for (;;) { 358 rv = valz_acpi_hci_get(sc, HCI_GET, HCI_SYSTEM_EVENT_FIFO, 359 &value, &result); 360 if (ACPI_SUCCESS(rv) && result == 0) { 361 switch (value) { 362 case FN_F9_PRESS: 363 valz_acpi_touchpad_toggle(sc); 364 break; 365 case FN_TAB_PRESS: 366 valz_acpi_lcd_backlight_toggle(sc); 367 break; 368 369 default: 370 /* Many unused buttons */ 371 aprint_debug("Pressed: 0x%x\n", value); 372 break; 373 } 374 } 375 if (ACPI_FAILURE(rv) || result == HCI_NOT_SUPPORTED || 376 result == HCI_FIFO_EMPTY) 377 break; 378 } 379 } 380 381 /* 382 * HCI/SCI operation 383 */ 384 static ACPI_STATUS 385 hci_op(struct valz_acpi_softc *sc, uint32_t *input, uint32_t *output) 386 { 387 ACPI_STATUS rv; 388 ACPI_OBJECT Arg[HCI_WORDS]; 389 ACPI_OBJECT_LIST ArgList; 390 ACPI_OBJECT *param, *PrtElement; 391 ACPI_BUFFER buf; 392 int i; 393 394 for (i = 0; i < HCI_WORDS; i++) { 395 Arg[i].Type = ACPI_TYPE_INTEGER; 396 Arg[i].Integer.Value = 0; 397 } 398 399 for (i = 0; i < HCI_WORDS; i++) { 400 Arg[i].Integer.Value = input[i]; 401 } 402 403 ArgList.Count = HCI_WORDS; 404 ArgList.Pointer = Arg; 405 406 buf.Pointer = NULL; 407 buf.Length = ACPI_ALLOCATE_BUFFER; 408 409 rv = AcpiEvaluateObjectTyped(sc->sc_node->ad_handle, 410 METHOD_HCI, &ArgList, &buf, ACPI_TYPE_PACKAGE); 411 if (ACPI_FAILURE(rv)) { 412 aprint_error_dev(sc->sc_dev, "failed to evaluate GHCI: %s\n", 413 AcpiFormatException(rv)); 414 return rv; 415 } 416 417 param = (ACPI_OBJECT *)buf.Pointer; 418 PrtElement = param->Package.Elements; 419 for (i = 0; i < HCI_WORDS; i++) { 420 output[i] = PrtElement[i].Type == ACPI_TYPE_INTEGER ? 421 PrtElement[i].Integer.Value : 0; 422 } 423 424 ACPI_FREE(buf.Pointer); 425 426 return rv; 427 } 428 429 /* 430 * valz_acpi_hci_get: 431 * 432 * Get value via "GHCI" Method. 433 */ 434 static ACPI_STATUS 435 valz_acpi_hci_get(struct valz_acpi_softc *sc, uint32_t function, 436 uint32_t reg, uint32_t *value, uint32_t *result) 437 { 438 ACPI_STATUS rv; 439 440 uint32_t input[HCI_WORDS]; 441 uint32_t output[HCI_WORDS]; 442 443 input[HCI_REG_AX] = function; 444 input[HCI_REG_BX] = reg; 445 input[HCI_REG_CX] = 0; 446 input[HCI_REG_DX] = 0; 447 input[HCI_REG_SI] = 0; 448 input[HCI_REG_DI] = 0; 449 450 rv = hci_op(sc, input, output); 451 452 *result = output[HCI_REG_AX]; 453 *value = output[HCI_REG_CX]; 454 455 return rv; 456 } 457 458 /* 459 * valz_acpi_hci_set: 460 * 461 * Set value via "GHCI" Method. 462 */ 463 static ACPI_STATUS 464 valz_acpi_hci_set(struct valz_acpi_softc *sc, uint32_t function, 465 uint32_t reg, uint32_t value, uint32_t *result) 466 { 467 ACPI_STATUS rv; 468 469 uint32_t input[HCI_WORDS]; 470 uint32_t output[HCI_WORDS]; 471 472 input[HCI_REG_AX] = function; 473 input[HCI_REG_BX] = reg; 474 input[HCI_REG_CX] = value; 475 input[HCI_REG_DX] = 0; 476 input[HCI_REG_SI] = 0; 477 input[HCI_REG_DI] = 0; 478 479 rv = hci_op(sc, input, output); 480 481 *result = output[HCI_REG_AX]; 482 483 return rv; 484 } 485 486 /* 487 * Open SCI 488 */ 489 static ACPI_STATUS 490 sci_open(struct valz_acpi_softc *sc) 491 { 492 ACPI_STATUS rv; 493 uint32_t result; 494 495 rv = valz_acpi_hci_set(sc, SCI_OPEN, 0, 0, &result); 496 if (ACPI_FAILURE(rv)) { 497 aprint_error("SCI: ACPI set error\n"); 498 } else { 499 switch (result) { 500 case SCI_OPENCLOSE_OK: 501 aprint_debug("Opening SCI\n"); 502 break; 503 case SCI_ALREADY_OPEN: 504 aprint_error("SCI already open\n"); 505 break; 506 case SCI_NOT_SUPPORTED: 507 aprint_error("SCI is not supported\n"); 508 break; 509 case SCI_NOT_PRESENT: 510 aprint_error("SCI is not present\n"); 511 break; 512 default: 513 aprint_error("SCI: undefined behavior\n"); 514 break; 515 } 516 } 517 518 return rv; 519 } 520 521 /* 522 * Close SCI 523 */ 524 static ACPI_STATUS 525 sci_close(struct valz_acpi_softc *sc) 526 { 527 ACPI_STATUS rv; 528 uint32_t result; 529 530 rv = valz_acpi_hci_set(sc, SCI_CLOSE, 0, 0, &result); 531 if (ACPI_FAILURE(rv)) { 532 aprint_error("SCI: ACPI set error\n"); 533 } else { 534 switch (result) { 535 case SCI_OPENCLOSE_OK: 536 aprint_debug("Closing SCI\n"); 537 break; 538 case SCI_NOT_OPEN: 539 aprint_error("SCI is not opened\n"); 540 break; 541 case SCI_NOT_SUPPORTED: 542 aprint_error("SCI is not supported\n"); 543 break; 544 case SCI_NOT_PRESENT: 545 aprint_error("SCI is not present\n"); 546 break; 547 default: 548 aprint_error("SCI: undefined behavior\n"); 549 break; 550 } 551 } 552 553 return rv; 554 } 555 556 /* 557 * Enable/disable touchpad and trackpoint with HCI_ENABLE/HCI_DISABLE 558 */ 559 static ACPI_STATUS 560 valz_acpi_touchpad_toggle(struct valz_acpi_softc *sc) 561 { 562 ACPI_STATUS rv; 563 uint32_t result, status, value; 564 565 rv = sci_open(sc); 566 if (ACPI_FAILURE(rv)) 567 aprint_error_dev(sc->sc_dev, 568 "Cannot open SCI: %s\n", 569 AcpiFormatException(rv)); 570 571 rv = valz_acpi_hci_get(sc, SCI_GET, SCI_TOUCHPAD, &value, &result); 572 if (ACPI_FAILURE(rv)) 573 aprint_error_dev(sc->sc_dev, 574 "Cannot get SCI touchpad status: %s\n", 575 AcpiFormatException(rv)); 576 577 switch (value) { 578 case HCI_ENABLE: 579 status = HCI_DISABLE; 580 break; 581 case HCI_DISABLE: 582 status = HCI_ENABLE; 583 break; 584 default: 585 status = HCI_ENABLE; 586 break; 587 } 588 589 rv = valz_acpi_hci_set(sc, SCI_SET, SCI_TOUCHPAD, status, &result); 590 if (ACPI_FAILURE(rv)) 591 aprint_error_dev(sc->sc_dev, 592 "Cannot set SCI touchpad status: %s\n", 593 AcpiFormatException(rv)); 594 595 rv = sci_close(sc); 596 if (ACPI_FAILURE(rv)) 597 aprint_error_dev(sc->sc_dev, 598 "Cannot close SCI: %s\n", 599 AcpiFormatException(rv)); 600 601 return rv; 602 } 603 604 /* 605 * Enable/disable LCD backlight with HCI_ENABLE/HCI_DISABLE 606 */ 607 static ACPI_STATUS 608 valz_acpi_lcd_backlight_toggle(struct valz_acpi_softc *sc) 609 { 610 ACPI_STATUS rv; 611 uint32_t result, status, value; 612 613 rv = valz_acpi_hci_get(sc, HCI_GET, HCI_LCD_BACKLIGHT, &value, &result); 614 if (ACPI_FAILURE(rv)) 615 aprint_error_dev(sc->sc_dev, 616 "Cannot get HCI LCD backlight status: %s\n", 617 AcpiFormatException(rv)); 618 619 switch (value) { 620 case HCI_ON: 621 status = HCI_OFF; 622 break; 623 case HCI_OFF: 624 status = HCI_ON; 625 break; 626 default: 627 status = HCI_ON; 628 break; 629 } 630 631 rv = valz_acpi_hci_set(sc, HCI_SET, HCI_LCD_BACKLIGHT, status, &result); 632 if (ACPI_FAILURE(rv)) 633 aprint_error_dev(sc->sc_dev, 634 "Cannot set HCI LCD backlight status: %s\n", 635 AcpiFormatException(rv)); 636 637 return rv; 638 } 639