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_SW, 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 case DELL_PRIVACY_CAMERA_EVENT: /* Camera mute */ 119 priv->last_status = status; 120 sparse_keymap_report_entry(priv->input_dev, key, 1, true); 121 ret = true; 122 break; 123 default: 124 dev_dbg(&priv->wdev->dev, "unknown event type 0x%04x 0x%04x\n", type, code); 125 } 126 127 error: 128 mutex_unlock(&list_mutex); 129 return ret; 130 } 131 132 static ssize_t dell_privacy_supported_type_show(struct device *dev, 133 struct device_attribute *attr, 134 char *buf) 135 { 136 struct privacy_wmi_data *priv = dev_get_drvdata(dev); 137 enum dell_hardware_privacy_type type; 138 u32 privacy_list; 139 int len = 0; 140 141 privacy_list = priv->features_present; 142 for (type = DELL_PRIVACY_TYPE_AUDIO; type < DELL_PRIVACY_TYPE_MAX; type++) { 143 if (privacy_list & BIT(type)) 144 len += sysfs_emit_at(buf, len, "[%s] [supported]\n", privacy_types[type]); 145 else 146 len += sysfs_emit_at(buf, len, "[%s] [unsupported]\n", privacy_types[type]); 147 } 148 149 return len; 150 } 151 152 static ssize_t dell_privacy_current_state_show(struct device *dev, 153 struct device_attribute *attr, 154 char *buf) 155 { 156 struct privacy_wmi_data *priv = dev_get_drvdata(dev); 157 u32 privacy_supported = priv->features_present; 158 enum dell_hardware_privacy_type type; 159 u32 privacy_state = priv->last_status; 160 int len = 0; 161 162 for (type = DELL_PRIVACY_TYPE_AUDIO; type < DELL_PRIVACY_TYPE_MAX; type++) { 163 if (privacy_supported & BIT(type)) { 164 if (privacy_state & BIT(type)) 165 len += sysfs_emit_at(buf, len, "[%s] [unmuted]\n", privacy_types[type]); 166 else 167 len += sysfs_emit_at(buf, len, "[%s] [muted]\n", privacy_types[type]); 168 } 169 } 170 171 return len; 172 } 173 174 static DEVICE_ATTR_RO(dell_privacy_supported_type); 175 static DEVICE_ATTR_RO(dell_privacy_current_state); 176 177 static struct attribute *privacy_attrs[] = { 178 &dev_attr_dell_privacy_supported_type.attr, 179 &dev_attr_dell_privacy_current_state.attr, 180 NULL, 181 }; 182 ATTRIBUTE_GROUPS(privacy); 183 184 /* 185 * Describes the Device State class exposed by BIOS which can be consumed by 186 * various applications interested in knowing the Privacy feature capabilities. 187 * class DeviceState 188 * { 189 * [key, read] string InstanceName; 190 * [read] boolean ReadOnly; 191 * 192 * [WmiDataId(1), read] uint32 DevicesSupported; 193 * 0 - None; 0x1 - Microphone; 0x2 - Camera; 0x4 - ePrivacy Screen 194 * 195 * [WmiDataId(2), read] uint32 CurrentState; 196 * 0 - Off; 1 - On; Bit0 - Microphone; Bit1 - Camera; Bit2 - ePrivacyScreen 197 * }; 198 */ 199 static int get_current_status(struct wmi_device *wdev) 200 { 201 struct privacy_wmi_data *priv = dev_get_drvdata(&wdev->dev); 202 union acpi_object *obj_present; 203 u32 *buffer; 204 int ret = 0; 205 206 if (!priv) { 207 dev_err(&wdev->dev, "dell privacy priv is NULL\n"); 208 return -EINVAL; 209 } 210 /* check privacy support features and device states */ 211 obj_present = wmidev_block_query(wdev, 0); 212 if (!obj_present) { 213 dev_err(&wdev->dev, "failed to read Binary MOF\n"); 214 return -EIO; 215 } 216 217 if (obj_present->type != ACPI_TYPE_BUFFER) { 218 dev_err(&wdev->dev, "Binary MOF is not a buffer!\n"); 219 ret = -EIO; 220 goto obj_free; 221 } 222 /* Although it's not technically a failure, this would lead to 223 * unexpected behavior 224 */ 225 if (obj_present->buffer.length != 8) { 226 dev_err(&wdev->dev, "Dell privacy buffer has unexpected length (%d)!\n", 227 obj_present->buffer.length); 228 ret = -EINVAL; 229 goto obj_free; 230 } 231 buffer = (u32 *)obj_present->buffer.pointer; 232 priv->features_present = buffer[0]; 233 priv->last_status = buffer[1]; 234 235 obj_free: 236 kfree(obj_present); 237 return ret; 238 } 239 240 static int dell_privacy_micmute_led_set(struct led_classdev *led_cdev, 241 enum led_brightness brightness) 242 { 243 struct privacy_wmi_data *priv = led_to_priv(led_cdev); 244 static char *acpi_method = (char *)"ECAK"; 245 acpi_status status; 246 acpi_handle handle; 247 248 handle = ec_get_handle(); 249 if (!handle) 250 return -EIO; 251 252 if (!acpi_has_method(handle, acpi_method)) 253 return -EIO; 254 255 status = acpi_evaluate_object(handle, acpi_method, NULL, NULL); 256 if (ACPI_FAILURE(status)) { 257 dev_err(&priv->wdev->dev, "Error setting privacy EC ack value: %s\n", 258 acpi_format_exception(status)); 259 return -EIO; 260 } 261 262 return 0; 263 } 264 265 /* 266 * Pressing the mute key activates a time delayed circuit to physically cut 267 * off the mute. The LED is in the same circuit, so it reflects the true 268 * state of the HW mute. The reason for the EC "ack" is so that software 269 * can first invoke a SW mute before the HW circuit is cut off. Without SW 270 * cutting this off first does not affect the time delayed muting or status 271 * of the LED but there is a possibility of a "popping" noise. 272 * 273 * If the EC receives the SW ack, the circuit will be activated before the 274 * delay completed. 275 * 276 * Exposing as an LED device allows the codec drivers notification path to 277 * EC ACK to work 278 */ 279 static int dell_privacy_leds_setup(struct device *dev) 280 { 281 struct privacy_wmi_data *priv = dev_get_drvdata(dev); 282 283 priv->cdev.name = "dell-privacy::micmute"; 284 priv->cdev.max_brightness = 1; 285 priv->cdev.brightness_set_blocking = dell_privacy_micmute_led_set; 286 priv->cdev.default_trigger = "audio-micmute"; 287 priv->cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); 288 return devm_led_classdev_register(dev, &priv->cdev); 289 } 290 291 static int dell_privacy_wmi_probe(struct wmi_device *wdev, const void *context) 292 { 293 struct privacy_wmi_data *priv; 294 struct key_entry *keymap; 295 int ret, i; 296 297 ret = wmi_has_guid(DELL_PRIVACY_GUID); 298 if (!ret) 299 pr_debug("Unable to detect available Dell privacy devices!\n"); 300 301 priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL); 302 if (!priv) 303 return -ENOMEM; 304 305 dev_set_drvdata(&wdev->dev, priv); 306 priv->wdev = wdev; 307 /* create evdev passing interface */ 308 priv->input_dev = devm_input_allocate_device(&wdev->dev); 309 if (!priv->input_dev) 310 return -ENOMEM; 311 312 /* remap the wmi keymap event to new keymap */ 313 keymap = kcalloc(ARRAY_SIZE(dell_wmi_keymap_type_0012), 314 sizeof(struct key_entry), GFP_KERNEL); 315 if (!keymap) 316 return -ENOMEM; 317 318 /* remap the keymap code with Dell privacy key type 0x12 as prefix 319 * KEY_MICMUTE scancode will be reported as 0x120001 320 */ 321 for (i = 0; i < ARRAY_SIZE(dell_wmi_keymap_type_0012); i++) { 322 keymap[i] = dell_wmi_keymap_type_0012[i]; 323 keymap[i].code |= (0x0012 << 16); 324 } 325 ret = sparse_keymap_setup(priv->input_dev, keymap, NULL); 326 kfree(keymap); 327 if (ret) 328 return ret; 329 330 priv->input_dev->dev.parent = &wdev->dev; 331 priv->input_dev->name = "Dell Privacy Driver"; 332 priv->input_dev->id.bustype = BUS_HOST; 333 334 ret = input_register_device(priv->input_dev); 335 if (ret) 336 return ret; 337 338 ret = get_current_status(priv->wdev); 339 if (ret) 340 return ret; 341 342 if (priv->features_present & BIT(DELL_PRIVACY_TYPE_AUDIO)) { 343 ret = dell_privacy_leds_setup(&priv->wdev->dev); 344 if (ret) 345 return ret; 346 } 347 mutex_lock(&list_mutex); 348 list_add_tail(&priv->list, &wmi_list); 349 mutex_unlock(&list_mutex); 350 return 0; 351 } 352 353 static void dell_privacy_wmi_remove(struct wmi_device *wdev) 354 { 355 struct privacy_wmi_data *priv = dev_get_drvdata(&wdev->dev); 356 357 mutex_lock(&list_mutex); 358 list_del(&priv->list); 359 mutex_unlock(&list_mutex); 360 } 361 362 static const struct wmi_device_id dell_wmi_privacy_wmi_id_table[] = { 363 { .guid_string = DELL_PRIVACY_GUID }, 364 { }, 365 }; 366 367 static struct wmi_driver dell_privacy_wmi_driver = { 368 .driver = { 369 .name = "dell-privacy", 370 .dev_groups = privacy_groups, 371 }, 372 .probe = dell_privacy_wmi_probe, 373 .remove = dell_privacy_wmi_remove, 374 .id_table = dell_wmi_privacy_wmi_id_table, 375 }; 376 377 int dell_privacy_register_driver(void) 378 { 379 return wmi_driver_register(&dell_privacy_wmi_driver); 380 } 381 382 void dell_privacy_unregister_driver(void) 383 { 384 wmi_driver_unregister(&dell_privacy_wmi_driver); 385 } 386