diff options
Diffstat (limited to 'drivers/platform/x86/system76_acpi.c')
| -rw-r--r-- | drivers/platform/x86/system76_acpi.c | 74 | 
1 files changed, 59 insertions, 15 deletions
| diff --git a/drivers/platform/x86/system76_acpi.c b/drivers/platform/x86/system76_acpi.c index fc4708fa6ebe..3da753b3d00d 100644 --- a/drivers/platform/x86/system76_acpi.c +++ b/drivers/platform/x86/system76_acpi.c @@ -2,7 +2,7 @@  /*   * System76 ACPI Driver   * - * Copyright (C) 2019 System76 + * Copyright (C) 2023 System76   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License version 2 as @@ -24,6 +24,12 @@  #include <acpi/battery.h> +enum kbled_type { +	KBLED_NONE, +	KBLED_WHITE, +	KBLED_RGB, +}; +  struct system76_data {  	struct acpi_device *acpi_dev;  	struct led_classdev ap_led; @@ -36,6 +42,7 @@ struct system76_data {  	union acpi_object *ntmp;  	struct input_dev *input;  	bool has_open_ec; +	enum kbled_type kbled_type;  };  static const struct acpi_device_id device_ids[] = { @@ -327,7 +334,11 @@ static int kb_led_set(struct led_classdev *led, enum led_brightness value)  	data = container_of(led, struct system76_data, kb_led);  	data->kb_brightness = value; -	return system76_set(data, "SKBL", (int)data->kb_brightness); +	if (acpi_has_method(acpi_device_handle(data->acpi_dev), "GKBK")) { +		return system76_set(data, "SKBB", (int)data->kb_brightness); +	} else { +		return system76_set(data, "SKBL", (int)data->kb_brightness); +	}  }  // Get the last set keyboard LED color @@ -399,7 +410,12 @@ static void kb_led_hotkey_hardware(struct system76_data *data)  {  	int value; -	value = system76_get(data, "GKBL"); +	if (acpi_has_method(acpi_device_handle(data->acpi_dev), "GKBK")) { +		value = system76_get(data, "GKBB"); +	} else { +		value = system76_get(data, "GKBL"); +	} +  	if (value < 0)  		return;  	data->kb_brightness = value; @@ -459,8 +475,9 @@ static void kb_led_hotkey_color(struct system76_data *data)  {  	int i; -	if (data->kb_color < 0) +	if (data->kbled_type != KBLED_RGB)  		return; +  	if (data->kb_brightness > 0) {  		for (i = 0; i < ARRAY_SIZE(kb_colors); i++) {  			if (kb_colors[i] == data->kb_color) @@ -687,19 +704,46 @@ static int system76_add(struct acpi_device *acpi_dev)  	data->kb_led.flags = LED_BRIGHT_HW_CHANGED | LED_CORE_SUSPENDRESUME;  	data->kb_led.brightness_get = kb_led_get;  	data->kb_led.brightness_set_blocking = kb_led_set; -	if (acpi_has_method(acpi_device_handle(data->acpi_dev), "SKBC")) { -		data->kb_led.max_brightness = 255; -		data->kb_led.groups = system76_kb_led_color_groups; -		data->kb_toggle_brightness = 72; -		data->kb_color = 0xffffff; -		system76_set(data, "SKBC", data->kb_color); +	if (acpi_has_method(acpi_device_handle(data->acpi_dev), "GKBK")) { +		// Use the new ACPI methods +		data->kbled_type = system76_get(data, "GKBK"); + +		switch (data->kbled_type) { +		case KBLED_NONE: +			// Nothing to do: Device will not be registered. +			break; +		case KBLED_WHITE: +			data->kb_led.max_brightness = 255; +			data->kb_toggle_brightness = 72; +			break; +		case KBLED_RGB: +			data->kb_led.max_brightness = 255; +			data->kb_led.groups = system76_kb_led_color_groups; +			data->kb_toggle_brightness = 72; +			data->kb_color = 0xffffff; +			system76_set(data, "SKBC", data->kb_color); +			break; +		}  	} else { -		data->kb_led.max_brightness = 5; -		data->kb_color = -1; +		// Use the old ACPI methods +		if (acpi_has_method(acpi_device_handle(data->acpi_dev), "SKBC")) { +			data->kbled_type = KBLED_RGB; +			data->kb_led.max_brightness = 255; +			data->kb_led.groups = system76_kb_led_color_groups; +			data->kb_toggle_brightness = 72; +			data->kb_color = 0xffffff; +			system76_set(data, "SKBC", data->kb_color); +		} else { +			data->kbled_type = KBLED_WHITE; +			data->kb_led.max_brightness = 5; +		} +	} + +	if (data->kbled_type != KBLED_NONE) { +		err = devm_led_classdev_register(&acpi_dev->dev, &data->kb_led); +		if (err) +			return err;  	} -	err = devm_led_classdev_register(&acpi_dev->dev, &data->kb_led); -	if (err) -		return err;  	data->input = devm_input_allocate_device(&acpi_dev->dev);  	if (!data->input) |