drivers/platform/x86/lenovo/wmi-hotkey-utilities.c

Source file repositories/reference/linux-study-clean/drivers/platform/x86/lenovo/wmi-hotkey-utilities.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/x86/lenovo/wmi-hotkey-utilities.c
Extension
.c
Size
5763 bytes
Lines
225
Domain
Driver Families
Bucket
drivers/platform
Inferred role
Driver Families: implementation source
Status
source 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 wmi_led_args {
	u8 id;
	u8 subid;
	u16 value;
};

/* Values of input parameters to SetFeature of audio LED and Mic LED */
enum hotkey_set_feature {
	MIC_MUTE_LED_ON		= 1,
	MIC_MUTE_LED_OFF	= 2,
	AUDIO_MUTE_LED_ON	= 4,
	AUDIO_MUTE_LED_OFF	= 5,
};

#define LSH_ACPI_LED_MAX 2

struct lenovo_super_hotkey_wmi_private {
	struct led_classdev cdev[LSH_ACPI_LED_MAX];
	struct wmi_device *led_wdev;
};

enum mute_led_type {
	MIC_MUTE,
	AUDIO_MUTE,
};

static int lsh_wmi_mute_led_set(enum mute_led_type led_type, struct led_classdev *led_cdev,
				enum led_brightness brightness)

{
	struct lenovo_super_hotkey_wmi_private *wpriv = container_of(led_cdev,
			struct lenovo_super_hotkey_wmi_private, cdev[led_type]);
	struct wmi_led_args led_arg = {0, 0, 0};
	struct acpi_buffer input;
	acpi_status status;

	switch (led_type) {
	case MIC_MUTE:
		led_arg.id = brightness == LED_ON ? MIC_MUTE_LED_ON : MIC_MUTE_LED_OFF;
		break;
	case AUDIO_MUTE:
		led_arg.id = brightness == LED_ON ? AUDIO_MUTE_LED_ON : AUDIO_MUTE_LED_OFF;
		break;
	default:
		return -EINVAL;
	}

	input.length = sizeof(led_arg);
	input.pointer = &led_arg;
	status = wmidev_evaluate_method(wpriv->led_wdev, 0, WMI_LUD_SET_FEATURE, &input, NULL);
	if (ACPI_FAILURE(status))
		return -EIO;

	return 0;
}

static int lsh_wmi_audiomute_led_set(struct led_classdev *led_cdev,
				     enum led_brightness brightness)

{
	return lsh_wmi_mute_led_set(AUDIO_MUTE, led_cdev, brightness);
}

static int lsh_wmi_micmute_led_set(struct led_classdev *led_cdev,
				   enum led_brightness brightness)
{
	return lsh_wmi_mute_led_set(MIC_MUTE, led_cdev, brightness);
}

static int lenovo_super_hotkey_wmi_led_init(enum mute_led_type led_type, struct device *dev)
{
	struct lenovo_super_hotkey_wmi_private *wpriv = dev_get_drvdata(dev);
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer input;
	int led_version, err = 0;
	unsigned int wmiarg;
	acpi_status status;

	switch (led_type) {
	case MIC_MUTE:
		wmiarg = WMI_LUD_GET_MICMUTE_LED_VER;
		break;
	case AUDIO_MUTE:
		wmiarg = WMI_LUD_GET_AUDIOMUTE_LED_VER;
		break;
	default:
		return -EINVAL;
	}

	input.length = sizeof(wmiarg);

Annotation

Implementation Notes