valz_acpi.c revision 1.6
1/* $NetBSD: valz_acpi.c,v 1.6 2015/09/26 13:04:10 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.6 2015/09/26 13:04:10 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 88ACPI_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 229struct valz_acpi_softc { 230 device_t sc_dev; /* base device glue */ 231 struct acpi_devnode *sc_node; /* our ACPI devnode */ 232}; 233 234static const char * const valz_acpi_hids[] = { 235 "TOS6208", 236 NULL 237}; 238 239static int valz_acpi_match(device_t, cfdata_t, void *); 240static void valz_acpi_attach(device_t, device_t, void *); 241 242static void valz_acpi_event(void *); 243static 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 */ 250static ACPI_STATUS hci_op(struct valz_acpi_softc *, 251 uint32_t *, uint32_t *); 252static ACPI_STATUS valz_acpi_hci_get(struct valz_acpi_softc *, uint32_t, 253 uint32_t, uint32_t *, uint32_t *); 254static ACPI_STATUS valz_acpi_hci_set(struct valz_acpi_softc *, uint32_t, 255 uint32_t, uint32_t, uint32_t *); 256 257static ACPI_STATUS sci_open(struct valz_acpi_softc *); 258static ACPI_STATUS sci_close(struct valz_acpi_softc *); 259 260static ACPI_STATUS valz_acpi_touchpad_toggle(struct valz_acpi_softc *); 261static ACPI_STATUS valz_acpi_lcd_backlight_toggle( 262 struct valz_acpi_softc *sc); 263 264CFATTACH_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 */ 272static int 273valz_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 */ 288static void 289valz_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 */ 317static void 318valz_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 */ 350static void 351valz_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 */ 384static ACPI_STATUS 385hci_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 for (i = 0; i < HCI_WORDS; i++) { 418 output[i] = 0; 419 } 420 param = (ACPI_OBJECT *)buf.Pointer; 421 PrtElement = param->Package.Elements; 422 for (i = 0; i < HCI_WORDS; i++) { 423 if (PrtElement->Type == ACPI_TYPE_INTEGER) { 424 output[i] = PrtElement->Integer.Value; 425 PrtElement++; 426 } 427 } 428 429 ACPI_FREE(buf.Pointer); 430 431 return rv; 432} 433 434/* 435 * valz_acpi_hci_get: 436 * 437 * Get value via "GHCI" Method. 438 */ 439static ACPI_STATUS 440valz_acpi_hci_get(struct valz_acpi_softc *sc, uint32_t function, 441 uint32_t reg, uint32_t *value, uint32_t *result) 442{ 443 ACPI_STATUS rv; 444 445 uint32_t input[HCI_WORDS]; 446 uint32_t output[HCI_WORDS]; 447 448 input[HCI_REG_AX] = function; 449 input[HCI_REG_BX] = reg; 450 input[HCI_REG_CX] = 0; 451 input[HCI_REG_DX] = 0; 452 input[HCI_REG_SI] = 0; 453 input[HCI_REG_DI] = 0; 454 455 rv = hci_op(sc, input, output); 456 457 *result = output[HCI_REG_AX]; 458 *value = output[HCI_REG_CX]; 459 460 return rv; 461} 462 463/* 464 * valz_acpi_hci_set: 465 * 466 * Set value via "GHCI" Method. 467 */ 468static ACPI_STATUS 469valz_acpi_hci_set(struct valz_acpi_softc *sc, uint32_t function, 470 uint32_t reg, uint32_t value, uint32_t *result) 471{ 472 ACPI_STATUS rv; 473 474 uint32_t input[HCI_WORDS]; 475 uint32_t output[HCI_WORDS]; 476 477 input[HCI_REG_AX] = function; 478 input[HCI_REG_BX] = reg; 479 input[HCI_REG_CX] = value; 480 input[HCI_REG_DX] = 0; 481 input[HCI_REG_SI] = 0; 482 input[HCI_REG_DI] = 0; 483 484 rv = hci_op(sc, input, output); 485 486 *result = output[HCI_REG_AX]; 487 488 return rv; 489} 490 491/* 492 * Open SCI 493 */ 494static ACPI_STATUS 495sci_open(struct valz_acpi_softc *sc) 496{ 497 ACPI_STATUS rv; 498 uint32_t result; 499 500 rv = valz_acpi_hci_set(sc, SCI_OPEN, 0, 0, &result); 501 if (ACPI_FAILURE(rv)) { 502 aprint_error("SCI: ACPI set error\n"); 503 } else { 504 switch (result) { 505 case SCI_OPENCLOSE_OK: 506 aprint_debug("Opening SCI\n"); 507 break; 508 case SCI_ALREADY_OPEN: 509 aprint_error("SCI already open\n"); 510 break; 511 case SCI_NOT_SUPPORTED: 512 aprint_error("SCI is not supported\n"); 513 break; 514 case SCI_NOT_PRESENT: 515 aprint_error("SCI is not present\n"); 516 break; 517 default: 518 aprint_error("SCI: undefined behavior\n"); 519 break; 520 } 521 } 522 523 return rv; 524} 525 526/* 527 * Close SCI 528 */ 529static ACPI_STATUS 530sci_close(struct valz_acpi_softc *sc) 531{ 532 ACPI_STATUS rv; 533 uint32_t result; 534 535 rv = valz_acpi_hci_set(sc, SCI_CLOSE, 0, 0, &result); 536 if (ACPI_FAILURE(rv)) { 537 aprint_error("SCI: ACPI set error\n"); 538 } else { 539 switch (result) { 540 case SCI_OPENCLOSE_OK: 541 aprint_debug("Closing SCI\n"); 542 break; 543 case SCI_NOT_OPEN: 544 aprint_error("SCI is not opened\n"); 545 break; 546 case SCI_NOT_SUPPORTED: 547 aprint_error("SCI is not supported\n"); 548 break; 549 case SCI_NOT_PRESENT: 550 aprint_error("SCI is not present\n"); 551 break; 552 default: 553 aprint_error("SCI: undefined behavior\n"); 554 break; 555 } 556 } 557 558 return rv; 559} 560 561/* 562 * Enable/disable touchpad and trackpoint with HCI_ENABLE/HCI_DISABLE 563 */ 564static ACPI_STATUS 565valz_acpi_touchpad_toggle(struct valz_acpi_softc *sc) 566{ 567 ACPI_STATUS rv; 568 uint32_t result, status, value; 569 570 rv = sci_open(sc); 571 if (ACPI_FAILURE(rv)) 572 aprint_error_dev(sc->sc_dev, 573 "Cannot open SCI: %s\n", 574 AcpiFormatException(rv)); 575 576 rv = valz_acpi_hci_get(sc, SCI_GET, SCI_TOUCHPAD, &value, &result); 577 if (ACPI_FAILURE(rv)) 578 aprint_error_dev(sc->sc_dev, 579 "Cannot get SCI touchpad status: %s\n", 580 AcpiFormatException(rv)); 581 582 switch (value) { 583 case HCI_ENABLE: 584 status = HCI_DISABLE; 585 break; 586 case HCI_DISABLE: 587 status = HCI_ENABLE; 588 break; 589 default: 590 status = HCI_ENABLE; 591 break; 592 } 593 594 rv = valz_acpi_hci_set(sc, SCI_SET, SCI_TOUCHPAD, status, &result); 595 if (ACPI_FAILURE(rv)) 596 aprint_error_dev(sc->sc_dev, 597 "Cannot set SCI touchpad status: %s\n", 598 AcpiFormatException(rv)); 599 600 rv = sci_close(sc); 601 if (ACPI_FAILURE(rv)) 602 aprint_error_dev(sc->sc_dev, 603 "Cannot close SCI: %s\n", 604 AcpiFormatException(rv)); 605 606 return rv; 607} 608 609/* 610 * Enable/disable LCD backlight with HCI_ENABLE/HCI_DISABLE 611 */ 612static ACPI_STATUS 613valz_acpi_lcd_backlight_toggle(struct valz_acpi_softc *sc) 614{ 615 ACPI_STATUS rv; 616 uint32_t result, status, value; 617 618 rv = valz_acpi_hci_get(sc, HCI_GET, HCI_LCD_BACKLIGHT, &value, &result); 619 if (ACPI_FAILURE(rv)) 620 aprint_error_dev(sc->sc_dev, 621 "Cannot get HCI LCD backlight status: %s\n", 622 AcpiFormatException(rv)); 623 624 switch (value) { 625 case HCI_ON: 626 status = HCI_OFF; 627 break; 628 case HCI_OFF: 629 status = HCI_ON; 630 break; 631 default: 632 status = HCI_ON; 633 break; 634 } 635 636 rv = valz_acpi_hci_set(sc, HCI_SET, HCI_LCD_BACKLIGHT, status, &result); 637 if (ACPI_FAILURE(rv)) 638 aprint_error_dev(sc->sc_dev, 639 "Cannot set HCI LCD backlight status: %s\n", 640 AcpiFormatException(rv)); 641 642 return rv; 643} 644