1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Dell privacy notification driver 4 * 5 * Copyright (C) 2021 Dell Inc. All Rights Reserved. 6 */ 7 8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 10 #include <linux/acpi.h> 11 #include <linux/bitops.h> 12 #include <linux/input.h> 13 #include <linux/input/sparse-keymap.h> 14 #include <linux/list.h> 15 #include <linux/leds.h> 16 #include <linux/module.h> 17 #include <linux/wmi.h> 18 19 #include "dell-wmi-privacy.h" 20 21 #define DELL_PRIVACY_GUID "6932965F-1671-4CEB-B988-D3AB0A901919" 22 #define MICROPHONE_STATUS BIT(0) 23 #define CAMERA_STATUS BIT(1) 24 #define DELL_PRIVACY_AUDIO_EVENT 0x1 25 #define DELL_PRIVACY_CAMERA_EVENT 0x2 26 #define led_to_priv(c) container_of(c, struct privacy_wmi_data, cdev) 27 28 /* 29 * The wmi_list is used to store the privacy_priv struct with mutex protecting 30 */ 31 static LIST_HEAD(wmi_list); 32 static DEFINE_MUTEX(list_mutex); 33 34 struct privacy_wmi_data { 35 struct input_dev *input_dev; 36 struct wmi_device *wdev; 37 struct list_head list; 38 struct led_classdev cdev; 39 u32 features_present; 40 u32 last_status; 41 }; 42 43 /* DELL Privacy Type */ 44 enum dell_hardware_privacy_type { 45 DELL_PRIVACY_TYPE_AUDIO = 0, 46 DELL_PRIVACY_TYPE_CAMERA, 47 DELL_PRIVACY_TYPE_SCREEN, 48 DELL_PRIVACY_TYPE_MAX, 49 }; 50 51 static const char * const privacy_types[DELL_PRIVACY_TYPE_MAX] = { 52 [DELL_PRIVACY_TYPE_AUDIO] = "Microphone", 53 [DELL_PRIVACY_TYPE_CAMERA] = "Camera Shutter", 54 [DELL_PRIVACY_TYPE_SCREEN] = "ePrivacy Screen", 55 }; 56 57 /* 58 * Keymap for WMI privacy events of type 0x0012 59 */ 60 static const struct key_entry dell_wmi_keymap_type_0012[] = { 61 /* privacy mic mute */ 62 { KE_KEY, 0x0001, { KEY_MICMUTE } }, 63 /* privacy camera mute */ 64 { KE_VSW, 0x0002, { SW_CAMERA_LENS_COVER } }, 65 { KE_END, 0}, 66 }; 67 68 bool dell_privacy_has_mic_mute(void) 69 { 70 struct privacy_wmi_data *priv; 71 72 mutex_lock(&list_mutex); 73 priv = list_first_entry_or_null(&wmi_list, 74 struct privacy_wmi_data, 75 list); 76 mutex_unlock(&list_mutex); 77 78 return priv && (priv->features_present & BIT(DELL_PRIVACY_TYPE_AUDIO)); 79 } 80 EXPORT_SYMBOL_GPL(dell_privacy_has_mic_mute); 81 82 /* 83 * The flow of privacy event: 84 * 1) User presses key. HW does stuff with this key (timeout is started) 85 * 2) WMI event is emitted from BIOS 86 * 3) WMI event is received by dell-privacy 87 * 4) KEY_MICMUTE emitted from dell-privacy 88 * 5) Userland picks up key and modifies kcontrol for SW mute 89 * 6) Codec kernel driver catches and calls ledtrig_audio_set which will call 90 * led_set_brightness() on the LED registered by dell_privacy_leds_setup() 91 * 7) dell-privacy notifies EC, the timeout is cancelled and the HW mute activates. 92 * If the EC is not notified then the HW mic mute will activate when the timeout 93 * triggers, just a bit later than with the active ack. 94 */ 95 bool dell_privacy_process_event(int type, int code, int status) 96 { 97 struct privacy_wmi_data *priv; 98 const struct key_entry *key; 99 bool ret = false; 100 101 mutex_lock(&list_mutex); 102 priv = list_first_entry_or_null(&wmi_list, 103 struct privacy_wmi_data, 104 list); 105 if (!priv) 106 goto error; 107 108 key = sparse_keymap_entry_from_scancode(priv->input_dev, (type << 16) | code); 109 if (!key) { 110 dev_warn(&priv->wdev->dev, "Unknown key with type 0x%04x and code 0x%04x pressed\n", 111 type, code); 112 goto error; 113 } 114 dev_dbg(&priv->wdev->dev, "Key with type 0x%04x and code 0x%04x pressed\n", type, code); 115 116 switch (code) { 117 case DELL_PRIVACY_AUDIO_EVENT: /* Mic mute */ 118 priv->last_status = status; 119 sparse_keymap_report_entry(priv->input_dev, key, 1, true); 120 ret = true; 121 break; 122 case DELL_PRIVACY_CAMERA_EVENT: /* Camera mute */ 123 priv->last_status = status; 124 sparse_keymap_report_entry(priv->input_dev, key, !(status & CAMERA_STATUS), false); 125 ret = true; 126 break; 127 default: 128 dev_dbg(&priv->wdev->dev, "unknown event type 0x%04x 0x%04x\n", type, code); 129 } 130 131 error: 132 mutex_unlock(&list_mutex); 133 return ret; 134 } 135 136 static ssize_t dell_privacy_supported_type_show(struct device *dev, 137 struct device_attribute *attr, 138 char *buf) 139 { 140 struct privacy_wmi_data *priv = dev_get_drvdata(dev); 141 enum dell_hardware_privacy_type type; 142 u32 privacy_list; 143 int len = 0; 144 145 privacy_list = priv->features_present; 146 for (type = DELL_PRIVACY_TYPE_AUDIO; type < DELL_PRIVACY_TYPE_MAX; type++) { 147 if (privacy_list & BIT(type)) 148 len += sysfs_emit_at(buf, len, "[%s] [supported]\n", privacy_types[type]); 149 else 150 len += sysfs_emit_at(buf, len, "[%s] [unsupported]\n", privacy_types[type]); 151 } 152 153 return len; 154 } 155 156 static ssize_t dell_privacy_current_state_show(struct device *dev, 157 struct device_attribute *attr, 158 char *buf) 159 { 160 struct privacy_wmi_data *priv = dev_get_drvdata(dev); 161 u32 privacy_supported = priv->features_present; 162 enum dell_hardware_privacy_type type; 163 u32 privacy_state = priv->last_status; 164 int len = 0; 165 166 for (type = DELL_PRIVACY_TYPE_AUDIO; type < DELL_PRIVACY_TYPE_MAX; type++) { 167 if (privacy_supported & BIT(type)) { 168 if (privacy_state & BIT(type)) 169 len += sysfs_emit_at(buf, len, "[%s] [unmuted]\n", privacy_types[type]); 170 else 171 len += sysfs_emit_at(buf, len, "[%s] [muted]\n", privacy_types[type]); 172 } 173 } 174 175 return len; 176 } 177 178 static DEVICE_ATTR_RO(dell_privacy_supported_type); 179 static DEVICE_ATTR_RO(dell_privacy_current_state); 180 181 static struct attribute *privacy_attrs[] = { 182 &dev_attr_dell_privacy_supported_type.attr, 183 &dev_attr_dell_privacy_current_state.attr, 184 NULL, 185 }; 186 ATTRIBUTE_GROUPS(privacy); 187 188 /* 189 * Describes the Device State class exposed by BIOS which can be consumed by 190 * various applications interested in knowing the Privacy feature capabilities. 191 * class DeviceState 192 * { 193 * [key, read] string InstanceName; 194 * [read] boolean ReadOnly; 195 * 196 * [WmiDataId(1), read] uint32 DevicesSupported; 197 * 0 - None; 0x1 - Microphone; 0x2 - Camera; 0x4 - ePrivacy Screen 198 * 199 * [WmiDataId(2), read] uint32 CurrentState; 200 * 0 - Off; 1 - On; Bit0 - Microphone; Bit1 - Camera; Bit2 - ePrivacyScreen 201 * }; 202 */ 203 static int get_current_status(struct wmi_device *wdev) 204 { 205 struct privacy_wmi_data *priv = dev_get_drvdata(&wdev->dev); 206 union acpi_object *obj_present; 207 u32 *buffer; 208 int ret = 0; 209 210 if (!priv) { 211 dev_err(&wdev->dev, "dell privacy priv is NULL\n"); 212 return -EINVAL; 213 } 214 /* check privacy support features and device states */ 215 obj_present = wmidev_block_query(wdev, 0); 216 if (!obj_present) { 217 dev_err(&wdev->dev, "failed to read Binary MOF\n"); 218 return -EIO; 219 } 220 221 if (obj_present->type != ACPI_TYPE_BUFFER) { 222 dev_err(&wdev->dev, "Binary MOF is not a buffer!\n"); 223 ret = -EIO; 224 goto obj_free; 225 } 226 /* Although it's not technically a failure, this would lead to 227 * unexpected behavior 228 */ 229 if (obj_present->buffer.length != 8) { 230 dev_err(&wdev->dev, "Dell privacy buffer has unexpected length (%d)!\n", 231 obj_present->buffer.length); 232 ret = -EINVAL; 233 goto obj_free; 234 } 235 buffer = (u32 *)obj_present->buffer.pointer; 236 priv->features_present = buffer[0]; 237 priv->last_status = buffer[1]; 238 239 obj_free: 240 kfree(obj_present); 241 return ret; 242 } 243 244 static int dell_privacy_micmute_led_set(struct led_classdev *led_cdev, 245 enum led_brightness brightness) 246 { 247 struct privacy_wmi_data *priv = led_to_priv(led_cdev); 248 static char *acpi_method = (char *)"ECAK"; 249 acpi_status status; 250 acpi_handle handle; 251 252 handle = ec_get_handle(); 253 if (!handle) 254 return -EIO; 255 256 if (!acpi_has_method(handle, acpi_method)) 257 return -EIO; 258 259 status = acpi_evaluate_object(handle, acpi_method, NULL, NULL); 260 if (ACPI_FAILURE(status)) { 261 dev_err(&priv->wdev->dev, "Error setting privacy EC ack value: %s\n", 262 acpi_format_exception(status)); 263 return -EIO; 264 } 265 266 return 0; 267 } 268 269 /* 270 * Pressing the mute key activates a time delayed circuit to physically cut 271 * off the mute. The LED is in the same circuit, so it reflects the true 272 * state of the HW mute. The reason for the EC "ack" is so that software 273 * can first invoke a SW mute before the HW circuit is cut off. Without SW 274 * cutting this off first does not affect the time delayed muting or status 275 * of the LED but there is a possibility of a "popping" noise. 276 * 277 * If the EC receives the SW ack, the circuit will be activated before the 278 * delay completed. 279 * 280 * Exposing as an LED device allows the codec drivers notification path to 281 * EC ACK to work 282 */ 283 static int dell_privacy_leds_setup(struct device *dev) 284 { 285 struct privacy_wmi_data *priv = dev_get_drvdata(dev); 286 287 priv->cdev.name = "dell-privacy::micmute"; 288 priv->cdev.max_brightness = 1; 289 priv->cdev.brightness_set_blocking = dell_privacy_micmute_led_set; 290 priv->cdev.default_trigger = "audio-micmute"; 291 return devm_led_classdev_register(dev, &priv->cdev); 292 } 293 294 static int dell_privacy_wmi_probe(struct wmi_device *wdev, const void *context) 295 { 296 struct privacy_wmi_data *priv; 297 struct key_entry *keymap; 298 int ret, i, j; 299 300 priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL); 301 if (!priv) 302 return -ENOMEM; 303 304 dev_set_drvdata(&wdev->dev, priv); 305 priv->wdev = wdev; 306 307 ret = get_current_status(priv->wdev); 308 if (ret) 309 return ret; 310 311 /* create evdev passing interface */ 312 priv->input_dev = devm_input_allocate_device(&wdev->dev); 313 if (!priv->input_dev) 314 return -ENOMEM; 315 316 /* remap the wmi keymap event to new keymap */ 317 keymap = kcalloc(ARRAY_SIZE(dell_wmi_keymap_type_0012), 318 sizeof(struct key_entry), GFP_KERNEL); 319 if (!keymap) 320 return -ENOMEM; 321 322 /* remap the keymap code with Dell privacy key type 0x12 as prefix 323 * KEY_MICMUTE scancode will be reported as 0x120001 324 */ 325 for (i = 0, j = 0; i < ARRAY_SIZE(dell_wmi_keymap_type_0012); i++) { 326 /* 327 * Unlike keys where only presses matter, userspace may act 328 * on switches in both of their positions. Only register 329 * SW_CAMERA_LENS_COVER if it is actually there. 330 */ 331 if (dell_wmi_keymap_type_0012[i].type == KE_VSW && 332 dell_wmi_keymap_type_0012[i].sw.code == SW_CAMERA_LENS_COVER && 333 !(priv->features_present & BIT(DELL_PRIVACY_TYPE_CAMERA))) 334 continue; 335 336 keymap[j] = dell_wmi_keymap_type_0012[i]; 337 keymap[j].code |= (0x0012 << 16); 338 j++; 339 } 340 ret = sparse_keymap_setup(priv->input_dev, keymap, NULL); 341 kfree(keymap); 342 if (ret) 343 return ret; 344 345 priv->input_dev->dev.parent = &wdev->dev; 346 priv->input_dev->name = "Dell Privacy Driver"; 347 priv->input_dev->id.bustype = BUS_HOST; 348 349 /* Report initial camera-cover status */ 350 if (priv->features_present & BIT(DELL_PRIVACY_TYPE_CAMERA)) 351 input_report_switch(priv->input_dev, SW_CAMERA_LENS_COVER, 352 !(priv->last_status & CAMERA_STATUS)); 353 354 ret = input_register_device(priv->input_dev); 355 if (ret) 356 return ret; 357 358 if (priv->features_present & BIT(DELL_PRIVACY_TYPE_AUDIO)) { 359 ret = dell_privacy_leds_setup(&priv->wdev->dev); 360 if (ret) 361 return ret; 362 } 363 mutex_lock(&list_mutex); 364 list_add_tail(&priv->list, &wmi_list); 365 mutex_unlock(&list_mutex); 366 return 0; 367 } 368 369 static void dell_privacy_wmi_remove(struct wmi_device *wdev) 370 { 371 struct privacy_wmi_data *priv = dev_get_drvdata(&wdev->dev); 372 373 mutex_lock(&list_mutex); 374 list_del(&priv->list); 375 mutex_unlock(&list_mutex); 376 } 377 378 static const struct wmi_device_id dell_wmi_privacy_wmi_id_table[] = { 379 { .guid_string = DELL_PRIVACY_GUID }, 380 { }, 381 }; 382 383 static struct wmi_driver dell_privacy_wmi_driver = { 384 .driver = { 385 .name = "dell-privacy", 386 .dev_groups = privacy_groups, 387 }, 388 .probe = dell_privacy_wmi_probe, 389 .remove = dell_privacy_wmi_remove, 390 .id_table = dell_wmi_privacy_wmi_id_table, 391 }; 392 393 int dell_privacy_register_driver(void) 394 { 395 return wmi_driver_register(&dell_privacy_wmi_driver); 396 } 397 398 void dell_privacy_unregister_driver(void) 399 { 400 wmi_driver_unregister(&dell_privacy_wmi_driver); 401 } 402