Sun May 30 11:24:11 2021 UTC ()
thinkpad(4): Fix evaluation of MHKA on version 2 devices.

Need to pass an argument.


(riastradh)
diff -r1.52 -r1.53 src/sys/dev/acpi/thinkpad_acpi.c

cvs diff -r1.52 -r1.53 src/sys/dev/acpi/thinkpad_acpi.c (switch to unified diff)

--- src/sys/dev/acpi/thinkpad_acpi.c 2021/05/29 16:49:57 1.52
+++ src/sys/dev/acpi/thinkpad_acpi.c 2021/05/30 11:24:10 1.53
@@ -1,957 +1,1003 @@ @@ -1,957 +1,1003 @@
1/* $NetBSD: thinkpad_acpi.c,v 1.52 2021/05/29 16:49:57 riastradh Exp $ */ 1/* $NetBSD: thinkpad_acpi.c,v 1.53 2021/05/30 11:24:10 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: thinkpad_acpi.c,v 1.52 2021/05/29 16:49:57 riastradh Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: thinkpad_acpi.c,v 1.53 2021/05/30 11:24:10 riastradh Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/device.h> 33#include <sys/device.h>
34#include <sys/module.h> 34#include <sys/module.h>
35#include <sys/sdt.h> 35#include <sys/sdt.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37 37
38#include <dev/acpi/acpireg.h> 38#include <dev/acpi/acpireg.h>
39#include <dev/acpi/acpivar.h> 39#include <dev/acpi/acpivar.h>
40#include <dev/acpi/acpi_ecvar.h> 40#include <dev/acpi/acpi_ecvar.h>
41#include <dev/acpi/acpi_power.h> 41#include <dev/acpi/acpi_power.h>
42 42
43#include <dev/isa/isareg.h> 43#include <dev/isa/isareg.h>
44 44
45#define _COMPONENT ACPI_RESOURCE_COMPONENT 45#define _COMPONENT ACPI_RESOURCE_COMPONENT
46ACPI_MODULE_NAME ("thinkpad_acpi") 46ACPI_MODULE_NAME ("thinkpad_acpi")
47 47
48#define THINKPAD_NTEMPSENSORS 8 48#define THINKPAD_NTEMPSENSORS 8
49#define THINKPAD_NFANSENSORS 1 49#define THINKPAD_NFANSENSORS 1
50#define THINKPAD_NSENSORS (THINKPAD_NTEMPSENSORS + THINKPAD_NFANSENSORS) 50#define THINKPAD_NSENSORS (THINKPAD_NTEMPSENSORS + THINKPAD_NFANSENSORS)
51 51
52typedef struct thinkpad_softc { 52typedef struct thinkpad_softc {
53 device_t sc_dev; 53 device_t sc_dev;
54 device_t sc_ecdev; 54 device_t sc_ecdev;
55 struct acpi_devnode *sc_node; 55 struct acpi_devnode *sc_node;
56 ACPI_HANDLE sc_powhdl; 56 ACPI_HANDLE sc_powhdl;
57 ACPI_HANDLE sc_cmoshdl; 57 ACPI_HANDLE sc_cmoshdl;
 58 ACPI_INTEGER sc_ver;
58 59
59#define TP_PSW_SLEEP 0 /* FnF4 */ 60#define TP_PSW_SLEEP 0 /* FnF4 */
60#define TP_PSW_HIBERNATE 1 /* FnF12 */ 61#define TP_PSW_HIBERNATE 1 /* FnF12 */
61#define TP_PSW_DISPLAY_CYCLE 2 /* FnF7 */ 62#define TP_PSW_DISPLAY_CYCLE 2 /* FnF7 */
62#define TP_PSW_LOCK_SCREEN 3 /* FnF2 */ 63#define TP_PSW_LOCK_SCREEN 3 /* FnF2 */
63#define TP_PSW_BATTERY_INFO 4 /* FnF3 */ 64#define TP_PSW_BATTERY_INFO 4 /* FnF3 */
64#define TP_PSW_EJECT_BUTTON 5 /* FnF9 */ 65#define TP_PSW_EJECT_BUTTON 5 /* FnF9 */
65#define TP_PSW_ZOOM_BUTTON 6 /* FnSPACE */ 66#define TP_PSW_ZOOM_BUTTON 6 /* FnSPACE */
66#define TP_PSW_VENDOR_BUTTON 7 /* ThinkVantage */ 67#define TP_PSW_VENDOR_BUTTON 7 /* ThinkVantage */
67#define TP_PSW_FNF1_BUTTON 8 /* FnF1 */ 68#define TP_PSW_FNF1_BUTTON 8 /* FnF1 */
68#define TP_PSW_WIRELESS_BUTTON 9 /* FnF5 */ 69#define TP_PSW_WIRELESS_BUTTON 9 /* FnF5 */
69#define TP_PSW_WWAN_BUTTON 10 /* FnF6 */ 70#define TP_PSW_WWAN_BUTTON 10 /* FnF6 */
70#define TP_PSW_POINTER_BUTTON 11 /* FnF8 */ 71#define TP_PSW_POINTER_BUTTON 11 /* FnF8 */
71#define TP_PSW_FNF10_BUTTON 12 /* FnF10 */ 72#define TP_PSW_FNF10_BUTTON 12 /* FnF10 */
72#define TP_PSW_FNF11_BUTTON 13 /* FnF11 */ 73#define TP_PSW_FNF11_BUTTON 13 /* FnF11 */
73#define TP_PSW_BRIGHTNESS_UP 14 74#define TP_PSW_BRIGHTNESS_UP 14
74#define TP_PSW_BRIGHTNESS_DOWN 15 75#define TP_PSW_BRIGHTNESS_DOWN 15
75#define TP_PSW_THINKLIGHT 16 76#define TP_PSW_THINKLIGHT 16
76#define TP_PSW_VOLUME_UP 17 77#define TP_PSW_VOLUME_UP 17
77#define TP_PSW_VOLUME_DOWN 18 78#define TP_PSW_VOLUME_DOWN 18
78#define TP_PSW_VOLUME_MUTE 19 79#define TP_PSW_VOLUME_MUTE 19
79#define TP_PSW_STAR_BUTTON 20 80#define TP_PSW_STAR_BUTTON 20
80#define TP_PSW_SCISSORS_BUTTON 21 81#define TP_PSW_SCISSORS_BUTTON 21
81#define TP_PSW_BLUETOOTH_BUTTON 22 82#define TP_PSW_BLUETOOTH_BUTTON 22
82#define TP_PSW_KEYBOARD_BUTTON 23 83#define TP_PSW_KEYBOARD_BUTTON 23
83#define TP_PSW_LAST 24 84#define TP_PSW_LAST 24
84 85
85 struct sysmon_pswitch sc_smpsw[TP_PSW_LAST]; 86 struct sysmon_pswitch sc_smpsw[TP_PSW_LAST];
86 bool sc_smpsw_valid; 87 bool sc_smpsw_valid;
87 88
88 struct sysmon_envsys *sc_sme; 89 struct sysmon_envsys *sc_sme;
89 envsys_data_t sc_sensor[THINKPAD_NSENSORS]; 90 envsys_data_t sc_sensor[THINKPAD_NSENSORS];
90 91
91 int sc_display_state; 92 int sc_display_state;
92} thinkpad_softc_t; 93} thinkpad_softc_t;
93 94
94/* Hotkey events */ 95/* Hotkey events */
95#define THINKPAD_NOTIFY_FnF1 0x001 96#define THINKPAD_NOTIFY_FnF1 0x001
96#define THINKPAD_NOTIFY_LockScreen 0x002 97#define THINKPAD_NOTIFY_LockScreen 0x002
97#define THINKPAD_NOTIFY_BatteryInfo 0x003 98#define THINKPAD_NOTIFY_BatteryInfo 0x003
98#define THINKPAD_NOTIFY_SleepButton 0x004 99#define THINKPAD_NOTIFY_SleepButton 0x004
99#define THINKPAD_NOTIFY_WirelessSwitch 0x005 100#define THINKPAD_NOTIFY_WirelessSwitch 0x005
100#define THINKPAD_NOTIFY_wWANSwitch 0x006 101#define THINKPAD_NOTIFY_wWANSwitch 0x006
101#define THINKPAD_NOTIFY_DisplayCycle 0x007 102#define THINKPAD_NOTIFY_DisplayCycle 0x007
102#define THINKPAD_NOTIFY_PointerSwitch 0x008 103#define THINKPAD_NOTIFY_PointerSwitch 0x008
103#define THINKPAD_NOTIFY_EjectButton 0x009 104#define THINKPAD_NOTIFY_EjectButton 0x009
104#define THINKPAD_NOTIFY_FnF10 0x00a /* XXX: Not seen on T61 */ 105#define THINKPAD_NOTIFY_FnF10 0x00a /* XXX: Not seen on T61 */
105#define THINKPAD_NOTIFY_FnF11 0x00b 106#define THINKPAD_NOTIFY_FnF11 0x00b
106#define THINKPAD_NOTIFY_HibernateButton 0x00c 107#define THINKPAD_NOTIFY_HibernateButton 0x00c
107#define THINKPAD_NOTIFY_BrightnessUp 0x010 108#define THINKPAD_NOTIFY_BrightnessUp 0x010
108#define THINKPAD_NOTIFY_BrightnessDown 0x011 109#define THINKPAD_NOTIFY_BrightnessDown 0x011
109#define THINKPAD_NOTIFY_ThinkLight 0x012 110#define THINKPAD_NOTIFY_ThinkLight 0x012
110#define THINKPAD_NOTIFY_Zoom 0x014 111#define THINKPAD_NOTIFY_Zoom 0x014
111#define THINKPAD_NOTIFY_VolumeUp 0x015 /* XXX: Not seen on T61 */ 112#define THINKPAD_NOTIFY_VolumeUp 0x015 /* XXX: Not seen on T61 */
112#define THINKPAD_NOTIFY_VolumeDown 0x016 /* XXX: Not seen on T61 */ 113#define THINKPAD_NOTIFY_VolumeDown 0x016 /* XXX: Not seen on T61 */
113#define THINKPAD_NOTIFY_VolumeMute 0x017 /* XXX: Not seen on T61 */ 114#define THINKPAD_NOTIFY_VolumeMute 0x017 /* XXX: Not seen on T61 */
114#define THINKPAD_NOTIFY_ThinkVantage 0x018 115#define THINKPAD_NOTIFY_ThinkVantage 0x018
115#define THINKPAD_NOTIFY_Star 0x311 116#define THINKPAD_NOTIFY_Star 0x311
116#define THINKPAD_NOTIFY_Scissors 0x312 117#define THINKPAD_NOTIFY_Scissors 0x312
117#define THINKPAD_NOTIFY_Bluetooth 0x314 118#define THINKPAD_NOTIFY_Bluetooth 0x314
118#define THINKPAD_NOTIFY_Keyboard 0x315 119#define THINKPAD_NOTIFY_Keyboard 0x315
119 120
120#define THINKPAD_CMOS_BRIGHTNESS_UP 0x04 121#define THINKPAD_CMOS_BRIGHTNESS_UP 0x04
121#define THINKPAD_CMOS_BRIGHTNESS_DOWN 0x05 122#define THINKPAD_CMOS_BRIGHTNESS_DOWN 0x05
122 123
123#define THINKPAD_HKEY_VERSION_1 0x0100 124#define THINKPAD_HKEY_VERSION_1 0x0100
124#define THINKPAD_HKEY_VERSION_2 0x0200 125#define THINKPAD_HKEY_VERSION_2 0x0200
125 126
126#define THINKPAD_DISPLAY_LCD 0x01 127#define THINKPAD_DISPLAY_LCD 0x01
127#define THINKPAD_DISPLAY_CRT 0x02 128#define THINKPAD_DISPLAY_CRT 0x02
128#define THINKPAD_DISPLAY_DVI 0x08 129#define THINKPAD_DISPLAY_DVI 0x08
129#define THINKPAD_DISPLAY_ALL \ 130#define THINKPAD_DISPLAY_ALL \
130 (THINKPAD_DISPLAY_LCD | THINKPAD_DISPLAY_CRT | THINKPAD_DISPLAY_DVI) 131 (THINKPAD_DISPLAY_LCD | THINKPAD_DISPLAY_CRT | THINKPAD_DISPLAY_DVI)
131 132
132#define THINKPAD_BLUETOOTH_HWPRESENT 0x01 133#define THINKPAD_BLUETOOTH_HWPRESENT 0x01
133#define THINKPAD_BLUETOOTH_RADIOSSW 0x02 134#define THINKPAD_BLUETOOTH_RADIOSSW 0x02
134#define THINKPAD_BLUETOOTH_RESUMECTRL 0x04 135#define THINKPAD_BLUETOOTH_RESUMECTRL 0x04
135 136
136#define THINKPAD_WWAN_HWPRESENT 0x01 137#define THINKPAD_WWAN_HWPRESENT 0x01
137#define THINKPAD_WWAN_RADIOSSW 0x02 138#define THINKPAD_WWAN_RADIOSSW 0x02
138#define THINKPAD_WWAN_RESUMECTRL 0x04 139#define THINKPAD_WWAN_RESUMECTRL 0x04
139 140
140#define THINKPAD_UWB_HWPRESENT 0x01 141#define THINKPAD_UWB_HWPRESENT 0x01
141#define THINKPAD_UWB_RADIOSSW 0x02 142#define THINKPAD_UWB_RADIOSSW 0x02
142 143
143#define THINKPAD_RFK_BLUETOOTH 0 144#define THINKPAD_RFK_BLUETOOTH 0
144#define THINKPAD_RFK_WWAN 1 145#define THINKPAD_RFK_WWAN 1
145#define THINKPAD_RFK_UWB 2 146#define THINKPAD_RFK_UWB 2
146 147
147static int thinkpad_match(device_t, cfdata_t, void *); 148static int thinkpad_match(device_t, cfdata_t, void *);
148static void thinkpad_attach(device_t, device_t, void *); 149static void thinkpad_attach(device_t, device_t, void *);
149static int thinkpad_detach(device_t, int); 150static int thinkpad_detach(device_t, int);
150 151
151static ACPI_STATUS thinkpad_mask_init(thinkpad_softc_t *, uint32_t); 152static ACPI_STATUS thinkpad_mask_init(thinkpad_softc_t *, uint32_t);
152static void thinkpad_notify_handler(ACPI_HANDLE, uint32_t, void *); 153static void thinkpad_notify_handler(ACPI_HANDLE, uint32_t, void *);
153static void thinkpad_get_hotkeys(void *); 154static void thinkpad_get_hotkeys(void *);
154 155
155static void thinkpad_sensors_init(thinkpad_softc_t *); 156static void thinkpad_sensors_init(thinkpad_softc_t *);
156static void thinkpad_sensors_refresh(struct sysmon_envsys *, envsys_data_t *); 157static void thinkpad_sensors_refresh(struct sysmon_envsys *, envsys_data_t *);
157static void thinkpad_temp_refresh(struct sysmon_envsys *, envsys_data_t *); 158static void thinkpad_temp_refresh(struct sysmon_envsys *, envsys_data_t *);
158static void thinkpad_fan_refresh(struct sysmon_envsys *, envsys_data_t *); 159static void thinkpad_fan_refresh(struct sysmon_envsys *, envsys_data_t *);
159 160
160static void thinkpad_uwb_toggle(thinkpad_softc_t *); 161static void thinkpad_uwb_toggle(thinkpad_softc_t *);
161static void thinkpad_wwan_toggle(thinkpad_softc_t *); 162static void thinkpad_wwan_toggle(thinkpad_softc_t *);
162static void thinkpad_bluetooth_toggle(thinkpad_softc_t *); 163static void thinkpad_bluetooth_toggle(thinkpad_softc_t *);
163 164
164static bool thinkpad_resume(device_t, const pmf_qual_t *); 165static bool thinkpad_resume(device_t, const pmf_qual_t *);
165static void thinkpad_brightness_up(device_t); 166static void thinkpad_brightness_up(device_t);
166static void thinkpad_brightness_down(device_t); 167static void thinkpad_brightness_down(device_t);
167static uint8_t thinkpad_brightness_read(thinkpad_softc_t *sc); 168static uint8_t thinkpad_brightness_read(thinkpad_softc_t *sc);
168static void thinkpad_cmos(thinkpad_softc_t *, uint8_t); 169static void thinkpad_cmos(thinkpad_softc_t *, uint8_t);
169 170
170CFATTACH_DECL3_NEW(thinkpad, sizeof(thinkpad_softc_t), 171CFATTACH_DECL3_NEW(thinkpad, sizeof(thinkpad_softc_t),
171 thinkpad_match, thinkpad_attach, thinkpad_detach, NULL, NULL, NULL, 172 thinkpad_match, thinkpad_attach, thinkpad_detach, NULL, NULL, NULL,
172 DVF_DETACH_SHUTDOWN); 173 DVF_DETACH_SHUTDOWN);
173 174
174static const struct device_compatible_entry compat_data[] = { 175static const struct device_compatible_entry compat_data[] = {
175 { .compat = "IBM0068" }, 176 { .compat = "IBM0068" },
176 { .compat = "LEN0068" }, 177 { .compat = "LEN0068" },
177 { .compat = "LEN0268" }, 178 { .compat = "LEN0268" },
178 DEVICE_COMPAT_EOL 179 DEVICE_COMPAT_EOL
179}; 180};
180 181
181static int 182static int
182thinkpad_match(device_t parent, cfdata_t match, void *opaque) 183thinkpad_match(device_t parent, cfdata_t match, void *opaque)
183{ 184{
184 struct acpi_attach_args *aa = (struct acpi_attach_args *)opaque; 185 struct acpi_attach_args *aa = (struct acpi_attach_args *)opaque;
185 ACPI_INTEGER ver; 186 ACPI_INTEGER ver;
186 int ret; 187 int ret;
187 188
188 ret = acpi_compatible_match(aa, compat_data); 189 ret = acpi_compatible_match(aa, compat_data);
189 if (ret == 0) 190 if (ret == 0)
190 return 0; 191 return 0;
191 192
192 /* We only support hotkey versions 0x0100 and 0x0200 */ 193 /* We only support hotkey versions 0x0100 and 0x0200 */
193 if (ACPI_FAILURE(acpi_eval_integer(aa->aa_node->ad_handle, "MHKV", 194 if (ACPI_FAILURE(acpi_eval_integer(aa->aa_node->ad_handle, "MHKV",
194 &ver))) 195 &ver)))
195 return 0; 196 return 0;
196 197
197 switch (ver) { 198 switch (ver) {
198 case THINKPAD_HKEY_VERSION_1: 199 case THINKPAD_HKEY_VERSION_1:
199 case THINKPAD_HKEY_VERSION_2: 200 case THINKPAD_HKEY_VERSION_2:
200 break; 201 break;
201 default: 202 default:
202 return 0; 203 return 0;
203 } 204 }
204 205
205 /* Cool, looks like we're good to go */ 206 /* Cool, looks like we're good to go */
206 return ret; 207 return ret;
207} 208}
208 209
209static void 210static void
210thinkpad_attach(device_t parent, device_t self, void *opaque) 211thinkpad_attach(device_t parent, device_t self, void *opaque)
211{ 212{
212 thinkpad_softc_t *sc = device_private(self); 213 thinkpad_softc_t *sc = device_private(self);
213 struct acpi_attach_args *aa = (struct acpi_attach_args *)opaque; 214 struct acpi_attach_args *aa = (struct acpi_attach_args *)opaque;
214 struct sysmon_pswitch *psw; 215 struct sysmon_pswitch *psw;
215 device_t curdev; 216 device_t curdev;
216 deviter_t di; 217 deviter_t di;
217 ACPI_STATUS rv; 218 ACPI_STATUS rv;
218 ACPI_INTEGER val; 219 ACPI_INTEGER val;
219 int i; 220 int i;
220 221
221 sc->sc_dev = self; 222 sc->sc_dev = self;
222 sc->sc_powhdl = NULL; 223 sc->sc_powhdl = NULL;
223 sc->sc_cmoshdl = NULL; 224 sc->sc_cmoshdl = NULL;
224 sc->sc_node = aa->aa_node; 225 sc->sc_node = aa->aa_node;
225 sc->sc_display_state = THINKPAD_DISPLAY_LCD; 226 sc->sc_display_state = THINKPAD_DISPLAY_LCD;
226 227
227 aprint_naive("\n"); 228 aprint_naive("\n");
228 aprint_normal("\n"); 229 aprint_normal("\n");
229 230
230 sc->sc_ecdev = NULL; 231 sc->sc_ecdev = NULL;
231 for (curdev = deviter_first(&di, DEVITER_F_ROOT_FIRST); 232 for (curdev = deviter_first(&di, DEVITER_F_ROOT_FIRST);
232 curdev != NULL; curdev = deviter_next(&di)) 233 curdev != NULL; curdev = deviter_next(&di))
233 if (device_is_a(curdev, "acpiecdt") || 234 if (device_is_a(curdev, "acpiecdt") ||
234 device_is_a(curdev, "acpiec")) { 235 device_is_a(curdev, "acpiec")) {
235 sc->sc_ecdev = curdev; 236 sc->sc_ecdev = curdev;
236 break; 237 break;
237 } 238 }
238 deviter_release(&di); 239 deviter_release(&di);
239 240
240 if (sc->sc_ecdev) 241 if (sc->sc_ecdev)
241 aprint_debug_dev(self, "using EC at %s\n", 242 aprint_debug_dev(self, "using EC at %s\n",
242 device_xname(sc->sc_ecdev)); 243 device_xname(sc->sc_ecdev));
243 244
244 /* Get the supported event mask */ 245 /* Query the version number */
245 rv = acpi_eval_integer(sc->sc_node->ad_handle, "MHKA", &val); 246 rv = acpi_eval_integer(aa->aa_node->ad_handle, "MHKV", &sc->sc_ver);
246 if (ACPI_FAILURE(rv)) { 247 if (ACPI_FAILURE(rv)) {
247 aprint_error_dev(self, "couldn't evaluate MHKA: %s\n", 248 aprint_error_dev(self, "couldn't evaluate MHKV: %s\n",
248 AcpiFormatException(rv)); 249 AcpiFormatException(rv));
249 goto fail; 250 goto fail;
250 } 251 }
 252 aprint_normal_dev(self, "version %04x\n", (unsigned)sc->sc_ver);
 253
 254 /* Get the supported event mask */
 255 switch (sc->sc_ver) {
 256 case THINKPAD_HKEY_VERSION_1:
 257 rv = acpi_eval_integer(sc->sc_node->ad_handle, "MHKA", &val);
 258 if (ACPI_FAILURE(rv)) {
 259 aprint_error_dev(self, "couldn't evaluate MHKA: %s\n",
 260 AcpiFormatException(rv));
 261 goto fail;
 262 }
 263 break;
 264 case THINKPAD_HKEY_VERSION_2: {
 265 ACPI_OBJECT args[1] = {
 266 [0] = { .Integer = {
 267 .Type = ACPI_TYPE_INTEGER,
 268 .Value = 1, /* hotkey events */
 269 } },
 270 };
 271 ACPI_OBJECT_LIST arglist = {
 272 .Count = __arraycount(args),
 273 .Pointer = args,
 274 };
 275 ACPI_OBJECT ret;
 276 ACPI_BUFFER buf = { .Pointer = &ret, .Length = sizeof(ret) };
 277
 278 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "MHKA",
 279 &arglist, &buf);
 280 if (ACPI_FAILURE(rv)) {
 281 aprint_error_dev(self, "couldn't evaluate MHKA(1):"
 282 " %s\n",
 283 AcpiFormatException(rv));
 284 goto fail;
 285 }
 286 if (buf.Length == 0 || ret.Type != ACPI_TYPE_INTEGER) {
 287 aprint_error_dev(self, "failed to evaluate MHKA(1)\n");
 288 goto fail;
 289 }
 290 val = ret.Integer.Value;
 291 break;
 292 }
 293 default:
 294 panic("%s: invalid version %jd", device_xname(self),
 295 (intmax_t)sc->sc_ver);
 296 }
251 297
252 /* Enable all supported events */ 298 /* Enable all supported events */
253 rv = thinkpad_mask_init(sc, val); 299 rv = thinkpad_mask_init(sc, val);
254 if (ACPI_FAILURE(rv)) { 300 if (ACPI_FAILURE(rv)) {
255 aprint_error_dev(self, "couldn't set event mask: %s\n", 301 aprint_error_dev(self, "couldn't set event mask: %s\n",
256 AcpiFormatException(rv)); 302 AcpiFormatException(rv));
257 goto fail; 303 goto fail;
258 } 304 }
259 305
260 (void)acpi_register_notify(sc->sc_node, thinkpad_notify_handler); 306 (void)acpi_register_notify(sc->sc_node, thinkpad_notify_handler);
261 307
262 /* 308 /*
263 * Obtain a handle for CMOS commands. This is used by T61. 309 * Obtain a handle for CMOS commands. This is used by T61.
264 */ 310 */
265 (void)AcpiGetHandle(NULL, "\\UCMS", &sc->sc_cmoshdl); 311 (void)AcpiGetHandle(NULL, "\\UCMS", &sc->sc_cmoshdl);
266 312
267 /* 313 /*
268 * Obtain a handle to the power resource available on many models. 314 * Obtain a handle to the power resource available on many models.
269 * Since pmf(9) is not yet integrated with the ACPI power resource 315 * Since pmf(9) is not yet integrated with the ACPI power resource
270 * code, this must be turned on manually upon resume. Otherwise the 316 * code, this must be turned on manually upon resume. Otherwise the
271 * system may, for instance, resume from S3 with usb(4) powered down. 317 * system may, for instance, resume from S3 with usb(4) powered down.
272 */ 318 */
273 (void)AcpiGetHandle(NULL, "\\_SB.PCI0.LPC.EC.PUBS", &sc->sc_powhdl); 319 (void)AcpiGetHandle(NULL, "\\_SB.PCI0.LPC.EC.PUBS", &sc->sc_powhdl);
274 320
275 /* Register power switches with sysmon */ 321 /* Register power switches with sysmon */
276 psw = sc->sc_smpsw; 322 psw = sc->sc_smpsw;
277 sc->sc_smpsw_valid = true; 323 sc->sc_smpsw_valid = true;
278 324
279 psw[TP_PSW_SLEEP].smpsw_name = device_xname(self); 325 psw[TP_PSW_SLEEP].smpsw_name = device_xname(self);
280 psw[TP_PSW_SLEEP].smpsw_type = PSWITCH_TYPE_SLEEP; 326 psw[TP_PSW_SLEEP].smpsw_type = PSWITCH_TYPE_SLEEP;
281#if notyet 327#if notyet
282 psw[TP_PSW_HIBERNATE].smpsw_name = device_xname(self); 328 psw[TP_PSW_HIBERNATE].smpsw_name = device_xname(self);
283 mpsw[TP_PSW_HIBERNATE].smpsw_type = PSWITCH_TYPE_HIBERNATE; 329 mpsw[TP_PSW_HIBERNATE].smpsw_type = PSWITCH_TYPE_HIBERNATE;
284#endif 330#endif
285 for (i = TP_PSW_DISPLAY_CYCLE; i < TP_PSW_LAST; i++) 331 for (i = TP_PSW_DISPLAY_CYCLE; i < TP_PSW_LAST; i++)
286 sc->sc_smpsw[i].smpsw_type = PSWITCH_TYPE_HOTKEY; 332 sc->sc_smpsw[i].smpsw_type = PSWITCH_TYPE_HOTKEY;
287 psw[TP_PSW_DISPLAY_CYCLE].smpsw_name = PSWITCH_HK_DISPLAY_CYCLE; 333 psw[TP_PSW_DISPLAY_CYCLE].smpsw_name = PSWITCH_HK_DISPLAY_CYCLE;
288 psw[TP_PSW_LOCK_SCREEN].smpsw_name = PSWITCH_HK_LOCK_SCREEN; 334 psw[TP_PSW_LOCK_SCREEN].smpsw_name = PSWITCH_HK_LOCK_SCREEN;
289 psw[TP_PSW_BATTERY_INFO].smpsw_name = PSWITCH_HK_BATTERY_INFO; 335 psw[TP_PSW_BATTERY_INFO].smpsw_name = PSWITCH_HK_BATTERY_INFO;
290 psw[TP_PSW_EJECT_BUTTON].smpsw_name = PSWITCH_HK_EJECT_BUTTON; 336 psw[TP_PSW_EJECT_BUTTON].smpsw_name = PSWITCH_HK_EJECT_BUTTON;
291 psw[TP_PSW_ZOOM_BUTTON].smpsw_name = PSWITCH_HK_ZOOM_BUTTON; 337 psw[TP_PSW_ZOOM_BUTTON].smpsw_name = PSWITCH_HK_ZOOM_BUTTON;
292 psw[TP_PSW_VENDOR_BUTTON].smpsw_name = PSWITCH_HK_VENDOR_BUTTON; 338 psw[TP_PSW_VENDOR_BUTTON].smpsw_name = PSWITCH_HK_VENDOR_BUTTON;
293#ifndef THINKPAD_NORMAL_HOTKEYS 339#ifndef THINKPAD_NORMAL_HOTKEYS
294 psw[TP_PSW_FNF1_BUTTON].smpsw_name = PSWITCH_HK_FNF1_BUTTON; 340 psw[TP_PSW_FNF1_BUTTON].smpsw_name = PSWITCH_HK_FNF1_BUTTON;
295 psw[TP_PSW_WIRELESS_BUTTON].smpsw_name = PSWITCH_HK_WIRELESS_BUTTON; 341 psw[TP_PSW_WIRELESS_BUTTON].smpsw_name = PSWITCH_HK_WIRELESS_BUTTON;
296 psw[TP_PSW_WWAN_BUTTON].smpsw_name = PSWITCH_HK_WWAN_BUTTON; 342 psw[TP_PSW_WWAN_BUTTON].smpsw_name = PSWITCH_HK_WWAN_BUTTON;
297 psw[TP_PSW_POINTER_BUTTON].smpsw_name = PSWITCH_HK_POINTER_BUTTON; 343 psw[TP_PSW_POINTER_BUTTON].smpsw_name = PSWITCH_HK_POINTER_BUTTON;
298 psw[TP_PSW_FNF10_BUTTON].smpsw_name = PSWITCH_HK_FNF10_BUTTON; 344 psw[TP_PSW_FNF10_BUTTON].smpsw_name = PSWITCH_HK_FNF10_BUTTON;
299 psw[TP_PSW_FNF11_BUTTON].smpsw_name = PSWITCH_HK_FNF11_BUTTON; 345 psw[TP_PSW_FNF11_BUTTON].smpsw_name = PSWITCH_HK_FNF11_BUTTON;
300 psw[TP_PSW_BRIGHTNESS_UP].smpsw_name = PSWITCH_HK_BRIGHTNESS_UP; 346 psw[TP_PSW_BRIGHTNESS_UP].smpsw_name = PSWITCH_HK_BRIGHTNESS_UP;
301 psw[TP_PSW_BRIGHTNESS_DOWN].smpsw_name = PSWITCH_HK_BRIGHTNESS_DOWN; 347 psw[TP_PSW_BRIGHTNESS_DOWN].smpsw_name = PSWITCH_HK_BRIGHTNESS_DOWN;
302 psw[TP_PSW_THINKLIGHT].smpsw_name = PSWITCH_HK_THINKLIGHT; 348 psw[TP_PSW_THINKLIGHT].smpsw_name = PSWITCH_HK_THINKLIGHT;
303 psw[TP_PSW_VOLUME_UP].smpsw_name = PSWITCH_HK_VOLUME_UP; 349 psw[TP_PSW_VOLUME_UP].smpsw_name = PSWITCH_HK_VOLUME_UP;
304 psw[TP_PSW_VOLUME_DOWN].smpsw_name = PSWITCH_HK_VOLUME_DOWN; 350 psw[TP_PSW_VOLUME_DOWN].smpsw_name = PSWITCH_HK_VOLUME_DOWN;
305 psw[TP_PSW_VOLUME_MUTE].smpsw_name = PSWITCH_HK_VOLUME_MUTE; 351 psw[TP_PSW_VOLUME_MUTE].smpsw_name = PSWITCH_HK_VOLUME_MUTE;
306 psw[TP_PSW_STAR_BUTTON].smpsw_name = PSWITCH_HK_STAR_BUTTON; 352 psw[TP_PSW_STAR_BUTTON].smpsw_name = PSWITCH_HK_STAR_BUTTON;
307 psw[TP_PSW_SCISSORS_BUTTON].smpsw_name = PSWITCH_HK_SCISSORS_BUTTON; 353 psw[TP_PSW_SCISSORS_BUTTON].smpsw_name = PSWITCH_HK_SCISSORS_BUTTON;
308 psw[TP_PSW_BLUETOOTH_BUTTON].smpsw_name = PSWITCH_HK_BLUETOOTH_BUTTON; 354 psw[TP_PSW_BLUETOOTH_BUTTON].smpsw_name = PSWITCH_HK_BLUETOOTH_BUTTON;
309 psw[TP_PSW_KEYBOARD_BUTTON].smpsw_name = PSWITCH_HK_KEYBOARD_BUTTON; 355 psw[TP_PSW_KEYBOARD_BUTTON].smpsw_name = PSWITCH_HK_KEYBOARD_BUTTON;
310#endif /* THINKPAD_NORMAL_HOTKEYS */ 356#endif /* THINKPAD_NORMAL_HOTKEYS */
311 357
312 for (i = 0; i < TP_PSW_LAST; i++) { 358 for (i = 0; i < TP_PSW_LAST; i++) {
313 /* not supported yet */ 359 /* not supported yet */
314 if (i == TP_PSW_HIBERNATE) 360 if (i == TP_PSW_HIBERNATE)
315 continue; 361 continue;
316 if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) { 362 if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) {
317 aprint_error_dev(self, 363 aprint_error_dev(self,
318 "couldn't register with sysmon\n"); 364 "couldn't register with sysmon\n");
319 sc->sc_smpsw_valid = false; 365 sc->sc_smpsw_valid = false;
320 break; 366 break;
321 } 367 }
322 } 368 }
323 369
324 /* Register temperature and fan sensors with envsys */ 370 /* Register temperature and fan sensors with envsys */
325 thinkpad_sensors_init(sc); 371 thinkpad_sensors_init(sc);
326 372
327fail: 373fail:
328 if (!pmf_device_register(self, NULL, thinkpad_resume)) 374 if (!pmf_device_register(self, NULL, thinkpad_resume))
329 aprint_error_dev(self, "couldn't establish power handler\n"); 375 aprint_error_dev(self, "couldn't establish power handler\n");
330 if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP, 376 if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP,
331 thinkpad_brightness_up, true)) 377 thinkpad_brightness_up, true))
332 aprint_error_dev(self, "couldn't register event handler\n"); 378 aprint_error_dev(self, "couldn't register event handler\n");
333 if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN, 379 if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN,
334 thinkpad_brightness_down, true)) 380 thinkpad_brightness_down, true))
335 aprint_error_dev(self, "couldn't register event handler\n"); 381 aprint_error_dev(self, "couldn't register event handler\n");
336} 382}
337 383
338static int 384static int
339thinkpad_detach(device_t self, int flags) 385thinkpad_detach(device_t self, int flags)
340{ 386{
341 struct thinkpad_softc *sc = device_private(self); 387 struct thinkpad_softc *sc = device_private(self);
342 int i; 388 int i;
343 389
344 acpi_deregister_notify(sc->sc_node); 390 acpi_deregister_notify(sc->sc_node);
345 391
346 for (i = 0; i < TP_PSW_LAST; i++) 392 for (i = 0; i < TP_PSW_LAST; i++)
347 sysmon_pswitch_unregister(&sc->sc_smpsw[i]); 393 sysmon_pswitch_unregister(&sc->sc_smpsw[i]);
348 394
349 if (sc->sc_sme != NULL) 395 if (sc->sc_sme != NULL)
350 sysmon_envsys_unregister(sc->sc_sme); 396 sysmon_envsys_unregister(sc->sc_sme);
351 397
352 pmf_device_deregister(self); 398 pmf_device_deregister(self);
353 399
354 pmf_event_deregister(self, PMFE_DISPLAY_BRIGHTNESS_UP, 400 pmf_event_deregister(self, PMFE_DISPLAY_BRIGHTNESS_UP,
355 thinkpad_brightness_up, true); 401 thinkpad_brightness_up, true);
356 402
357 pmf_event_deregister(self, PMFE_DISPLAY_BRIGHTNESS_DOWN, 403 pmf_event_deregister(self, PMFE_DISPLAY_BRIGHTNESS_DOWN,
358 thinkpad_brightness_down, true); 404 thinkpad_brightness_down, true);
359 405
360 return 0; 406 return 0;
361} 407}
362 408
363static void 409static void
364thinkpad_notify_handler(ACPI_HANDLE hdl, uint32_t notify, void *opaque) 410thinkpad_notify_handler(ACPI_HANDLE hdl, uint32_t notify, void *opaque)
365{ 411{
366 device_t self = opaque; 412 device_t self = opaque;
367 thinkpad_softc_t *sc; 413 thinkpad_softc_t *sc;
368 414
369 sc = device_private(self); 415 sc = device_private(self);
370 416
371 if (notify != 0x80) { 417 if (notify != 0x80) {
372 aprint_debug_dev(self, "unknown notify 0x%02x\n", notify); 418 aprint_debug_dev(self, "unknown notify 0x%02x\n", notify);
373 return; 419 return;
374 } 420 }
375 421
376 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, thinkpad_get_hotkeys, sc); 422 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, thinkpad_get_hotkeys, sc);
377} 423}
378 424
379SDT_PROBE_DEFINE2(sdt, thinkpad, hotkey, MHKP, 425SDT_PROBE_DEFINE2(sdt, thinkpad, hotkey, MHKP,
380 "struct thinkpad_softc *"/*sc*/, 426 "struct thinkpad_softc *"/*sc*/,
381 "ACPI_INTEGER"/*val*/); 427 "ACPI_INTEGER"/*val*/);
382 428
383static void 429static void
384thinkpad_get_hotkeys(void *opaque) 430thinkpad_get_hotkeys(void *opaque)
385{ 431{
386 thinkpad_softc_t *sc = (thinkpad_softc_t *)opaque; 432 thinkpad_softc_t *sc = (thinkpad_softc_t *)opaque;
387 device_t self = sc->sc_dev; 433 device_t self = sc->sc_dev;
388 ACPI_STATUS rv; 434 ACPI_STATUS rv;
389 ACPI_INTEGER val; 435 ACPI_INTEGER val;
390 int type, event; 436 int type, event;
391 437
392 for (;;) { 438 for (;;) {
393 rv = acpi_eval_integer(sc->sc_node->ad_handle, "MHKP", &val); 439 rv = acpi_eval_integer(sc->sc_node->ad_handle, "MHKP", &val);
394 if (ACPI_FAILURE(rv)) { 440 if (ACPI_FAILURE(rv)) {
395 aprint_error_dev(self, "couldn't evaluate MHKP: %s\n", 441 aprint_error_dev(self, "couldn't evaluate MHKP: %s\n",
396 AcpiFormatException(rv)); 442 AcpiFormatException(rv));
397 return; 443 return;
398 } 444 }
399 SDT_PROBE2(sdt, thinkpad, hotkey, MHKP, sc, val); 445 SDT_PROBE2(sdt, thinkpad, hotkey, MHKP, sc, val);
400 446
401 if (val == 0) 447 if (val == 0)
402 return; 448 return;
403 449
404 type = (val & 0xf000) >> 12; 450 type = (val & 0xf000) >> 12;
405 event = val & 0x0fff; 451 event = val & 0x0fff;
406 452
407 if (type != 1) 453 if (type != 1)
408 /* Only type 1 events are supported for now */ 454 /* Only type 1 events are supported for now */
409 continue; 455 continue;
410 456
411 switch (event) { 457 switch (event) {
412 case THINKPAD_NOTIFY_BrightnessUp: 458 case THINKPAD_NOTIFY_BrightnessUp:
413 thinkpad_brightness_up(self); 459 thinkpad_brightness_up(self);
414#ifndef THINKPAD_NORMAL_HOTKEYS 460#ifndef THINKPAD_NORMAL_HOTKEYS
415 if (sc->sc_smpsw_valid == false) 461 if (sc->sc_smpsw_valid == false)
416 break; 462 break;
417 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_BRIGHTNESS_UP], 463 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_BRIGHTNESS_UP],
418 PSWITCH_EVENT_PRESSED); 464 PSWITCH_EVENT_PRESSED);
419#endif 465#endif
420 break; 466 break;
421 case THINKPAD_NOTIFY_BrightnessDown: 467 case THINKPAD_NOTIFY_BrightnessDown:
422 thinkpad_brightness_down(self); 468 thinkpad_brightness_down(self);
423#ifndef THINKPAD_NORMAL_HOTKEYS 469#ifndef THINKPAD_NORMAL_HOTKEYS
424 if (sc->sc_smpsw_valid == false) 470 if (sc->sc_smpsw_valid == false)
425 break; 471 break;
426 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_BRIGHTNESS_DOWN], 472 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_BRIGHTNESS_DOWN],
427 PSWITCH_EVENT_PRESSED); 473 PSWITCH_EVENT_PRESSED);
428#endif 474#endif
429 break; 475 break;
430 case THINKPAD_NOTIFY_WirelessSwitch: 476 case THINKPAD_NOTIFY_WirelessSwitch:
431 thinkpad_uwb_toggle(sc); 477 thinkpad_uwb_toggle(sc);
432 thinkpad_wwan_toggle(sc); 478 thinkpad_wwan_toggle(sc);
433 thinkpad_bluetooth_toggle(sc); 479 thinkpad_bluetooth_toggle(sc);
434#ifndef THINKPAD_NORMAL_HOTKEYS 480#ifndef THINKPAD_NORMAL_HOTKEYS
435 if (sc->sc_smpsw_valid == false) 481 if (sc->sc_smpsw_valid == false)
436 break; 482 break;
437 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_WIRELESS_BUTTON], 483 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_WIRELESS_BUTTON],
438 PSWITCH_EVENT_PRESSED); 484 PSWITCH_EVENT_PRESSED);
439#endif 485#endif
440 break; 486 break;
441 case THINKPAD_NOTIFY_Bluetooth: 487 case THINKPAD_NOTIFY_Bluetooth:
442 thinkpad_bluetooth_toggle(sc); 488 thinkpad_bluetooth_toggle(sc);
443#ifndef THINKPAD_NORMAL_HOTKEYS 489#ifndef THINKPAD_NORMAL_HOTKEYS
444 if (sc->sc_smpsw_valid == false) 490 if (sc->sc_smpsw_valid == false)
445 break; 491 break;
446 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_BLUETOOTH_BUTTON], 492 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_BLUETOOTH_BUTTON],
447 PSWITCH_EVENT_PRESSED); 493 PSWITCH_EVENT_PRESSED);
448#endif 494#endif
449 break; 495 break;
450 case THINKPAD_NOTIFY_wWANSwitch: 496 case THINKPAD_NOTIFY_wWANSwitch:
451 thinkpad_wwan_toggle(sc); 497 thinkpad_wwan_toggle(sc);
452#ifndef THINKPAD_NORMAL_HOTKEYS 498#ifndef THINKPAD_NORMAL_HOTKEYS
453 if (sc->sc_smpsw_valid == false) 499 if (sc->sc_smpsw_valid == false)
454 break; 500 break;
455 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_WWAN_BUTTON], 501 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_WWAN_BUTTON],
456 PSWITCH_EVENT_PRESSED); 502 PSWITCH_EVENT_PRESSED);
457#endif 503#endif
458 break; 504 break;
459 case THINKPAD_NOTIFY_SleepButton: 505 case THINKPAD_NOTIFY_SleepButton:
460 if (sc->sc_smpsw_valid == false) 506 if (sc->sc_smpsw_valid == false)
461 break; 507 break;
462 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_SLEEP], 508 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_SLEEP],
463 PSWITCH_EVENT_PRESSED); 509 PSWITCH_EVENT_PRESSED);
464 break; 510 break;
465 case THINKPAD_NOTIFY_HibernateButton: 511 case THINKPAD_NOTIFY_HibernateButton:
466#if notyet 512#if notyet
467 if (sc->sc_smpsw_valid == false) 513 if (sc->sc_smpsw_valid == false)
468 break; 514 break;
469 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_HIBERNATE], 515 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_HIBERNATE],
470 PSWITCH_EVENT_PRESSED); 516 PSWITCH_EVENT_PRESSED);
471#endif 517#endif
472 break; 518 break;
473 case THINKPAD_NOTIFY_DisplayCycle: 519 case THINKPAD_NOTIFY_DisplayCycle:
474 if (sc->sc_smpsw_valid == false) 520 if (sc->sc_smpsw_valid == false)
475 break; 521 break;
476 sysmon_pswitch_event( 522 sysmon_pswitch_event(
477 &sc->sc_smpsw[TP_PSW_DISPLAY_CYCLE], 523 &sc->sc_smpsw[TP_PSW_DISPLAY_CYCLE],
478 PSWITCH_EVENT_PRESSED); 524 PSWITCH_EVENT_PRESSED);
479 break; 525 break;
480 case THINKPAD_NOTIFY_LockScreen: 526 case THINKPAD_NOTIFY_LockScreen:
481 if (sc->sc_smpsw_valid == false) 527 if (sc->sc_smpsw_valid == false)
482 break; 528 break;
483 sysmon_pswitch_event( 529 sysmon_pswitch_event(
484 &sc->sc_smpsw[TP_PSW_LOCK_SCREEN], 530 &sc->sc_smpsw[TP_PSW_LOCK_SCREEN],
485 PSWITCH_EVENT_PRESSED); 531 PSWITCH_EVENT_PRESSED);
486 break; 532 break;
487 case THINKPAD_NOTIFY_BatteryInfo: 533 case THINKPAD_NOTIFY_BatteryInfo:
488 if (sc->sc_smpsw_valid == false) 534 if (sc->sc_smpsw_valid == false)
489 break; 535 break;
490 sysmon_pswitch_event( 536 sysmon_pswitch_event(
491 &sc->sc_smpsw[TP_PSW_BATTERY_INFO], 537 &sc->sc_smpsw[TP_PSW_BATTERY_INFO],
492 PSWITCH_EVENT_PRESSED); 538 PSWITCH_EVENT_PRESSED);
493 break; 539 break;
494 case THINKPAD_NOTIFY_EjectButton: 540 case THINKPAD_NOTIFY_EjectButton:
495 if (sc->sc_smpsw_valid == false) 541 if (sc->sc_smpsw_valid == false)
496 break; 542 break;
497 sysmon_pswitch_event( 543 sysmon_pswitch_event(
498 &sc->sc_smpsw[TP_PSW_EJECT_BUTTON], 544 &sc->sc_smpsw[TP_PSW_EJECT_BUTTON],
499 PSWITCH_EVENT_PRESSED); 545 PSWITCH_EVENT_PRESSED);
500 break; 546 break;
501 case THINKPAD_NOTIFY_Zoom: 547 case THINKPAD_NOTIFY_Zoom:
502 if (sc->sc_smpsw_valid == false) 548 if (sc->sc_smpsw_valid == false)
503 break; 549 break;
504 sysmon_pswitch_event( 550 sysmon_pswitch_event(
505 &sc->sc_smpsw[TP_PSW_ZOOM_BUTTON], 551 &sc->sc_smpsw[TP_PSW_ZOOM_BUTTON],
506 PSWITCH_EVENT_PRESSED); 552 PSWITCH_EVENT_PRESSED);
507 break; 553 break;
508 case THINKPAD_NOTIFY_ThinkVantage: 554 case THINKPAD_NOTIFY_ThinkVantage:
509 if (sc->sc_smpsw_valid == false) 555 if (sc->sc_smpsw_valid == false)
510 break; 556 break;
511 sysmon_pswitch_event( 557 sysmon_pswitch_event(
512 &sc->sc_smpsw[TP_PSW_VENDOR_BUTTON], 558 &sc->sc_smpsw[TP_PSW_VENDOR_BUTTON],
513 PSWITCH_EVENT_PRESSED); 559 PSWITCH_EVENT_PRESSED);
514 break; 560 break;
515#ifndef THINKPAD_NORMAL_HOTKEYS 561#ifndef THINKPAD_NORMAL_HOTKEYS
516 case THINKPAD_NOTIFY_FnF1: 562 case THINKPAD_NOTIFY_FnF1:
517 if (sc->sc_smpsw_valid == false) 563 if (sc->sc_smpsw_valid == false)
518 break; 564 break;
519 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_FNF1_BUTTON], 565 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_FNF1_BUTTON],
520 PSWITCH_EVENT_PRESSED); 566 PSWITCH_EVENT_PRESSED);
521 break; 567 break;
522 case THINKPAD_NOTIFY_PointerSwitch: 568 case THINKPAD_NOTIFY_PointerSwitch:
523 if (sc->sc_smpsw_valid == false) 569 if (sc->sc_smpsw_valid == false)
524 break; 570 break;
525 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_POINTER_BUTTON], 571 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_POINTER_BUTTON],
526 PSWITCH_EVENT_PRESSED); 572 PSWITCH_EVENT_PRESSED);
527 break; 573 break;
528 case THINKPAD_NOTIFY_FnF11: 574 case THINKPAD_NOTIFY_FnF11:
529 if (sc->sc_smpsw_valid == false) 575 if (sc->sc_smpsw_valid == false)
530 break; 576 break;
531 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_FNF11_BUTTON], 577 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_FNF11_BUTTON],
532 PSWITCH_EVENT_PRESSED); 578 PSWITCH_EVENT_PRESSED);
533 break; 579 break;
534 case THINKPAD_NOTIFY_ThinkLight: 580 case THINKPAD_NOTIFY_ThinkLight:
535 if (sc->sc_smpsw_valid == false) 581 if (sc->sc_smpsw_valid == false)
536 break; 582 break;
537 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_THINKLIGHT], 583 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_THINKLIGHT],
538 PSWITCH_EVENT_PRESSED); 584 PSWITCH_EVENT_PRESSED);
539 break; 585 break;
540 /* 586 /*
541 * For some reason the next four aren't seen on my T61. 587 * For some reason the next four aren't seen on my T61.
542 */ 588 */
543 case THINKPAD_NOTIFY_FnF10: 589 case THINKPAD_NOTIFY_FnF10:
544 if (sc->sc_smpsw_valid == false) 590 if (sc->sc_smpsw_valid == false)
545 break; 591 break;
546 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_FNF10_BUTTON], 592 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_FNF10_BUTTON],
547 PSWITCH_EVENT_PRESSED); 593 PSWITCH_EVENT_PRESSED);
548 break; 594 break;
549 case THINKPAD_NOTIFY_VolumeUp: 595 case THINKPAD_NOTIFY_VolumeUp:
550 if (sc->sc_smpsw_valid == false) 596 if (sc->sc_smpsw_valid == false)
551 break; 597 break;
552 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_VOLUME_UP], 598 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_VOLUME_UP],
553 PSWITCH_EVENT_PRESSED); 599 PSWITCH_EVENT_PRESSED);
554 break; 600 break;
555 case THINKPAD_NOTIFY_VolumeDown: 601 case THINKPAD_NOTIFY_VolumeDown:
556 if (sc->sc_smpsw_valid == false) 602 if (sc->sc_smpsw_valid == false)
557 break; 603 break;
558 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_VOLUME_DOWN], 604 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_VOLUME_DOWN],
559 PSWITCH_EVENT_PRESSED); 605 PSWITCH_EVENT_PRESSED);
560 break; 606 break;
561 case THINKPAD_NOTIFY_VolumeMute: 607 case THINKPAD_NOTIFY_VolumeMute:
562 if (sc->sc_smpsw_valid == false) 608 if (sc->sc_smpsw_valid == false)
563 break; 609 break;
564 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_VOLUME_MUTE], 610 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_VOLUME_MUTE],
565 PSWITCH_EVENT_PRESSED); 611 PSWITCH_EVENT_PRESSED);
566 break; 612 break;
567 case THINKPAD_NOTIFY_Star: 613 case THINKPAD_NOTIFY_Star:
568 if (sc->sc_smpsw_valid == false) 614 if (sc->sc_smpsw_valid == false)
569 break; 615 break;
570 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_STAR_BUTTON], 616 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_STAR_BUTTON],
571 PSWITCH_EVENT_PRESSED); 617 PSWITCH_EVENT_PRESSED);
572 break; 618 break;
573 case THINKPAD_NOTIFY_Scissors: 619 case THINKPAD_NOTIFY_Scissors:
574 if (sc->sc_smpsw_valid == false) 620 if (sc->sc_smpsw_valid == false)
575 break; 621 break;
576 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_SCISSORS_BUTTON], 622 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_SCISSORS_BUTTON],
577 PSWITCH_EVENT_PRESSED); 623 PSWITCH_EVENT_PRESSED);
578 break; 624 break;
579 case THINKPAD_NOTIFY_Keyboard: 625 case THINKPAD_NOTIFY_Keyboard:
580 if (sc->sc_smpsw_valid == false) 626 if (sc->sc_smpsw_valid == false)
581 break; 627 break;
582 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_KEYBOARD_BUTTON], 628 sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_KEYBOARD_BUTTON],
583 PSWITCH_EVENT_PRESSED); 629 PSWITCH_EVENT_PRESSED);
584 break; 630 break;
585#else 631#else
586 case THINKPAD_NOTIFY_FnF1: 632 case THINKPAD_NOTIFY_FnF1:
587 case THINKPAD_NOTIFY_PointerSwitch: 633 case THINKPAD_NOTIFY_PointerSwitch:
588 case THINKPAD_NOTIFY_FnF10: 634 case THINKPAD_NOTIFY_FnF10:
589 case THINKPAD_NOTIFY_FnF11: 635 case THINKPAD_NOTIFY_FnF11:
590 case THINKPAD_NOTIFY_ThinkLight: 636 case THINKPAD_NOTIFY_ThinkLight:
591 case THINKPAD_NOTIFY_VolumeUp: 637 case THINKPAD_NOTIFY_VolumeUp:
592 case THINKPAD_NOTIFY_VolumeDown: 638 case THINKPAD_NOTIFY_VolumeDown:
593 case THINKPAD_NOTIFY_VolumeMute: 639 case THINKPAD_NOTIFY_VolumeMute:
594 case THINKPAD_NOTIFY_Star: 640 case THINKPAD_NOTIFY_Star:
595 case THINKPAD_NOTIFY_Scissors: 641 case THINKPAD_NOTIFY_Scissors:
596 case THINKPAD_NOTIFY_Keyboard: 642 case THINKPAD_NOTIFY_Keyboard:
597 /* XXXJDM we should deliver hotkeys as keycodes */ 643 /* XXXJDM we should deliver hotkeys as keycodes */
598 break; 644 break;
599#endif /* THINKPAD_NORMAL_HOTKEYS */ 645#endif /* THINKPAD_NORMAL_HOTKEYS */
600 default: 646 default:
601 aprint_debug_dev(self, "notify event 0x%03x\n", event); 647 aprint_debug_dev(self, "notify event 0x%03x\n", event);
602 break; 648 break;
603 } 649 }
604 } 650 }
605} 651}
606 652
607static ACPI_STATUS 653static ACPI_STATUS
608thinkpad_mask_init(thinkpad_softc_t *sc, uint32_t mask) 654thinkpad_mask_init(thinkpad_softc_t *sc, uint32_t mask)
609{ 655{
610 ACPI_OBJECT param[2]; 656 ACPI_OBJECT param[2];
611 ACPI_OBJECT_LIST params; 657 ACPI_OBJECT_LIST params;
612 ACPI_STATUS rv; 658 ACPI_STATUS rv;
613 int i; 659 int i;
614 660
615 /* Update hotkey mask */ 661 /* Update hotkey mask */
616 params.Count = 2; 662 params.Count = 2;
617 params.Pointer = param; 663 params.Pointer = param;
618 param[0].Type = param[1].Type = ACPI_TYPE_INTEGER; 664 param[0].Type = param[1].Type = ACPI_TYPE_INTEGER;
619 665
620 for (i = 0; i < 32; i++) { 666 for (i = 0; i < 32; i++) {
621 param[0].Integer.Value = i + 1; 667 param[0].Integer.Value = i + 1;
622 param[1].Integer.Value = ((__BIT(i) & mask) != 0); 668 param[1].Integer.Value = ((__BIT(i) & mask) != 0);
623 669
624 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "MHKM", 670 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "MHKM",
625 &params, NULL); 671 &params, NULL);
626 if (ACPI_FAILURE(rv)) 672 if (ACPI_FAILURE(rv))
627 return rv; 673 return rv;
628 } 674 }
629 675
630 /* Enable hotkey events */ 676 /* Enable hotkey events */
631 rv = acpi_eval_set_integer(sc->sc_node->ad_handle, "MHKC", 1); 677 rv = acpi_eval_set_integer(sc->sc_node->ad_handle, "MHKC", 1);
632 if (ACPI_FAILURE(rv)) { 678 if (ACPI_FAILURE(rv)) {
633 aprint_error_dev(sc->sc_dev, "couldn't enable hotkeys: %s\n", 679 aprint_error_dev(sc->sc_dev, "couldn't enable hotkeys: %s\n",
634 AcpiFormatException(rv)); 680 AcpiFormatException(rv));
635 return rv; 681 return rv;
636 } 682 }
637 683
638 /* Claim ownership of brightness control */ 684 /* Claim ownership of brightness control */
639 (void)acpi_eval_set_integer(sc->sc_node->ad_handle, "PWMS", 0); 685 (void)acpi_eval_set_integer(sc->sc_node->ad_handle, "PWMS", 0);
640 686
641 return AE_OK; 687 return AE_OK;
642} 688}
643 689
644static void 690static void
645thinkpad_sensors_init(thinkpad_softc_t *sc) 691thinkpad_sensors_init(thinkpad_softc_t *sc)
646{ 692{
647 int i, j; 693 int i, j;
648 694
649 if (sc->sc_ecdev == NULL) 695 if (sc->sc_ecdev == NULL)
650 return; /* no chance of this working */ 696 return; /* no chance of this working */
651 697
652 sc->sc_sme = sysmon_envsys_create(); 698 sc->sc_sme = sysmon_envsys_create();
653 699
654 for (i = j = 0; i < THINKPAD_NTEMPSENSORS; i++) { 700 for (i = j = 0; i < THINKPAD_NTEMPSENSORS; i++) {
655 701
656 sc->sc_sensor[i].units = ENVSYS_STEMP; 702 sc->sc_sensor[i].units = ENVSYS_STEMP;
657 sc->sc_sensor[i].state = ENVSYS_SINVALID; 703 sc->sc_sensor[i].state = ENVSYS_SINVALID;
658 sc->sc_sensor[i].flags = ENVSYS_FHAS_ENTROPY; 704 sc->sc_sensor[i].flags = ENVSYS_FHAS_ENTROPY;
659 705
660 (void)snprintf(sc->sc_sensor[i].desc, 706 (void)snprintf(sc->sc_sensor[i].desc,
661 sizeof(sc->sc_sensor[i].desc), "temperature %d", i); 707 sizeof(sc->sc_sensor[i].desc), "temperature %d", i);
662 708
663 if (sysmon_envsys_sensor_attach(sc->sc_sme, 709 if (sysmon_envsys_sensor_attach(sc->sc_sme,
664 &sc->sc_sensor[i]) != 0) 710 &sc->sc_sensor[i]) != 0)
665 goto fail; 711 goto fail;
666 } 712 }
667 713
668 for (i = THINKPAD_NTEMPSENSORS; i < THINKPAD_NSENSORS; i++, j++) { 714 for (i = THINKPAD_NTEMPSENSORS; i < THINKPAD_NSENSORS; i++, j++) {
669 715
670 sc->sc_sensor[i].units = ENVSYS_SFANRPM; 716 sc->sc_sensor[i].units = ENVSYS_SFANRPM;
671 sc->sc_sensor[i].state = ENVSYS_SINVALID; 717 sc->sc_sensor[i].state = ENVSYS_SINVALID;
672 sc->sc_sensor[i].flags = ENVSYS_FHAS_ENTROPY; 718 sc->sc_sensor[i].flags = ENVSYS_FHAS_ENTROPY;
673 719
674 (void)snprintf(sc->sc_sensor[i].desc, 720 (void)snprintf(sc->sc_sensor[i].desc,
675 sizeof(sc->sc_sensor[i].desc), "fan speed %d", j); 721 sizeof(sc->sc_sensor[i].desc), "fan speed %d", j);
676 722
677 if (sysmon_envsys_sensor_attach(sc->sc_sme, 723 if (sysmon_envsys_sensor_attach(sc->sc_sme,
678 &sc->sc_sensor[i]) != 0) 724 &sc->sc_sensor[i]) != 0)
679 goto fail; 725 goto fail;
680 } 726 }
681 727
682 sc->sc_sme->sme_name = device_xname(sc->sc_dev); 728 sc->sc_sme->sme_name = device_xname(sc->sc_dev);
683 sc->sc_sme->sme_cookie = sc; 729 sc->sc_sme->sme_cookie = sc;
684 sc->sc_sme->sme_refresh = thinkpad_sensors_refresh; 730 sc->sc_sme->sme_refresh = thinkpad_sensors_refresh;
685 731
686 if (sysmon_envsys_register(sc->sc_sme) != 0) 732 if (sysmon_envsys_register(sc->sc_sme) != 0)
687 goto fail; 733 goto fail;
688 734
689 return; 735 return;
690 736
691fail: 737fail:
692 aprint_error_dev(sc->sc_dev, "failed to initialize sysmon\n"); 738 aprint_error_dev(sc->sc_dev, "failed to initialize sysmon\n");
693 sysmon_envsys_destroy(sc->sc_sme); 739 sysmon_envsys_destroy(sc->sc_sme);
694 sc->sc_sme = NULL; 740 sc->sc_sme = NULL;
695} 741}
696 742
697static void 743static void
698thinkpad_sensors_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 744thinkpad_sensors_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
699{ 745{
700 switch (edata->units) { 746 switch (edata->units) {
701 case ENVSYS_STEMP: 747 case ENVSYS_STEMP:
702 thinkpad_temp_refresh(sme, edata); 748 thinkpad_temp_refresh(sme, edata);
703 break; 749 break;
704 case ENVSYS_SFANRPM: 750 case ENVSYS_SFANRPM:
705 thinkpad_fan_refresh(sme, edata); 751 thinkpad_fan_refresh(sme, edata);
706 break; 752 break;
707 default: 753 default:
708 break; 754 break;
709 } 755 }
710} 756}
711 757
712static void 758static void
713thinkpad_temp_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 759thinkpad_temp_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
714{ 760{
715 thinkpad_softc_t *sc = sme->sme_cookie; 761 thinkpad_softc_t *sc = sme->sme_cookie;
716 char sname[5] = "TMP?"; 762 char sname[5] = "TMP?";
717 ACPI_INTEGER val; 763 ACPI_INTEGER val;
718 ACPI_STATUS rv; 764 ACPI_STATUS rv;
719 int temp; 765 int temp;
720 766
721 sname[3] = '0' + edata->sensor; 767 sname[3] = '0' + edata->sensor;
722 rv = acpi_eval_integer(acpiec_get_handle(sc->sc_ecdev), sname, &val); 768 rv = acpi_eval_integer(acpiec_get_handle(sc->sc_ecdev), sname, &val);
723 if (ACPI_FAILURE(rv)) { 769 if (ACPI_FAILURE(rv)) {
724 edata->state = ENVSYS_SINVALID; 770 edata->state = ENVSYS_SINVALID;
725 return; 771 return;
726 } 772 }
727 temp = (int)val; 773 temp = (int)val;
728 if (temp > 127 || temp < -127) { 774 if (temp > 127 || temp < -127) {
729 edata->state = ENVSYS_SINVALID; 775 edata->state = ENVSYS_SINVALID;
730 return; 776 return;
731 } 777 }
732 778
733 edata->value_cur = temp * 1000000 + 273150000; 779 edata->value_cur = temp * 1000000 + 273150000;
734 edata->state = ENVSYS_SVALID; 780 edata->state = ENVSYS_SVALID;
735} 781}
736 782
737static void 783static void
738thinkpad_fan_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 784thinkpad_fan_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
739{ 785{
740 thinkpad_softc_t *sc = sme->sme_cookie; 786 thinkpad_softc_t *sc = sme->sme_cookie;
741 ACPI_INTEGER lo; 787 ACPI_INTEGER lo;
742 ACPI_INTEGER hi; 788 ACPI_INTEGER hi;
743 ACPI_STATUS rv; 789 ACPI_STATUS rv;
744 int rpm; 790 int rpm;
745 791
746 /* 792 /*
747 * Read the low byte first to avoid a firmware bug. 793 * Read the low byte first to avoid a firmware bug.
748 */ 794 */
749 rv = acpiec_bus_read(sc->sc_ecdev, 0x84, &lo, 1); 795 rv = acpiec_bus_read(sc->sc_ecdev, 0x84, &lo, 1);
750 if (ACPI_FAILURE(rv)) { 796 if (ACPI_FAILURE(rv)) {
751 edata->state = ENVSYS_SINVALID; 797 edata->state = ENVSYS_SINVALID;
752 return; 798 return;
753 } 799 }
754 rv = acpiec_bus_read(sc->sc_ecdev, 0x85, &hi, 1); 800 rv = acpiec_bus_read(sc->sc_ecdev, 0x85, &hi, 1);
755 if (ACPI_FAILURE(rv)) { 801 if (ACPI_FAILURE(rv)) {
756 edata->state = ENVSYS_SINVALID; 802 edata->state = ENVSYS_SINVALID;
757 return; 803 return;
758 } 804 }
759 805
760 /* 806 /*
761 * Extract the low bytes from buffers 807 * Extract the low bytes from buffers
762 */ 808 */
763 lo = ((uint8_t *)&lo)[0]; 809 lo = ((uint8_t *)&lo)[0];
764 hi = ((uint8_t *)&hi)[0]; 810 hi = ((uint8_t *)&hi)[0];
765 811
766 rpm = ((((int)hi) << 8) | ((int)lo)); 812 rpm = ((((int)hi) << 8) | ((int)lo));
767 if (rpm < 0) { 813 if (rpm < 0) {
768 edata->state = ENVSYS_SINVALID; 814 edata->state = ENVSYS_SINVALID;
769 return; 815 return;
770 } 816 }
771 817
772 edata->value_cur = rpm; 818 edata->value_cur = rpm;
773 edata->state = ENVSYS_SVALID; 819 edata->state = ENVSYS_SVALID;
774} 820}
775 821
776static void 822static void
777thinkpad_bluetooth_toggle(thinkpad_softc_t *sc) 823thinkpad_bluetooth_toggle(thinkpad_softc_t *sc)
778{ 824{
779 ACPI_BUFFER buf; 825 ACPI_BUFFER buf;
780 ACPI_OBJECT retobj; 826 ACPI_OBJECT retobj;
781 ACPI_OBJECT param[1]; 827 ACPI_OBJECT param[1];
782 ACPI_OBJECT_LIST params; 828 ACPI_OBJECT_LIST params;
783 ACPI_STATUS rv; 829 ACPI_STATUS rv;
784 830
785 /* Ignore return value, as the hardware may not support bluetooth */ 831 /* Ignore return value, as the hardware may not support bluetooth */
786 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "BTGL", NULL, NULL); 832 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "BTGL", NULL, NULL);
787 if (!ACPI_FAILURE(rv)) 833 if (!ACPI_FAILURE(rv))
788 return; 834 return;
789 835
790 buf.Pointer = &retobj; 836 buf.Pointer = &retobj;
791 buf.Length = sizeof(retobj); 837 buf.Length = sizeof(retobj);
792 838
793 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "GBDC", NULL, &buf); 839 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "GBDC", NULL, &buf);
794 if (ACPI_FAILURE(rv)) 840 if (ACPI_FAILURE(rv))
795 return; 841 return;
796 842
797 params.Count = 1; 843 params.Count = 1;
798 params.Pointer = param; 844 params.Pointer = param;
799 param[0].Type = ACPI_TYPE_INTEGER; 845 param[0].Type = ACPI_TYPE_INTEGER;
800 param[0].Integer.Value = 846 param[0].Integer.Value =
801 (retobj.Integer.Value & THINKPAD_BLUETOOTH_RADIOSSW) == 0 847 (retobj.Integer.Value & THINKPAD_BLUETOOTH_RADIOSSW) == 0
802 ? THINKPAD_BLUETOOTH_RADIOSSW | THINKPAD_BLUETOOTH_RESUMECTRL 848 ? THINKPAD_BLUETOOTH_RADIOSSW | THINKPAD_BLUETOOTH_RESUMECTRL
803 : 0; 849 : 0;
804 850
805 (void)AcpiEvaluateObject(sc->sc_node->ad_handle, "SBDC", &params, NULL); 851 (void)AcpiEvaluateObject(sc->sc_node->ad_handle, "SBDC", &params, NULL);
806} 852}
807 853
808static void 854static void
809thinkpad_wwan_toggle(thinkpad_softc_t *sc) 855thinkpad_wwan_toggle(thinkpad_softc_t *sc)
810{ 856{
811 ACPI_BUFFER buf; 857 ACPI_BUFFER buf;
812 ACPI_OBJECT retobj; 858 ACPI_OBJECT retobj;
813 ACPI_OBJECT param[1]; 859 ACPI_OBJECT param[1];
814 ACPI_OBJECT_LIST params; 860 ACPI_OBJECT_LIST params;
815 ACPI_STATUS rv; 861 ACPI_STATUS rv;
816 862
817 buf.Pointer = &retobj; 863 buf.Pointer = &retobj;
818 buf.Length = sizeof(retobj); 864 buf.Length = sizeof(retobj);
819 865
820 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "GWAN", NULL, &buf); 866 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "GWAN", NULL, &buf);
821 if (ACPI_FAILURE(rv)) 867 if (ACPI_FAILURE(rv))
822 return; 868 return;
823 869
824 params.Count = 1; 870 params.Count = 1;
825 params.Pointer = param; 871 params.Pointer = param;
826 param[0].Type = ACPI_TYPE_INTEGER; 872 param[0].Type = ACPI_TYPE_INTEGER;
827 param[0].Integer.Value = 873 param[0].Integer.Value =
828 (retobj.Integer.Value & THINKPAD_WWAN_RADIOSSW) == 0 874 (retobj.Integer.Value & THINKPAD_WWAN_RADIOSSW) == 0
829 ? THINKPAD_WWAN_RADIOSSW | THINKPAD_WWAN_RESUMECTRL 875 ? THINKPAD_WWAN_RADIOSSW | THINKPAD_WWAN_RESUMECTRL
830 : 0; 876 : 0;
831 877
832 (void)AcpiEvaluateObject(sc->sc_node->ad_handle, "SWAN", &params, NULL); 878 (void)AcpiEvaluateObject(sc->sc_node->ad_handle, "SWAN", &params, NULL);
833} 879}
834 880
835static void 881static void
836thinkpad_uwb_toggle(thinkpad_softc_t *sc) 882thinkpad_uwb_toggle(thinkpad_softc_t *sc)
837{ 883{
838 ACPI_BUFFER buf; 884 ACPI_BUFFER buf;
839 ACPI_OBJECT retobj; 885 ACPI_OBJECT retobj;
840 ACPI_OBJECT param[1]; 886 ACPI_OBJECT param[1];
841 ACPI_OBJECT_LIST params; 887 ACPI_OBJECT_LIST params;
842 ACPI_STATUS rv; 888 ACPI_STATUS rv;
843 889
844 buf.Pointer = &retobj; 890 buf.Pointer = &retobj;
845 buf.Length = sizeof(retobj); 891 buf.Length = sizeof(retobj);
846 892
847 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "GUWB", NULL, &buf); 893 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "GUWB", NULL, &buf);
848 if (ACPI_FAILURE(rv)) 894 if (ACPI_FAILURE(rv))
849 return; 895 return;
850 896
851 params.Count = 1; 897 params.Count = 1;
852 params.Pointer = param; 898 params.Pointer = param;
853 param[0].Type = ACPI_TYPE_INTEGER; 899 param[0].Type = ACPI_TYPE_INTEGER;
854 param[0].Integer.Value = 900 param[0].Integer.Value =
855 (retobj.Integer.Value & THINKPAD_UWB_RADIOSSW) == 0 901 (retobj.Integer.Value & THINKPAD_UWB_RADIOSSW) == 0
856 ? THINKPAD_UWB_RADIOSSW 902 ? THINKPAD_UWB_RADIOSSW
857 : 0; 903 : 0;
858 904
859 (void)AcpiEvaluateObject(sc->sc_node->ad_handle, "SUWB", &params, NULL); 905 (void)AcpiEvaluateObject(sc->sc_node->ad_handle, "SUWB", &params, NULL);
860} 906}
861 907
862static uint8_t 908static uint8_t
863thinkpad_brightness_read(thinkpad_softc_t *sc) 909thinkpad_brightness_read(thinkpad_softc_t *sc)
864{ 910{
865 uint32_t val = 0; 911 uint32_t val = 0;
866 912
867 AcpiOsWritePort(IO_RTC, 0x6c, 8); 913 AcpiOsWritePort(IO_RTC, 0x6c, 8);
868 AcpiOsReadPort(IO_RTC + 1, &val, 8); 914 AcpiOsReadPort(IO_RTC + 1, &val, 8);
869 915
870 return val & 7; 916 return val & 7;
871} 917}
872 918
873static void 919static void
874thinkpad_brightness_up(device_t self) 920thinkpad_brightness_up(device_t self)
875{ 921{
876 thinkpad_softc_t *sc = device_private(self); 922 thinkpad_softc_t *sc = device_private(self);
877 923
878 if (thinkpad_brightness_read(sc) == 7) 924 if (thinkpad_brightness_read(sc) == 7)
879 return; 925 return;
880 926
881 thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_UP); 927 thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_UP);
882} 928}
883 929
884static void 930static void
885thinkpad_brightness_down(device_t self) 931thinkpad_brightness_down(device_t self)
886{ 932{
887 thinkpad_softc_t *sc = device_private(self); 933 thinkpad_softc_t *sc = device_private(self);
888 934
889 if (thinkpad_brightness_read(sc) == 0) 935 if (thinkpad_brightness_read(sc) == 0)
890 return; 936 return;
891 937
892 thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_DOWN); 938 thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_DOWN);
893} 939}
894 940
895static void 941static void
896thinkpad_cmos(thinkpad_softc_t *sc, uint8_t cmd) 942thinkpad_cmos(thinkpad_softc_t *sc, uint8_t cmd)
897{ 943{
898 ACPI_STATUS rv; 944 ACPI_STATUS rv;
899 945
900 if (sc->sc_cmoshdl == NULL) 946 if (sc->sc_cmoshdl == NULL)
901 return; 947 return;
902 948
903 rv = acpi_eval_set_integer(sc->sc_cmoshdl, NULL, cmd); 949 rv = acpi_eval_set_integer(sc->sc_cmoshdl, NULL, cmd);
904 950
905 if (ACPI_FAILURE(rv)) 951 if (ACPI_FAILURE(rv))
906 aprint_error_dev(sc->sc_dev, "couldn't evaluate CMOS: %s\n", 952 aprint_error_dev(sc->sc_dev, "couldn't evaluate CMOS: %s\n",
907 AcpiFormatException(rv)); 953 AcpiFormatException(rv));
908} 954}
909 955
910static bool 956static bool
911thinkpad_resume(device_t dv, const pmf_qual_t *qual) 957thinkpad_resume(device_t dv, const pmf_qual_t *qual)
912{ 958{
913 thinkpad_softc_t *sc = device_private(dv); 959 thinkpad_softc_t *sc = device_private(dv);
914 960
915 if (sc->sc_powhdl == NULL) 961 if (sc->sc_powhdl == NULL)
916 return true; 962 return true;
917 963
918 (void)acpi_power_res(sc->sc_powhdl, sc->sc_node->ad_handle, true); 964 (void)acpi_power_res(sc->sc_powhdl, sc->sc_node->ad_handle, true);
919 965
920 return true; 966 return true;
921} 967}
922 968
923MODULE(MODULE_CLASS_DRIVER, thinkpad, "sysmon_envsys,sysmon_power"); 969MODULE(MODULE_CLASS_DRIVER, thinkpad, "sysmon_envsys,sysmon_power");
924 970
925#ifdef _MODULE 971#ifdef _MODULE
926#include "ioconf.c" 972#include "ioconf.c"
927#endif 973#endif
928 974
929static int 975static int
930thinkpad_modcmd(modcmd_t cmd, void *aux) 976thinkpad_modcmd(modcmd_t cmd, void *aux)
931{ 977{
932 int rv = 0; 978 int rv = 0;
933 979
934 switch (cmd) { 980 switch (cmd) {
935 981
936 case MODULE_CMD_INIT: 982 case MODULE_CMD_INIT:
937 983
938#ifdef _MODULE 984#ifdef _MODULE
939 rv = config_init_component(cfdriver_ioconf_thinkpad, 985 rv = config_init_component(cfdriver_ioconf_thinkpad,
940 cfattach_ioconf_thinkpad, cfdata_ioconf_thinkpad); 986 cfattach_ioconf_thinkpad, cfdata_ioconf_thinkpad);
941#endif 987#endif
942 break; 988 break;
943 989
944 case MODULE_CMD_FINI: 990 case MODULE_CMD_FINI:
945 991
946#ifdef _MODULE 992#ifdef _MODULE
947 rv = config_fini_component(cfdriver_ioconf_thinkpad, 993 rv = config_fini_component(cfdriver_ioconf_thinkpad,
948 cfattach_ioconf_thinkpad, cfdata_ioconf_thinkpad); 994 cfattach_ioconf_thinkpad, cfdata_ioconf_thinkpad);
949#endif 995#endif
950 break; 996 break;
951 997
952 default: 998 default:
953 rv = ENOTTY; 999 rv = ENOTTY;
954 } 1000 }
955 1001
956 return rv; 1002 return rv;
957} 1003}