drivers/platform/x86/dell/dell-wmi-privacy.c

Source file repositories/reference/linux-study-clean/drivers/platform/x86/dell/dell-wmi-privacy.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/x86/dell/dell-wmi-privacy.c
Extension
.c
Size
11370 bytes
Lines
402
Domain
Driver Families
Bucket
drivers/platform
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct privacy_wmi_data {
	struct input_dev *input_dev;
	struct wmi_device *wdev;
	struct list_head list;
	struct led_classdev cdev;
	u32 features_present;
	u32 last_status;
};

/* DELL Privacy Type */
enum dell_hardware_privacy_type {
	DELL_PRIVACY_TYPE_AUDIO = 0,
	DELL_PRIVACY_TYPE_CAMERA,
	DELL_PRIVACY_TYPE_SCREEN,
	DELL_PRIVACY_TYPE_MAX,
};

static const char * const privacy_types[DELL_PRIVACY_TYPE_MAX] = {
	[DELL_PRIVACY_TYPE_AUDIO] = "Microphone",
	[DELL_PRIVACY_TYPE_CAMERA] = "Camera Shutter",
	[DELL_PRIVACY_TYPE_SCREEN] = "ePrivacy Screen",
};

/*
 * Keymap for WMI privacy events of type 0x0012
 */
static const struct key_entry dell_wmi_keymap_type_0012[] = {
	/* privacy mic mute */
	{ KE_KEY, 0x0001, { KEY_MICMUTE } },
	/* privacy camera mute */
	{ KE_VSW, 0x0002, { SW_CAMERA_LENS_COVER } },
	{ KE_END, 0},
};

bool dell_privacy_has_mic_mute(void)
{
	struct privacy_wmi_data *priv;

	mutex_lock(&list_mutex);
	priv = list_first_entry_or_null(&wmi_list,
			struct privacy_wmi_data,
			list);
	mutex_unlock(&list_mutex);

	return priv && (priv->features_present & BIT(DELL_PRIVACY_TYPE_AUDIO));
}
EXPORT_SYMBOL_GPL(dell_privacy_has_mic_mute);

/*
 * The flow of privacy event:
 * 1) User presses key. HW does stuff with this key (timeout is started)
 * 2) WMI event is emitted from BIOS
 * 3) WMI event is received by dell-privacy
 * 4) KEY_MICMUTE emitted from dell-privacy
 * 5) Userland picks up key and modifies kcontrol for SW mute
 * 6) Codec kernel driver catches and calls ledtrig_audio_set which will call
 *    led_set_brightness() on the LED registered by dell_privacy_leds_setup()
 * 7) dell-privacy notifies EC, the timeout is cancelled and the HW mute activates.
 *    If the EC is not notified then the HW mic mute will activate when the timeout
 *    triggers, just a bit later than with the active ack.
 */
bool dell_privacy_process_event(int type, int code, int status)
{
	struct privacy_wmi_data *priv;
	const struct key_entry *key;
	bool ret = false;

	mutex_lock(&list_mutex);
	priv = list_first_entry_or_null(&wmi_list,
			struct privacy_wmi_data,
			list);
	if (!priv)
		goto error;

	key = sparse_keymap_entry_from_scancode(priv->input_dev, (type << 16) | code);
	if (!key) {
		dev_warn(&priv->wdev->dev, "Unknown key with type 0x%04x and code 0x%04x pressed\n",
			type, code);
		goto error;
	}
	dev_dbg(&priv->wdev->dev, "Key with type 0x%04x and code 0x%04x pressed\n", type, code);

	switch (code) {
	case DELL_PRIVACY_AUDIO_EVENT: /* Mic mute */
		priv->last_status = status;
		sparse_keymap_report_entry(priv->input_dev, key, 1, true);
		ret = true;
		break;
	case DELL_PRIVACY_CAMERA_EVENT: /* Camera mute */
		priv->last_status = status;

Annotation

Implementation Notes