Module Name: src Committed By: jruoho Date: Thu Apr 8 17:32:30 UTC 2010
Modified Files: src/sys/arch/amd64/conf: GENERIC src/sys/arch/i386/conf: GENERIC src/sys/dev/acpi/wmi: files.wmi Added Files: src/sys/dev/acpi/wmi: wmi_hp.c Log Message: Add WMI mappings for HP laptops. Requested by ceg...@. Thanks to apb@ and cegger@ for initial testing. XXX: This conflicts with hpqlb(4). Someone with the suitable hardware needs to complete the list of hotkeys before -- and if -- this can replace hpqlb(4). For now, the driver was left uncommented in the GENERICs. To generate a diff of this commit: cvs rdiff -u -r1.273 -r1.274 src/sys/arch/amd64/conf/GENERIC cvs rdiff -u -r1.976 -r1.977 src/sys/arch/i386/conf/GENERIC cvs rdiff -u -r1.2 -r1.3 src/sys/dev/acpi/wmi/files.wmi cvs rdiff -u -r0 -r1.1 src/sys/dev/acpi/wmi/wmi_hp.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/conf/GENERIC diff -u src/sys/arch/amd64/conf/GENERIC:1.273 src/sys/arch/amd64/conf/GENERIC:1.274 --- src/sys/arch/amd64/conf/GENERIC:1.273 Thu Apr 8 09:45:17 2010 +++ src/sys/arch/amd64/conf/GENERIC Thu Apr 8 17:32:30 2010 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.273 2010/04/08 09:45:17 jruoho Exp $ +# $NetBSD: GENERIC,v 1.274 2010/04/08 17:32:30 jruoho Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.273 $" +#ident "GENERIC-$Revision: 1.274 $" maxusers 64 # estimated number of users @@ -305,6 +305,7 @@ wb* at acpi? # Winbond W83L518D SD/MMC reader sdmmc* at wb? # SD/MMC bus wmidell* at acpiwmibus? # Dell WMI mappings +#wmihp* at acpiwmibus? # HP WMI mappings #apm0 at mainbus0 # Advanced power management Index: src/sys/arch/i386/conf/GENERIC diff -u src/sys/arch/i386/conf/GENERIC:1.976 src/sys/arch/i386/conf/GENERIC:1.977 --- src/sys/arch/i386/conf/GENERIC:1.976 Thu Apr 8 09:45:17 2010 +++ src/sys/arch/i386/conf/GENERIC Thu Apr 8 17:32:30 2010 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.976 2010/04/08 09:45:17 jruoho Exp $ +# $NetBSD: GENERIC,v 1.977 2010/04/08 17:32:30 jruoho Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.976 $" +#ident "GENERIC-$Revision: 1.977 $" maxusers 64 # estimated number of users @@ -381,6 +381,7 @@ wb* at acpi? # Winbond W83L518D SD/MMC reader sdmmc* at wb? # SD/MMC bus wmidell* at acpiwmibus? # Dell WMI mappings +#wmihp* at acpiwmibus? # HP WMI mappings wss* at acpi? # NeoMagic 256AV in wss mode ym* at acpi? # Yamaha OPL3-SA[23] audio Index: src/sys/dev/acpi/wmi/files.wmi diff -u src/sys/dev/acpi/wmi/files.wmi:1.2 src/sys/dev/acpi/wmi/files.wmi:1.3 --- src/sys/dev/acpi/wmi/files.wmi:1.2 Thu Apr 8 12:14:19 2010 +++ src/sys/dev/acpi/wmi/files.wmi Thu Apr 8 17:32:30 2010 @@ -1,4 +1,4 @@ -# $NetBSD: files.wmi,v 1.2 2010/04/08 12:14:19 jruoho Exp $ +# $NetBSD: files.wmi,v 1.3 2010/04/08 17:32:30 jruoho Exp $ define acpiwmibus { } @@ -11,3 +11,8 @@ device wmidell: sysmon_power attach wmidell at acpiwmibus file dev/acpi/wmi/wmi_dell.c wmidell + +# HP WMI mappings +device wmihp: sysmon_envsys +attach wmihp at acpiwmibus +file dev/acpi/wmi/wmi_hp.c wmihp Added files: Index: src/sys/dev/acpi/wmi/wmi_hp.c diff -u /dev/null src/sys/dev/acpi/wmi/wmi_hp.c:1.1 --- /dev/null Thu Apr 8 17:32:31 2010 +++ src/sys/dev/acpi/wmi/wmi_hp.c Thu Apr 8 17:32:30 2010 @@ -0,0 +1,528 @@ +/* $NetBSD: wmi_hp.c,v 1.1 2010/04/08 17:32:30 jruoho Exp $ */ + +/*- + * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*- + * Copyright (c) 2009 Michael Gmelin <free...@grem.de> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: wmi_hp.c,v 1.1 2010/04/08 17:32:30 jruoho Exp $"); + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/kmem.h> + +#include <dev/acpi/acpireg.h> +#include <dev/acpi/acpivar.h> +#include <dev/acpi/wmi/wmi_acpivar.h> + +#include <dev/sysmon/sysmonvar.h> + +#define _COMPONENT ACPI_RESOURCE_COMPONENT +ACPI_MODULE_NAME ("wmi_hp") + +#define WMI_HP_METHOD_ARG_READ 0x01 +#define WMI_HP_METHOD_ARG_WRITE 0x02 +#define WMI_HP_METHOD_ARG_WRITE_SIZE 0x04 +#define WMI_HP_METHOD_ARG_MAGIC 0x55434553 +#define WMI_HP_METHOD_ARG_SIZE 0x05 * sizeof(uint32_t) + +#define WMI_HP_METHOD_CMD_DISPLAY 0x01 +#define WMI_HP_METHOD_CMD_HDDTEMP 0x02 +#define WMI_HP_METHOD_CMD_ALS 0x03 +#define WMI_HP_METHOD_CMD_DOCK 0x04 +#define WMI_HP_METHOD_CMD_SWITCH 0x05 +#define WMI_HP_METHOD_CMD_HOTKEY 0x0C + +#define WMI_HP_EVENT_DOCK 0x01 +#define WMI_HP_EVENT_HOTKEY 0x04 +#define WMI_HP_EVENT_SWITCH 0x05 +/* WMI_HP_EVENT_UNKNOWN 0xXX */ + +#define WMI_HP_HOTKEY_BRIGHTNESS_UP 0x02 +#define WMI_HP_HOTKEY_BRIGHTNESS_DOWN 0x03 +/* WMI_HP_HOTKEY_UNKNOWN 0xXX */ + +#define WMI_HP_SWITCH_WLAN 0x01 +#define WMI_HP_SWITCH_BT 0x02 +#define WMI_HP_SWITCH_WWAN 0x04 + +#define WMI_HP_SWITCH_ARG_WLAN_OFF 0x100 +#define WMI_HP_SWITCH_ARG_WLAN_ON 0x101 +#define WMI_HP_SWITCH_ARG_BT_OFF 0x200 +#define WMI_HP_SWITCH_ARG_BT_ON 0x202 +#define WMI_HP_SWITCH_ARG_WWAN_OFF 0x400 +#define WMI_HP_SWITCH_ARG_WWAN_ON 0x404 + +#define WMI_HP_SWITCH_MASK_WLAN_ONAIR __BIT(8) +#define WMI_HP_SWITCH_MASK_WLAN_ENABLED __BIT(9) +#define WMI_HP_SWITCH_MASK_WLAN_RADIO __BIT(11) +#define WMI_HP_SWITCH_MASK_BT_ONAIR __BIT(16) +#define WMI_HP_SWITCH_MASK_BT_ENABLED __BIT(17) +#define WMI_HP_SWITCH_MASK_BT_RADIO __BIT(19) +#define WMI_HP_SWITCH_MASK_WWAN_ONAIR __BIT(24) +#define WMI_HP_SWITCH_MASK_WWAN_ENABLED __BIT(25) +#define WMI_HP_SWITCH_MASK_WWAN_RADIO __BIT(27) + +#define WMI_HP_GUID_EVENT "95F24279-4D7B-4334-9387-ACCDC67EF61C" +#define WMI_HP_GUID_METHOD "5FB7F034-2C63-45E9-BE91-3D44E2C707E4" + +#define WMI_HP_SENSOR_WLAN 0 +#define WMI_HP_SENSOR_BT 1 +#define WMI_HP_SENSOR_WWAN 2 +#define WMI_HP_SENSOR_COUNT 3 +#define WMI_HP_SENSOR_SIZE 3 * sizeof(envsys_data_t) + +struct wmi_hp_softc { + device_t sc_dev; + device_t sc_parent; + struct sysmon_envsys *sc_sme; + envsys_data_t *sc_sensor; + uint32_t *sc_arg; + uint32_t sc_val; +}; + +static int wmi_hp_match(device_t, cfdata_t, void *); +static void wmi_hp_attach(device_t, device_t, void *); +static int wmi_hp_detach(device_t, int); +static bool wmi_hp_suspend(device_t, const pmf_qual_t *); +static bool wmi_hp_resume(device_t, const pmf_qual_t *); +static void wmi_hp_notify_handler(ACPI_HANDLE, uint32_t, void *); +static void wmi_hp_hotkey(void *); +static bool wmi_hp_method(struct wmi_hp_softc *); +static bool wmi_hp_method_read(struct wmi_hp_softc *, uint8_t); + +#if 0 +static bool wmi_hp_method_write(struct wmi_hp_softc *, uint8_t, uint32_t); +#endif + +static void wmi_hp_sensor_init(struct wmi_hp_softc *); +static void wmi_hp_sensor_update(void *); + +CFATTACH_DECL_NEW(wmihp, sizeof(struct wmi_hp_softc), + wmi_hp_match, wmi_hp_attach, wmi_hp_detach, NULL); + +static int +wmi_hp_match(device_t parent, cfdata_t match, void *aux) +{ + return acpi_wmi_guid_match(parent, WMI_HP_GUID_METHOD); +} + +static void +wmi_hp_attach(device_t parent, device_t self, void *aux) +{ + struct wmi_hp_softc *sc = device_private(self); + ACPI_STATUS rv = AE_ERROR; + + sc->sc_dev = self; + sc->sc_parent = parent; + + sc->sc_sme = NULL; + sc->sc_sensor = NULL; + + sc->sc_arg = kmem_alloc(WMI_HP_METHOD_ARG_SIZE, KM_SLEEP); + + if (sc->sc_arg == NULL) + return; + + aprint_naive("\n"); + aprint_normal(": HP WMI mappings\n"); + + (void)pmf_device_register(sc->sc_dev, wmi_hp_suspend, wmi_hp_resume); + + if (acpi_wmi_guid_match(parent, WMI_HP_GUID_EVENT) != 0) + rv = acpi_wmi_event_register(parent, wmi_hp_notify_handler); + + if (ACPI_FAILURE(rv)) + return; + + sc->sc_sensor = kmem_alloc(WMI_HP_SENSOR_SIZE, KM_SLEEP); + + if (sc->sc_sensor == NULL) + return; + + wmi_hp_sensor_init(sc); +} + +static int +wmi_hp_detach(device_t self, int flags) +{ + struct wmi_hp_softc *sc = device_private(self); + device_t parent = sc->sc_parent; + + (void)acpi_wmi_event_deregister(parent); + + if (sc->sc_sme != NULL) + sysmon_envsys_unregister(sc->sc_sme); + + if (sc->sc_sensor != NULL) + kmem_free(sc->sc_sensor, WMI_HP_SENSOR_SIZE); + + if (sc->sc_arg != NULL) + kmem_free(sc->sc_arg, WMI_HP_METHOD_ARG_SIZE); + + pmf_device_deregister(self); + + return 0; +} + +static bool +wmi_hp_suspend(device_t self, const pmf_qual_t *qual) +{ + struct wmi_hp_softc *sc = device_private(self); + device_t parent = sc->sc_parent; + + if (sc->sc_sensor != NULL) + (void)acpi_wmi_event_deregister(parent); + + return true; +} + +static bool +wmi_hp_resume(device_t self, const pmf_qual_t *qual) +{ + struct wmi_hp_softc *sc = device_private(self); + device_t parent = sc->sc_parent; + + if (sc->sc_sensor != NULL) + (void)acpi_wmi_event_register(parent, wmi_hp_notify_handler); + + return true; +} + +static void +wmi_hp_notify_handler(ACPI_HANDLE hdl, uint32_t evt, void *aux) +{ + static const int handler = OSL_NOTIFY_HANDLER; + struct wmi_hp_softc *sc; + device_t self = aux; + ACPI_OBJECT *obj; + ACPI_BUFFER buf; + ACPI_STATUS rv; + uint32_t val; + + sc = device_private(self); + rv = acpi_wmi_event_get(sc->sc_parent, evt, &buf); + + if (ACPI_FAILURE(rv)) + goto out; + + obj = buf.Pointer; + + if (obj->Type != ACPI_TYPE_BUFFER) { + rv = AE_TYPE; + goto out; + } + + if (obj->Buffer.Length != 8) { + rv = AE_LIMIT; + goto out; + } + + val = *((uint8_t *)obj->Buffer.Pointer); + + if (val == 0x00) { + rv = AE_BAD_DATA; + goto out; + } + + switch (val) { + + case WMI_HP_EVENT_SWITCH: + rv = AcpiOsExecute(handler, wmi_hp_sensor_update, self); + break; + + case WMI_HP_EVENT_HOTKEY: + rv = AcpiOsExecute(handler, wmi_hp_hotkey, self); + break; + + case WMI_HP_EVENT_DOCK: /* FALLTHROUGH */ + + default: + aprint_debug_dev(sc->sc_dev, "unknown event 0x%02X\n", evt); + break; + } + +out: + if (buf.Pointer != NULL) + ACPI_FREE(buf.Pointer); + + if (ACPI_FAILURE(rv)) + aprint_error_dev(sc->sc_dev, "failed to get data for " + "event 0x%02X: %s\n", evt, AcpiFormatException(rv)); +} + +static void +wmi_hp_hotkey(void *aux) +{ + struct wmi_hp_softc *sc; + device_t self = aux; + + sc = device_private(self); + + if (wmi_hp_method_read(sc, WMI_HP_METHOD_CMD_HOTKEY) != true) + return; + + switch (sc->sc_val) { + + case WMI_HP_HOTKEY_BRIGHTNESS_UP: + pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_UP); + break; + + case WMI_HP_HOTKEY_BRIGHTNESS_DOWN: + pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_DOWN); + break; + + default: + aprint_debug_dev(self, "unknown hotkey 0x%02x\n", sc->sc_val); + break; + } +} + +static bool +wmi_hp_method(struct wmi_hp_softc *sc) +{ + ACPI_BUFFER ibuf, obuf; + ACPI_STATUS rv = AE_OK; + ACPI_OBJECT *obj; + uint32_t cmd, *val; + + cmd = sc->sc_arg[2]; + + KDASSERT(cmd != 0); + KDASSERT(sc->sc_arg[0] == WMI_HP_METHOD_ARG_MAGIC); + + ibuf.Pointer = sc->sc_arg; + ibuf.Length = WMI_HP_METHOD_ARG_SIZE; + + rv = acpi_wmi_method(sc->sc_parent, + WMI_HP_GUID_METHOD, 0, 3, &ibuf, &obuf); + + if (ACPI_FAILURE(rv)) + goto out; + + obj = obuf.Pointer; + + if (obj->Type != ACPI_TYPE_BUFFER) { + rv = AE_TYPE; + goto out; + } + + /* + * val[0] unknown + * val[1] error code + * val[2] return value + */ + val = (uint32_t *)obj->Buffer.Pointer; + + if (val[1] != 0) { + rv = AE_ERROR; + goto out; + } + + sc->sc_val = val[2]; + +out: + if (obuf.Pointer != NULL) + ACPI_FREE(obuf.Pointer); + + if (ACPI_FAILURE(rv)) { + aprint_debug_dev(sc->sc_dev, "failed to evaluate method " + "(cmd = 0x%02X): %s\n", cmd, AcpiFormatException(rv)); + return false; + } + + return true; +} + +static bool +wmi_hp_method_read(struct wmi_hp_softc *sc, uint8_t cmd) +{ + + sc->sc_arg[0] = WMI_HP_METHOD_ARG_MAGIC; + sc->sc_arg[1] = WMI_HP_METHOD_ARG_READ; + sc->sc_arg[2] = cmd; + sc->sc_arg[3] = 0; + sc->sc_arg[4] = 0; + + return wmi_hp_method(sc); +} + +#if 0 +static bool +wmi_hp_method_write(struct wmi_hp_softc *sc, uint8_t cmd, uint32_t val) +{ + + sc->sc_arg[0] = WMI_HP_METHOD_ARG_MAGIC; + sc->sc_arg[1] = WMI_HP_METHOD_ARG_WRITE; + sc->sc_arg[2] = cmd; + sc->sc_arg[3] = WMI_HP_METHOD_ARG_WRITE_SIZE; + sc->sc_arg[4] = val; + + return wmi_hp_method(sc); +} +#endif + +static void +wmi_hp_sensor_init(struct wmi_hp_softc *sc) +{ + int i, j, sensor[3]; + + const char desc[][ENVSYS_DESCLEN] = { + "wireless", "bluetooth", "mobile" + }; + + KDASSERT(sc->sc_sme == NULL); + KDASSERT(sc->sc_sensor != NULL); + + (void)memset(sc->sc_sensor, 0, WMI_HP_SENSOR_SIZE); + + if (wmi_hp_method_read(sc, WMI_HP_METHOD_CMD_SWITCH) != true) + return; + + sc->sc_sme = sysmon_envsys_create(); + + sensor[0] = WMI_HP_SWITCH_WLAN; + sensor[1] = WMI_HP_SWITCH_BT; + sensor[2] = WMI_HP_SWITCH_WWAN; + + CTASSERT(WMI_HP_SENSOR_WLAN == 0); + CTASSERT(WMI_HP_SENSOR_BT == 1); + CTASSERT(WMI_HP_SENSOR_WWAN == 2); + + for (i = j = 0; i < 3; i++) { + + if ((sc->sc_val & sensor[i]) == 0) + continue; + + (void)strlcpy(sc->sc_sensor[i].desc, desc[i], ENVSYS_DESCLEN); + + sc->sc_sensor[i].state = ENVSYS_SINVALID; + sc->sc_sensor[i].units = ENVSYS_INDICATOR; + + if (sysmon_envsys_sensor_attach(sc->sc_sme, + &sc->sc_sensor[i]) != 0) + goto fail; + + j++; + } + + if (j == 0) + goto fail; + + sc->sc_sme->sme_flags = SME_DISABLE_REFRESH; + sc->sc_sme->sme_name = device_xname(sc->sc_dev); + + if (sysmon_envsys_register(sc->sc_sme) != 0) + goto fail; + + wmi_hp_sensor_update(sc->sc_dev); + + return; + +fail: + aprint_debug_dev(sc->sc_dev, "failed to initialize sysmon\n"); + + sysmon_envsys_destroy(sc->sc_sme); + kmem_free(sc->sc_sensor, WMI_HP_SENSOR_SIZE); + + sc->sc_sme = NULL; + sc->sc_sensor = NULL; +} + +static void +wmi_hp_sensor_update(void *aux) +{ + struct wmi_hp_softc *sc; + device_t self = aux; + + sc = device_private(self); + + if (sc->sc_sme == NULL || sc->sc_sensor == NULL) + return; + + if (wmi_hp_method_read(sc, WMI_HP_METHOD_CMD_SWITCH) != true) { + sc->sc_sensor[WMI_HP_SENSOR_WLAN].state = ENVSYS_SINVALID; + sc->sc_sensor[WMI_HP_SENSOR_WWAN].state = ENVSYS_SINVALID; + sc->sc_sensor[WMI_HP_SENSOR_BT].state = ENVSYS_SINVALID; + return; + } + + if ((sc->sc_val & WMI_HP_SWITCH_WLAN) != 0) { + sc->sc_sensor[WMI_HP_SENSOR_WLAN].value_cur = 0; + + if ((sc->sc_val & WMI_HP_SWITCH_MASK_WLAN_ONAIR) != 0) + sc->sc_sensor[WMI_HP_SENSOR_WLAN].value_cur = 1; + + sc->sc_sensor[WMI_HP_SENSOR_WLAN].state = ENVSYS_SVALID; + } + + if ((sc->sc_val & WMI_HP_SWITCH_BT) != 0) { + sc->sc_sensor[WMI_HP_SENSOR_BT].value_cur = 0; + + if ((sc->sc_val & WMI_HP_SWITCH_MASK_BT_ONAIR) != 0) + sc->sc_sensor[WMI_HP_SENSOR_BT].value_cur = 1; + + sc->sc_sensor[WMI_HP_SENSOR_BT].state = ENVSYS_SVALID; + } + + if ((sc->sc_val & WMI_HP_SWITCH_WWAN) != 0) { + sc->sc_sensor[WMI_HP_SENSOR_WWAN].value_cur = 0; + + if ((sc->sc_val & WMI_HP_SWITCH_MASK_WWAN_ONAIR) != 0) + sc->sc_sensor[WMI_HP_SENSOR_WWAN].value_cur = 1; + + sc->sc_sensor[WMI_HP_SENSOR_WWAN].state = ENVSYS_SVALID; + } +}