acpi_panasonic.c revision 202771
1212700Sjkim/*- 2212700Sjkim * Copyright (c) 2003 OGAWA Takaya <t-ogawa@triaez.kaisei.org> 3212700Sjkim * Copyright (c) 2004 TAKAHASHI Yoshihiro <nyan@FreeBSD.org> 4212700Sjkim * All rights Reserved. 5212700Sjkim * 6212700Sjkim * Redistribution and use in source and binary forms, with or without 7212700Sjkim * modification, are permitted provided that the following conditions 8212700Sjkim * are met: 9212700Sjkim * 1. Redistributions of source code must retain the above copyright 10212700Sjkim * notice, this list of conditions and the following disclaimer. 11212700Sjkim * 2. Redistributions in binary form must reproduce the above copyright 12212700Sjkim * notice, this list of conditions and the following disclaimer in the 13212700Sjkim * documentation and/or other materials provided with the distribution. 14212700Sjkim * 15212700Sjkim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16212700Sjkim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17212700Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18212700Sjkim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19212700Sjkim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20212700Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21212700Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22212700Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23212700Sjkim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24212700Sjkim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25212700Sjkim * SUCH DAMAGE. 26212700Sjkim * 27212700Sjkim */ 28212700Sjkim 29212700Sjkim#include <sys/cdefs.h> 30212700Sjkim__FBSDID("$FreeBSD: head/sys/dev/acpi_support/acpi_panasonic.c 202771 2010-01-21 21:14:28Z jkim $"); 31212700Sjkim 32212700Sjkim#include "opt_acpi.h" 33212700Sjkim#include <sys/param.h> 34212700Sjkim#include <sys/kernel.h> 35212700Sjkim#include <sys/malloc.h> 36212700Sjkim#include <sys/module.h> 37212700Sjkim#include <sys/bus.h> 38212700Sjkim#include <sys/power.h> 39212700Sjkim 40212700Sjkim#include <contrib/dev/acpica/include/acpi.h> 41212700Sjkim 42212700Sjkim#include <dev/acpica/acpivar.h> 43212700Sjkim 44212700Sjkim#define _COMPONENT ACPI_OEM 45212700SjkimACPI_MODULE_NAME("Panasonic") 46212700Sjkim 47212700Sjkim/* Debug */ 48212700Sjkim#undef ACPI_PANASONIC_DEBUG 49212700Sjkim 50212700Sjkim/* Operations */ 51212700Sjkim#define HKEY_SET 0 52212700Sjkim#define HKEY_GET 1 53212700Sjkim 54212700Sjkim/* Functions */ 55212700Sjkim#define HKEY_REG_LCD_BRIGHTNESS_MAX_AC 0x02 56212700Sjkim#define HKEY_REG_LCD_BRIGHTNESS_MIN_AC 0x03 57212700Sjkim#define HKEY_REG_LCD_BRIGHTNESS_AC 0x04 58212700Sjkim#define HKEY_REG_LCD_BRIGHTNESS_MAX_DC 0x05 59212700Sjkim#define HKEY_REG_LCD_BRIGHTNESS_MIN_DC 0x06 60212700Sjkim#define HKEY_REG_LCD_BRIGHTNESS_DC 0x07 61212700Sjkim#define HKEY_REG_SOUND_MUTE 0x08 62212700Sjkim 63212700Sjkim/* Field definitions */ 64212700Sjkim#define HKEY_LCD_BRIGHTNESS_BITS 4 65212700Sjkim#define HKEY_LCD_BRIGHTNESS_DIV ((1 << HKEY_LCD_BRIGHTNESS_BITS) - 1) 66212700Sjkim 67212700Sjkimstruct acpi_panasonic_softc { 68212700Sjkim device_t dev; 69212700Sjkim ACPI_HANDLE handle; 70212700Sjkim 71212700Sjkim struct sysctl_ctx_list sysctl_ctx; 72212700Sjkim struct sysctl_oid *sysctl_tree; 73212700Sjkim 74212700Sjkim eventhandler_tag power_evh; 75212700Sjkim}; 76212700Sjkim 77212700Sjkim/* Prototype for HKEY functions for getting/setting a value. */ 78212700Sjkimtypedef int hkey_fn_t(ACPI_HANDLE, int, UINT32 *); 79212700Sjkim 80212700Sjkimstatic int acpi_panasonic_probe(device_t dev); 81212700Sjkimstatic int acpi_panasonic_attach(device_t dev); 82212700Sjkimstatic int acpi_panasonic_detach(device_t dev); 83212700Sjkimstatic int acpi_panasonic_shutdown(device_t dev); 84212700Sjkimstatic int acpi_panasonic_sysctl(SYSCTL_HANDLER_ARGS); 85212700Sjkimstatic UINT64 acpi_panasonic_sinf(ACPI_HANDLE h, UINT64 index); 86212700Sjkimstatic void acpi_panasonic_sset(ACPI_HANDLE h, UINT64 index, 87212700Sjkim UINT64 val); 88212700Sjkimstatic int acpi_panasonic_hkey_event(struct acpi_panasonic_softc *sc, 89212700Sjkim ACPI_HANDLE h, UINT32 *arg); 90212700Sjkimstatic void acpi_panasonic_hkey_action(struct acpi_panasonic_softc *sc, 91212700Sjkim ACPI_HANDLE h, UINT32 key); 92212700Sjkimstatic void acpi_panasonic_notify(ACPI_HANDLE h, UINT32 notify, 93212700Sjkim void *context); 94212700Sjkimstatic void acpi_panasonic_power_profile(void *arg); 95212700Sjkim 96212700Sjkimstatic hkey_fn_t hkey_lcd_brightness_max; 97212700Sjkimstatic hkey_fn_t hkey_lcd_brightness_min; 98212700Sjkimstatic hkey_fn_t hkey_lcd_brightness; 99212700Sjkimstatic hkey_fn_t hkey_sound_mute; 100212700SjkimACPI_SERIAL_DECL(panasonic, "ACPI Panasonic extras"); 101212700Sjkim 102212700Sjkim/* Table of sysctl names and HKEY functions to call. */ 103212700Sjkimstatic struct { 104212700Sjkim char *name; 105212700Sjkim hkey_fn_t *handler; 106212700Sjkim} sysctl_table[] = { 107212700Sjkim /* name, handler */ 108212700Sjkim {"lcd_brightness_max", hkey_lcd_brightness_max}, 109212700Sjkim {"lcd_brightness_min", hkey_lcd_brightness_min}, 110212700Sjkim {"lcd_brightness", hkey_lcd_brightness}, 111212700Sjkim {"sound_mute", hkey_sound_mute}, 112212700Sjkim {NULL, NULL} 113212700Sjkim}; 114212700Sjkim 115212700Sjkimstatic device_method_t acpi_panasonic_methods[] = { 116212700Sjkim DEVMETHOD(device_probe, acpi_panasonic_probe), 117212700Sjkim DEVMETHOD(device_attach, acpi_panasonic_attach), 118212700Sjkim DEVMETHOD(device_detach, acpi_panasonic_detach), 119212700Sjkim DEVMETHOD(device_shutdown, acpi_panasonic_shutdown), 120212700Sjkim 121212700Sjkim {0, 0} 122212700Sjkim}; 123212700Sjkim 124212700Sjkimstatic driver_t acpi_panasonic_driver = { 125212700Sjkim "acpi_panasonic", 126212700Sjkim acpi_panasonic_methods, 127212700Sjkim sizeof(struct acpi_panasonic_softc), 128212700Sjkim}; 129212700Sjkim 130212700Sjkimstatic devclass_t acpi_panasonic_devclass; 131212700Sjkim 132212700SjkimDRIVER_MODULE(acpi_panasonic, acpi, acpi_panasonic_driver, 133212700Sjkim acpi_panasonic_devclass, 0, 0); 134212700SjkimMODULE_DEPEND(acpi_panasonic, acpi, 1, 1, 1); 135212700Sjkim 136212700Sjkimstatic int 137212700Sjkimacpi_panasonic_probe(device_t dev) 138212700Sjkim{ 139212700Sjkim static char *mat_ids[] = { "MAT0019", NULL }; 140212700Sjkim 141212700Sjkim if (acpi_disabled("panasonic") || 142212700Sjkim ACPI_ID_PROBE(device_get_parent(dev), dev, mat_ids) == NULL || 143212700Sjkim device_get_unit(dev) != 0) 144212700Sjkim return (ENXIO); 145212700Sjkim 146212700Sjkim device_set_desc(dev, "Panasonic Notebook Hotkeys"); 147212700Sjkim return (0); 148212700Sjkim} 149212700Sjkim 150212700Sjkimstatic int 151212700Sjkimacpi_panasonic_attach(device_t dev) 152212700Sjkim{ 153212700Sjkim struct acpi_panasonic_softc *sc; 154212700Sjkim struct acpi_softc *acpi_sc; 155212700Sjkim ACPI_STATUS status; 156212700Sjkim int i; 157212700Sjkim 158212700Sjkim sc = device_get_softc(dev); 159212700Sjkim sc->dev = dev; 160212700Sjkim sc->handle = acpi_get_handle(dev); 161212700Sjkim 162212700Sjkim acpi_sc = acpi_device_get_parent_softc(dev); 163212700Sjkim 164212700Sjkim /* Build sysctl tree */ 165212700Sjkim sysctl_ctx_init(&sc->sysctl_ctx); 166212700Sjkim sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, 167212700Sjkim SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, 168212700Sjkim "panasonic", CTLFLAG_RD, 0, ""); 169212700Sjkim for (i = 0; sysctl_table[i].name != NULL; i++) { 170212700Sjkim SYSCTL_ADD_PROC(&sc->sysctl_ctx, 171212700Sjkim SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, 172212700Sjkim sysctl_table[i].name, 173212700Sjkim CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, 174212700Sjkim sc, i, acpi_panasonic_sysctl, "I", ""); 175212700Sjkim } 176212700Sjkim 177212700Sjkim#if 0 178212700Sjkim /* Activate hotkeys */ 179212700Sjkim status = AcpiEvaluateObject(sc->handle, "", NULL, NULL); 180212700Sjkim if (ACPI_FAILURE(status)) { 181212700Sjkim device_printf(dev, "enable FN keys failed\n"); 182212700Sjkim sysctl_ctx_free(&sc->sysctl_ctx); 183212700Sjkim return (ENXIO); 184212700Sjkim } 185212700Sjkim#endif 186212700Sjkim 187212700Sjkim /* Handle notifies */ 188212700Sjkim status = AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, 189212700Sjkim acpi_panasonic_notify, sc); 190212700Sjkim if (ACPI_FAILURE(status)) { 191212700Sjkim device_printf(dev, "couldn't install notify handler - %s\n", 192212700Sjkim AcpiFormatException(status)); 193212700Sjkim sysctl_ctx_free(&sc->sysctl_ctx); 194212700Sjkim return (ENXIO); 195212700Sjkim } 196212700Sjkim 197212700Sjkim /* Install power profile event handler */ 198212700Sjkim sc->power_evh = EVENTHANDLER_REGISTER(power_profile_change, 199212700Sjkim acpi_panasonic_power_profile, sc->handle, 0); 200212700Sjkim 201212700Sjkim return (0); 202212700Sjkim} 203212700Sjkim 204212700Sjkimstatic int 205212700Sjkimacpi_panasonic_detach(device_t dev) 206212700Sjkim{ 207212700Sjkim struct acpi_panasonic_softc *sc; 208212700Sjkim 209212700Sjkim sc = device_get_softc(dev); 210212700Sjkim 211212700Sjkim /* Remove power profile event handler */ 212212700Sjkim EVENTHANDLER_DEREGISTER(power_profile_change, sc->power_evh); 213212700Sjkim 214212700Sjkim /* Remove notify handler */ 215212700Sjkim AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, 216212700Sjkim acpi_panasonic_notify); 217212700Sjkim 218212700Sjkim /* Free sysctl tree */ 219212700Sjkim sysctl_ctx_free(&sc->sysctl_ctx); 220212700Sjkim 221212700Sjkim return (0); 222212700Sjkim} 223212700Sjkim 224212700Sjkimstatic int 225212700Sjkimacpi_panasonic_shutdown(device_t dev) 226212700Sjkim{ 227212700Sjkim struct acpi_panasonic_softc *sc; 228212700Sjkim int mute; 229212700Sjkim 230212700Sjkim /* Mute the main audio during reboot to prevent static burst to speaker. */ 231212700Sjkim sc = device_get_softc(dev); 232212700Sjkim mute = 1; 233212700Sjkim hkey_sound_mute(sc->handle, HKEY_SET, &mute); 234212700Sjkim return (0); 235212700Sjkim} 236212700Sjkim 237212700Sjkimstatic int 238212700Sjkimacpi_panasonic_sysctl(SYSCTL_HANDLER_ARGS) 239212700Sjkim{ 240212700Sjkim struct acpi_panasonic_softc *sc; 241212700Sjkim UINT32 arg; 242212700Sjkim int function, error; 243212700Sjkim hkey_fn_t *handler; 244212700Sjkim 245212700Sjkim sc = (struct acpi_panasonic_softc *)oidp->oid_arg1; 246212700Sjkim function = oidp->oid_arg2; 247212700Sjkim handler = sysctl_table[function].handler; 248212700Sjkim 249212700Sjkim /* Get the current value from the appropriate function. */ 250212700Sjkim ACPI_SERIAL_BEGIN(panasonic); 251212700Sjkim error = handler(sc->handle, HKEY_GET, &arg); 252212700Sjkim if (error != 0) 253212700Sjkim goto out; 254212700Sjkim 255212700Sjkim /* Send the current value to the user and return if no new value. */ 256212700Sjkim error = sysctl_handle_int(oidp, &arg, 0, req); 257212700Sjkim if (error != 0 || req->newptr == NULL) 258212700Sjkim goto out; 259212700Sjkim 260212700Sjkim /* Set the new value via the appropriate function. */ 261212700Sjkim error = handler(sc->handle, HKEY_SET, &arg); 262212700Sjkim 263212700Sjkimout: 264212700Sjkim ACPI_SERIAL_END(panasonic); 265212700Sjkim return (error); 266212700Sjkim} 267212700Sjkim 268212700Sjkimstatic UINT64 269212700Sjkimacpi_panasonic_sinf(ACPI_HANDLE h, UINT64 index) 270212700Sjkim{ 271212700Sjkim ACPI_BUFFER buf; 272212700Sjkim ACPI_OBJECT *res; 273212700Sjkim UINT64 ret; 274212700Sjkim 275212700Sjkim ACPI_SERIAL_ASSERT(panasonic); 276212700Sjkim ret = -1; 277212700Sjkim buf.Length = ACPI_ALLOCATE_BUFFER; 278212700Sjkim buf.Pointer = NULL; 279212700Sjkim AcpiEvaluateObject(h, "SINF", NULL, &buf); 280212700Sjkim res = (ACPI_OBJECT *)buf.Pointer; 281212700Sjkim if (res->Type == ACPI_TYPE_PACKAGE) 282212700Sjkim ret = res->Package.Elements[index].Integer.Value; 283212700Sjkim AcpiOsFree(buf.Pointer); 284212700Sjkim 285212700Sjkim return (ret); 286212700Sjkim} 287212700Sjkim 288212700Sjkimstatic void 289212700Sjkimacpi_panasonic_sset(ACPI_HANDLE h, UINT64 index, UINT64 val) 290212700Sjkim{ 291212700Sjkim ACPI_OBJECT_LIST args; 292212700Sjkim ACPI_OBJECT obj[2]; 293212700Sjkim 294212700Sjkim ACPI_SERIAL_ASSERT(panasonic); 295212700Sjkim obj[0].Type = ACPI_TYPE_INTEGER; 296212700Sjkim obj[0].Integer.Value = index; 297212700Sjkim obj[1].Type = ACPI_TYPE_INTEGER; 298212700Sjkim obj[1].Integer.Value = val; 299212700Sjkim args.Count = 2; 300212700Sjkim args.Pointer = obj; 301212700Sjkim AcpiEvaluateObject(h, "SSET", &args, NULL); 302212700Sjkim} 303212700Sjkim 304212700Sjkimstatic int 305212700Sjkimhkey_lcd_brightness_max(ACPI_HANDLE h, int op, UINT32 *val) 306212700Sjkim{ 307212700Sjkim int reg; 308212700Sjkim 309212700Sjkim ACPI_SERIAL_ASSERT(panasonic); 310212700Sjkim reg = (power_profile_get_state() == POWER_PROFILE_PERFORMANCE) ? 311212700Sjkim HKEY_REG_LCD_BRIGHTNESS_MAX_AC : HKEY_REG_LCD_BRIGHTNESS_MAX_DC; 312212700Sjkim 313212700Sjkim switch (op) { 314212700Sjkim case HKEY_SET: 315212700Sjkim return (EPERM); 316212700Sjkim break; 317212700Sjkim case HKEY_GET: 318212700Sjkim *val = acpi_panasonic_sinf(h, reg); 319212700Sjkim break; 320212700Sjkim } 321212700Sjkim 322212700Sjkim return (0); 323212700Sjkim} 324212700Sjkim 325212700Sjkimstatic int 326212700Sjkimhkey_lcd_brightness_min(ACPI_HANDLE h, int op, UINT32 *val) 327212700Sjkim{ 328212700Sjkim int reg; 329212700Sjkim 330212700Sjkim ACPI_SERIAL_ASSERT(panasonic); 331212700Sjkim reg = (power_profile_get_state() == POWER_PROFILE_PERFORMANCE) ? 332212700Sjkim HKEY_REG_LCD_BRIGHTNESS_MIN_AC : HKEY_REG_LCD_BRIGHTNESS_MIN_DC; 333212700Sjkim 334212700Sjkim switch (op) { 335212700Sjkim case HKEY_SET: 336212700Sjkim return (EPERM); 337212700Sjkim break; 338212700Sjkim case HKEY_GET: 339212700Sjkim *val = acpi_panasonic_sinf(h, reg); 340212700Sjkim break; 341212700Sjkim } 342212700Sjkim 343212700Sjkim return (0); 344212700Sjkim} 345212700Sjkim 346212700Sjkimstatic int 347212700Sjkimhkey_lcd_brightness(ACPI_HANDLE h, int op, UINT32 *val) 348212700Sjkim{ 349212700Sjkim int reg; 350212700Sjkim UINT32 max, min; 351212700Sjkim 352212700Sjkim reg = (power_profile_get_state() == POWER_PROFILE_PERFORMANCE) ? 353212700Sjkim HKEY_REG_LCD_BRIGHTNESS_AC : HKEY_REG_LCD_BRIGHTNESS_DC; 354212700Sjkim 355212700Sjkim ACPI_SERIAL_ASSERT(panasonic); 356212700Sjkim switch (op) { 357212700Sjkim case HKEY_SET: 358212700Sjkim hkey_lcd_brightness_max(h, HKEY_GET, &max); 359212700Sjkim hkey_lcd_brightness_min(h, HKEY_GET, &min); 360212700Sjkim if (*val < min || *val > max) 361212700Sjkim return (EINVAL); 362212700Sjkim acpi_panasonic_sset(h, reg, *val); 363212700Sjkim break; 364212700Sjkim case HKEY_GET: 365212700Sjkim *val = acpi_panasonic_sinf(h, reg); 366212700Sjkim break; 367212700Sjkim } 368212700Sjkim 369212700Sjkim return (0); 370212700Sjkim} 371212700Sjkim 372212700Sjkimstatic int 373212700Sjkimhkey_sound_mute(ACPI_HANDLE h, int op, UINT32 *val) 374212700Sjkim{ 375212700Sjkim 376212700Sjkim ACPI_SERIAL_ASSERT(panasonic); 377212700Sjkim switch (op) { 378212700Sjkim case HKEY_SET: 379212700Sjkim if (*val != 0 && *val != 1) 380212700Sjkim return (EINVAL); 381212700Sjkim acpi_panasonic_sset(h, HKEY_REG_SOUND_MUTE, *val); 382212700Sjkim break; 383212700Sjkim case HKEY_GET: 384212700Sjkim *val = acpi_panasonic_sinf(h, HKEY_REG_SOUND_MUTE); 385212700Sjkim break; 386212700Sjkim } 387212700Sjkim 388212700Sjkim return (0); 389212700Sjkim} 390212700Sjkim 391212700Sjkimstatic int 392212700Sjkimacpi_panasonic_hkey_event(struct acpi_panasonic_softc *sc, ACPI_HANDLE h, 393212700Sjkim UINT32 *arg) 394212700Sjkim{ 395212700Sjkim ACPI_BUFFER buf; 396212700Sjkim ACPI_OBJECT *res; 397212700Sjkim UINT64 val; 398212700Sjkim int status; 399212700Sjkim 400212700Sjkim ACPI_SERIAL_ASSERT(panasonic); 401212700Sjkim status = ENXIO; 402212700Sjkim 403212700Sjkim buf.Length = ACPI_ALLOCATE_BUFFER; 404212700Sjkim buf.Pointer = NULL; 405212700Sjkim AcpiEvaluateObject(h, "HINF", NULL, &buf); 406212700Sjkim res = (ACPI_OBJECT *)buf.Pointer; 407212700Sjkim if (res->Type != ACPI_TYPE_INTEGER) { 408212700Sjkim device_printf(sc->dev, "HINF returned non-integer\n"); 409212700Sjkim goto end; 410212700Sjkim } 411212700Sjkim val = res->Integer.Value; 412212700Sjkim#ifdef ACPI_PANASONIC_DEBUG 413212700Sjkim device_printf(sc->dev, "%s button Fn+F%d\n", 414212700Sjkim (val & 0x80) ? "Pressed" : "Released", 415212700Sjkim (int)(val & 0x7f)); 416212700Sjkim#endif 417212700Sjkim if ((val & 0x7f) > 0 && (val & 0x7f) < 11) { 418212700Sjkim *arg = val; 419212700Sjkim status = 0; 420212700Sjkim } 421212700Sjkimend: 422212700Sjkim if (buf.Pointer) 423212700Sjkim AcpiOsFree(buf.Pointer); 424212700Sjkim 425212700Sjkim return (status); 426212700Sjkim} 427212700Sjkim 428212700Sjkimstatic void 429212700Sjkimacpi_panasonic_hkey_action(struct acpi_panasonic_softc *sc, ACPI_HANDLE h, 430212700Sjkim UINT32 key) 431212700Sjkim{ 432212700Sjkim struct acpi_softc *acpi_sc; 433212700Sjkim int arg, max, min; 434212700Sjkim 435212700Sjkim acpi_sc = acpi_device_get_parent_softc(sc->dev); 436212700Sjkim 437212700Sjkim ACPI_SERIAL_ASSERT(panasonic); 438212700Sjkim switch (key) { 439212700Sjkim case 1: 440212700Sjkim /* Decrease LCD brightness. */ 441212700Sjkim hkey_lcd_brightness_max(h, HKEY_GET, &max); 442212700Sjkim hkey_lcd_brightness_min(h, HKEY_GET, &min); 443212700Sjkim hkey_lcd_brightness(h, HKEY_GET, &arg); 444212700Sjkim arg -= max / HKEY_LCD_BRIGHTNESS_DIV; 445212700Sjkim if (arg < min) 446212700Sjkim arg = min; 447212700Sjkim else if (arg > max) 448212700Sjkim arg = max; 449212700Sjkim hkey_lcd_brightness(h, HKEY_SET, &arg); 450212700Sjkim break; 451212700Sjkim case 2: 452212700Sjkim /* Increase LCD brightness. */ 453212700Sjkim hkey_lcd_brightness_max(h, HKEY_GET, &max); 454212700Sjkim hkey_lcd_brightness_min(h, HKEY_GET, &min); 455212700Sjkim hkey_lcd_brightness(h, HKEY_GET, &arg); 456212700Sjkim arg += max / HKEY_LCD_BRIGHTNESS_DIV; 457212700Sjkim if (arg < min) 458212700Sjkim arg = min; 459212700Sjkim else if (arg > max) 460212700Sjkim arg = max; 461212700Sjkim hkey_lcd_brightness(h, HKEY_SET, &arg); 462212700Sjkim break; 463212700Sjkim case 4: 464212700Sjkim /* Toggle sound mute. */ 465212700Sjkim hkey_sound_mute(h, HKEY_GET, &arg); 466212700Sjkim if (arg) 467212700Sjkim arg = 0; 468212700Sjkim else 469212700Sjkim arg = 1; 470212700Sjkim hkey_sound_mute(h, HKEY_SET, &arg); 471212700Sjkim break; 472212700Sjkim case 7: 473212700Sjkim /* Suspend. */ 474212700Sjkim acpi_event_sleep_button_sleep(acpi_sc); 475212700Sjkim break; 476212700Sjkim } 477212700Sjkim} 478212700Sjkim 479212700Sjkimstatic void 480212700Sjkimacpi_panasonic_notify(ACPI_HANDLE h, UINT32 notify, void *context) 481212700Sjkim{ 482212700Sjkim struct acpi_panasonic_softc *sc; 483212700Sjkim UINT32 key = 0; 484212700Sjkim 485212700Sjkim sc = (struct acpi_panasonic_softc *)context; 486212700Sjkim 487212700Sjkim switch (notify) { 488212700Sjkim case 0x80: 489212700Sjkim ACPI_SERIAL_BEGIN(panasonic); 490212700Sjkim if (acpi_panasonic_hkey_event(sc, h, &key) == 0) { 491212700Sjkim acpi_panasonic_hkey_action(sc, h, key); 492212700Sjkim acpi_UserNotify("Panasonic", h, (uint8_t)key); 493212700Sjkim } 494212700Sjkim ACPI_SERIAL_END(panasonic); 495212700Sjkim break; 496212700Sjkim default: 497212700Sjkim device_printf(sc->dev, "unknown notify: %#x\n", notify); 498212700Sjkim break; 499212700Sjkim } 500212700Sjkim} 501212700Sjkim 502212700Sjkimstatic void 503212700Sjkimacpi_panasonic_power_profile(void *arg) 504212700Sjkim{ 505212700Sjkim ACPI_HANDLE handle; 506212700Sjkim UINT32 brightness; 507212700Sjkim 508212700Sjkim handle = (ACPI_HANDLE)arg; 509212700Sjkim 510212700Sjkim /* Reset current brightness according to new power state. */ 511212700Sjkim ACPI_SERIAL_BEGIN(panasonic); 512212700Sjkim hkey_lcd_brightness(handle, HKEY_GET, &brightness); 513212700Sjkim hkey_lcd_brightness(handle, HKEY_SET, &brightness); 514212700Sjkim ACPI_SERIAL_END(panasonic); 515212700Sjkim} 516212700Sjkim