From d3be79612af0d3f5a706dab594dbeac68a627964 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Wed, 24 Aug 2022 17:59:37 +0200 Subject: [PATCH] Fix crash --- src/Kbuild | 4 +- src/clevo_keyboard.h | 4 +- src/clevo_leds.c | 267 ------------------------------------- src/clevo_leds.h | 304 +++++++++++++++++++++++++++++++++++++++++++ tuxedo_keyboard.conf | 2 +- 5 files changed, 310 insertions(+), 271 deletions(-) diff --git a/src/Kbuild b/src/Kbuild index bcf4ac3..0d77606 100644 --- a/src/Kbuild +++ b/src/Kbuild @@ -4,5 +4,5 @@ obj-m := tuxedo_keyboard.o \ tuxedo_io/tuxedo_io.o \ uniwill_wmi.o -clevo_wmi-y := clevo_leds.o -clevo_acpi-y := clevo_leds.o +#clevo_wmi-y := clevo_leds.o +#clevo_acpi-y := clevo_leds.o diff --git a/src/clevo_keyboard.h b/src/clevo_keyboard.h index 80701f4..9dee864 100644 --- a/src/clevo_keyboard.h +++ b/src/clevo_keyboard.h @@ -419,8 +419,10 @@ int clevo_keyboard_init(void) static int clevo_keyboard_probe(struct platform_device *dev) { - clevo_keyboard_init_device_interface(dev); clevo_leds_init(dev); + // clevo_keyboard_init_device_interface() must come after clevo_leds_init() + // to know keyboard backlight type + clevo_keyboard_init_device_interface(dev); clevo_keyboard_init(); return 0; diff --git a/src/clevo_leds.c b/src/clevo_leds.c index 7cbd3bf..9310504 100644 --- a/src/clevo_leds.c +++ b/src/clevo_leds.c @@ -16,270 +16,3 @@ * You should have received a copy of the GNU General Public License * along with this software. If not, see . */ - -#include "clevo_leds.h" - -#include "clevo_interfaces.h" - -#include -#include - -#define CLEVO_KBD_BRIGHTNESS_MIN 0 -#define CLEVO_KBD_BRIGHTNESS_MAX 255 -#define CLEVO_KBD_BRIGHTNESS_DEFAULT (CLEVO_KBD_BRIGHTNESS_MAX * 0.5) - -#define CLEVO_KB_COLOR_DEFAULT_RED 0xFF -#define CLEVO_KB_COLOR_DEFAULT_GREEN 0xFF -#define CLEVO_KB_COLOR_DEFAULT_BLUE 0xFF -#define CLEVO_KB_COLOR_DEFAULT ((CLEVO_KB_COLOR_DEFAULT_RED << 16) + (CLEVO_KB_COLOR_DEFAULT_GREEN << 8) + CLEVO_KB_COLOR_DEFAULT_BLUE) - -// The very first Clevos with keyboard backlight did have fixed color, but not yet the CLEVO_METHOD_ID_GET_SPECS. To -// not break these, we set this as default for the time being, better having an extra sysfs entry without function than -// a missing one. This is a temporary fix until we find a way to identify these early keyboard backlight devices. -static enum clevo_kb_backlight_types clevo_kb_backlight_type = CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR; - -static int clevo_evaluate_set_brightness(u8 brightness) -{ - pr_debug("Set brightness on %d", brightness); - - return clevo_evaluate_method (CLEVO_CMD_SET_KB_LEDS, 0xF4000000 | brightness, NULL); -} - -static int clevo_evaluate_set_color(u32 zone, u32 color) -{ - u32 cset = ((color & 0x0000FF) << 16) | ((color & 0xFF0000) >> 8) | ((color & 0x00FF00) >> 8); - u32 clevo_submethod_arg = zone | cset; - - pr_debug("Set Color '%08x' for region '%08x'", color, zone); - - return clevo_evaluate_method(CLEVO_CMD_SET_KB_LEDS, clevo_submethod_arg, NULL); -} - -static void clevo_leds_set_brightness(struct led_classdev *led_cdev __always_unused, enum led_brightness brightness) { - int ret = clevo_evaluate_set_brightness(brightness); - if (ret) { - pr_debug("clevo_leds_set_brightness(): clevo_evaluate_set_brightness() failed"); - return; - } - led_cdev->brightness = brightness; -} - -static void clevo_leds_set_brightness_mc(struct led_classdev *led_cdev, enum led_brightness brightness) { - int ret; - u32 zone, color; - struct led_classdev_mc *mcled_cdev = lcdev_to_mccdev(led_cdev); - - ret = clevo_evaluate_set_brightness(CLEVO_KBD_BRIGHTNESS_MAX); - if (ret) { - pr_debug("clevo_leds_set_brightness_mc(): clevo_evaluate_set_brightness() failed"); - return; - } - - zone = mcled_cdev->subled_info[0].channel; - - led_mc_calc_color_components(mcled_cdev, brightness); - color = (mcled_cdev->subled_info[0].brightness << 16) + - (mcled_cdev->subled_info[1].brightness << 8) + - mcled_cdev->subled_info[2].brightness; - - ret = clevo_evaluate_set_color(zone, color); - if (ret) { - pr_debug("clevo_leds_set_brightness_mc(): clevo_evaluate_set_color() failed"); - return; - } - led_cdev->brightness = brightness; -} - -static struct led_classdev clevo_led_cdev = { - .name = "rgb:kbd_backlight", - .max_brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .brightness_set = &clevo_leds_set_brightness, - .brightness = CLEVO_KBD_BRIGHTNESS_DEFAULT -}; - -static struct mc_subled clevo_mcled_cdevs_subleds[3][3] = { - { - { - .color_index = LED_COLOR_ID_RED, - .brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .intensity = CLEVO_KB_COLOR_DEFAULT_RED, - .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_0 - }, - { - .color_index = LED_COLOR_ID_GREEN, - .brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .intensity = CLEVO_KB_COLOR_DEFAULT_GREEN, - .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_0 - }, - { - .color_index = LED_COLOR_ID_BLUE, - .brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .intensity = CLEVO_KB_COLOR_DEFAULT_BLUE, - .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_0 - } - }, - { - { - .color_index = LED_COLOR_ID_RED, - .brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .intensity = CLEVO_KB_COLOR_DEFAULT_RED, - .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_1 - }, - { - .color_index = LED_COLOR_ID_GREEN, - .brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .intensity = CLEVO_KB_COLOR_DEFAULT_GREEN, - .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_1 - }, - { - .color_index = LED_COLOR_ID_BLUE, - .brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .intensity = CLEVO_KB_COLOR_DEFAULT_BLUE, - .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_1 - } - }, - { - { - .color_index = LED_COLOR_ID_RED, - .brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .intensity = CLEVO_KB_COLOR_DEFAULT_RED, - .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_2 - }, - { - .color_index = LED_COLOR_ID_GREEN, - .brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .intensity = CLEVO_KB_COLOR_DEFAULT_GREEN, - .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_2 - }, - { - .color_index = LED_COLOR_ID_BLUE, - .brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .intensity = CLEVO_KB_COLOR_DEFAULT_BLUE, - .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_2 - } - } -}; - -static struct led_classdev_mc clevo_mcled_cdevs[3] = { - { - .led_cdev.name = "rgb:kbd_backlight", - .led_cdev.max_brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .led_cdev.brightness_set = &clevo_leds_set_brightness_mc, - .led_cdev.brightness = CLEVO_KBD_BRIGHTNESS_DEFAULT, - .subled_info = clevo_mcled_cdevs_subleds[0] - }, - { - .led_cdev.name = "rgb:kbd_backlight", - .led_cdev.max_brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .led_cdev.brightness_set = &clevo_leds_set_brightness_mc, - .led_cdev.brightness = CLEVO_KBD_BRIGHTNESS_DEFAULT, - .subled_info = clevo_mcled_cdevs_subleds[1] - }, - { - .led_cdev.name = "rgb:kbd_backlight", - .led_cdev.max_brightness = CLEVO_KBD_BRIGHTNESS_MAX, - .led_cdev.brightness_set = &clevo_leds_set_brightness_mc, - .led_cdev.brightness = CLEVO_KBD_BRIGHTNESS_DEFAULT, - .subled_info = clevo_mcled_cdevs_subleds[2] - } -}; - -int clevo_leds_init(struct platform_device *dev) -{ - u32 status; - union acpi_object *result; - - status = clevo_evaluate_method2(CLEVO_CMD_GET_SPECS, 0, &result); - if (!status) { - if (result->type == ACPI_TYPE_BUFFER) { - pr_debug("CLEVO_CMD_GET_SPECS successful\n"); - clevo_kb_backlight_type = result->buffer.pointer[0x0f]; - } - else { - pr_debug("CLEVO_CMD_GET_SPECS return value has wrong type\n"); - } - ACPI_FREE(result); - } - else { - pr_debug("CLEVO_CMD_GET_SPECS failed\n"); - } - pr_debug("Keyboard backlight type: 0x%02x\n", clevo_kb_backlight_type); - - if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { - led_classdev_register(&dev->dev, &clevo_led_cdev); - } - else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { - devm_led_classdev_multicolor_register(&dev->dev, &clevo_mcled_cdevs[0]); - } - else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_3_ZONE_RGB) { - devm_led_classdev_multicolor_register(&dev->dev, &clevo_mcled_cdevs[0]); - devm_led_classdev_multicolor_register(&dev->dev, &clevo_mcled_cdevs[1]); - devm_led_classdev_multicolor_register(&dev->dev, &clevo_mcled_cdevs[2]); - } - - return 0; -} -EXPORT_SYMBOL(clevo_leds_init); - -int clevo_leds_remove(struct platform_device *dev) { - if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { - led_classdev_unregister(&clevo_led_cdev); - } - else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { - devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[0]); - } - else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_3_ZONE_RGB) { - devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[0]); - devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[1]); - devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[2]); - } - - return 0; -} -EXPORT_SYMBOL(clevo_leds_remove); - -enum clevo_kb_backlight_types clevo_leds_get_backlight_type() { - return clevo_kb_backlight_type; -} -EXPORT_SYMBOL(clevo_leds_get_backlight_type); - -void clevo_leds_set_brightness_extern(u32 brightness) { - if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { - clevo_led_cdev.brightness_set(&clevo_led_cdev, brightness); - } - else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { - clevo_mcled_cdevs[0].led_cdev.brightness_set(&clevo_mcled_cdevs[0].led_cdev, brightness); - } - else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_3_ZONE_RGB) { - clevo_mcled_cdevs[0].led_cdev.brightness_set(&clevo_mcled_cdevs[0].led_cdev, brightness); - clevo_mcled_cdevs[1].led_cdev.brightness_set(&clevo_mcled_cdevs[1].led_cdev, brightness); - clevo_mcled_cdevs[2].led_cdev.brightness_set(&clevo_mcled_cdevs[2].led_cdev, brightness); - } -} -EXPORT_SYMBOL(clevo_leds_set_brightness_extern); - -void clevo_leds_set_color_extern(u32 color) { - if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { - clevo_mcled_cdevs[0].subled_info[0].intensity = (color >> 16) & 0xff; - clevo_mcled_cdevs[0].subled_info[1].intensity = (color >> 8) & 0xff; - clevo_mcled_cdevs[0].subled_info[2].intensity = color & 0xff; - clevo_mcled_cdevs[0].led_cdev.brightness_set(&clevo_mcled_cdevs[0].led_cdev, clevo_mcled_cdevs[0].led_cdev.brightness); - } - else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_3_ZONE_RGB) { - clevo_mcled_cdevs[0].subled_info[0].intensity = (color >> 16) & 0xff; - clevo_mcled_cdevs[0].subled_info[1].intensity = (color >> 8) & 0xff; - clevo_mcled_cdevs[0].subled_info[2].intensity = color & 0xff; - clevo_mcled_cdevs[0].led_cdev.brightness_set(&clevo_mcled_cdevs[0].led_cdev, clevo_mcled_cdevs[0].led_cdev.brightness); - clevo_mcled_cdevs[1].subled_info[0].intensity = (color >> 16) & 0xff; - clevo_mcled_cdevs[1].subled_info[1].intensity = (color >> 8) & 0xff; - clevo_mcled_cdevs[1].subled_info[2].intensity = color & 0xff; - clevo_mcled_cdevs[1].led_cdev.brightness_set(&clevo_mcled_cdevs[1].led_cdev, clevo_mcled_cdevs[0].led_cdev.brightness); - clevo_mcled_cdevs[2].subled_info[0].intensity = (color >> 16) & 0xff; - clevo_mcled_cdevs[2].subled_info[1].intensity = (color >> 8) & 0xff; - clevo_mcled_cdevs[2].subled_info[2].intensity = color & 0xff; - clevo_mcled_cdevs[2].led_cdev.brightness_set(&clevo_mcled_cdevs[2].led_cdev, clevo_mcled_cdevs[0].led_cdev.brightness); - } -} -EXPORT_SYMBOL(clevo_leds_set_color_extern); - -MODULE_LICENSE("GPL"); diff --git a/src/clevo_leds.h b/src/clevo_leds.h index e6bf721..d56056f 100644 --- a/src/clevo_leds.h +++ b/src/clevo_leds.h @@ -21,6 +21,7 @@ #define CLEVO_LEDS_H #include +#include enum clevo_kb_backlight_types { CLEVO_KB_BACKLIGHT_TYPE_NONE = 0x00, @@ -36,4 +37,307 @@ enum clevo_kb_backlight_types clevo_leds_get_backlight_type(void); void clevo_leds_set_brightness_extern(u32 brightness); void clevo_leds_set_color_extern(u32 color); +// TODO The following should go into a seperate .c file, but for this to work more reworking is required in the tuxedo_keyboard structure. + +#include "clevo_leds.h" + +#include "clevo_interfaces.h" + +#include +#include + +#define CLEVO_KBD_BRIGHTNESS_MIN 0 +#define CLEVO_KBD_BRIGHTNESS_MAX 255 +#define CLEVO_KBD_BRIGHTNESS_DEFAULT (CLEVO_KBD_BRIGHTNESS_MAX * 0.5) + +#define CLEVO_KB_COLOR_DEFAULT_RED 0xFF +#define CLEVO_KB_COLOR_DEFAULT_GREEN 0xFF +#define CLEVO_KB_COLOR_DEFAULT_BLUE 0xFF +#define CLEVO_KB_COLOR_DEFAULT ((CLEVO_KB_COLOR_DEFAULT_RED << 16) + (CLEVO_KB_COLOR_DEFAULT_GREEN << 8) + CLEVO_KB_COLOR_DEFAULT_BLUE) + +// The very first Clevos with keyboard backlight did have fixed color, but not yet the CLEVO_METHOD_ID_GET_SPECS. To +// not break these, we set this as default for the time being, better having an extra sysfs entry without function than +// a missing one. This is a temporary fix until we find a way to identify these early keyboard backlight devices. +static enum clevo_kb_backlight_types clevo_kb_backlight_type = CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR; +static bool leds_initiaized; + +static int clevo_evaluate_set_brightness(u8 brightness) +{ + pr_debug("Set brightness on %d\n", brightness); + + return clevo_evaluate_method (CLEVO_CMD_SET_KB_LEDS, 0xF4000000 | brightness, NULL); +} + +static int clevo_evaluate_set_color(u32 zone, u32 color) +{ + u32 cset = ((color & 0x0000FF) << 16) | ((color & 0xFF0000) >> 8) | ((color & 0x00FF00) >> 8); + u32 clevo_submethod_arg = zone | cset; + + pr_debug("Set Color 0x%08x for region 0x%08x\n", color, zone); + + return clevo_evaluate_method(CLEVO_CMD_SET_KB_LEDS, clevo_submethod_arg, NULL); +} + +static void clevo_leds_set_brightness(struct led_classdev *led_cdev __always_unused, enum led_brightness brightness) { + int ret = clevo_evaluate_set_brightness(brightness); + if (ret) { + pr_debug("clevo_leds_set_brightness(): clevo_evaluate_set_brightness() failed\n"); + return; + } + led_cdev->brightness = brightness; +} + +static void clevo_leds_set_brightness_mc(struct led_classdev *led_cdev, enum led_brightness brightness) { + int ret; + u32 zone, color; + struct led_classdev_mc *mcled_cdev = lcdev_to_mccdev(led_cdev); + + ret = clevo_evaluate_set_brightness(CLEVO_KBD_BRIGHTNESS_MAX); + if (ret) { + pr_debug("clevo_leds_set_brightness_mc(): clevo_evaluate_set_brightness() failed\n"); + return; + } + + zone = mcled_cdev->subled_info[0].channel; + + led_mc_calc_color_components(mcled_cdev, brightness); + color = (mcled_cdev->subled_info[0].brightness << 16) + + (mcled_cdev->subled_info[1].brightness << 8) + + mcled_cdev->subled_info[2].brightness; + + ret = clevo_evaluate_set_color(zone, color); + if (ret) { + pr_debug("clevo_leds_set_brightness_mc(): clevo_evaluate_set_color() failed\n"); + return; + } + led_cdev->brightness = brightness; +} + +static struct led_classdev clevo_led_cdev = { + .name = DRIVER_NAME ":white:kbd_backlight", + .max_brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .brightness_set = &clevo_leds_set_brightness, + .brightness = CLEVO_KBD_BRIGHTNESS_DEFAULT +}; + +static struct mc_subled clevo_mcled_cdevs_subleds[3][3] = { + { + { + .color_index = LED_COLOR_ID_RED, + .brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .intensity = CLEVO_KB_COLOR_DEFAULT_RED, + .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_0 + }, + { + .color_index = LED_COLOR_ID_GREEN, + .brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .intensity = CLEVO_KB_COLOR_DEFAULT_GREEN, + .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_0 + }, + { + .color_index = LED_COLOR_ID_BLUE, + .brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .intensity = CLEVO_KB_COLOR_DEFAULT_BLUE, + .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_0 + } + }, + { + { + .color_index = LED_COLOR_ID_RED, + .brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .intensity = CLEVO_KB_COLOR_DEFAULT_RED, + .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_1 + }, + { + .color_index = LED_COLOR_ID_GREEN, + .brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .intensity = CLEVO_KB_COLOR_DEFAULT_GREEN, + .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_1 + }, + { + .color_index = LED_COLOR_ID_BLUE, + .brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .intensity = CLEVO_KB_COLOR_DEFAULT_BLUE, + .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_1 + } + }, + { + { + .color_index = LED_COLOR_ID_RED, + .brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .intensity = CLEVO_KB_COLOR_DEFAULT_RED, + .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_2 + }, + { + .color_index = LED_COLOR_ID_GREEN, + .brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .intensity = CLEVO_KB_COLOR_DEFAULT_GREEN, + .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_2 + }, + { + .color_index = LED_COLOR_ID_BLUE, + .brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .intensity = CLEVO_KB_COLOR_DEFAULT_BLUE, + .channel = CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_2 + } + } +}; + +static struct led_classdev_mc clevo_mcled_cdevs[3] = { + { + .led_cdev.name = DRIVER_NAME ":rgb:kbd_backlight", + .led_cdev.max_brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .led_cdev.brightness_set = &clevo_leds_set_brightness_mc, + .led_cdev.brightness = CLEVO_KBD_BRIGHTNESS_DEFAULT, + .num_colors = 3, + .subled_info = clevo_mcled_cdevs_subleds[0] + }, + { + .led_cdev.name = DRIVER_NAME ":rgb:kbd_backlight", + .led_cdev.max_brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .led_cdev.brightness_set = &clevo_leds_set_brightness_mc, + .led_cdev.brightness = CLEVO_KBD_BRIGHTNESS_DEFAULT, + .num_colors = 3, + .subled_info = clevo_mcled_cdevs_subleds[1] + }, + { + .led_cdev.name = DRIVER_NAME ":rgb:kbd_backlight", + .led_cdev.max_brightness = CLEVO_KBD_BRIGHTNESS_MAX, + .led_cdev.brightness_set = &clevo_leds_set_brightness_mc, + .led_cdev.brightness = CLEVO_KBD_BRIGHTNESS_DEFAULT, + .num_colors = 3, + .subled_info = clevo_mcled_cdevs_subleds[2] + } +}; + +int clevo_leds_init(struct platform_device *dev) +{ + int ret; + u32 status; + union acpi_object *result; + + status = clevo_evaluate_method2(CLEVO_CMD_GET_SPECS, 0, &result); + if (!status) { + if (result->type == ACPI_TYPE_BUFFER) { + pr_debug("CLEVO_CMD_GET_SPECS successful\n"); + clevo_kb_backlight_type = result->buffer.pointer[0x0f]; + } + else { + pr_err("CLEVO_CMD_GET_SPECS return value has wrong type\n"); + } + ACPI_FREE(result); + } + else { + pr_err("CLEVO_CMD_GET_SPECS failed\n"); + } + pr_debug("Keyboard backlight type: 0x%02x\n", clevo_kb_backlight_type); + + if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { + pr_debug("Registering fixed color leds interface\n"); + ret = led_classdev_register(&dev->dev, &clevo_led_cdev); + if(ret) { + pr_err("Registering fixed color leds interface failed\n"); + return ret; + } + } + else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { + pr_debug("Registering single zone rgb leds interface\n"); + ret = devm_led_classdev_multicolor_register(&dev->dev, &clevo_mcled_cdevs[0]); + if(ret) { + pr_err("Registering single zone rgb leds interface failed\n"); + return ret; + } + } + else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_3_ZONE_RGB) { + pr_debug("Registering three zone rgb leds interface\n"); + ret = devm_led_classdev_multicolor_register(&dev->dev, &clevo_mcled_cdevs[0]); + if(ret) { + pr_err("Registering three zone rgb zone 0 leds interface failed\n"); + return ret; + } + ret = devm_led_classdev_multicolor_register(&dev->dev, &clevo_mcled_cdevs[1]); + if(ret) { + pr_err("Registering three zone rgb zone 1 leds interface failed\n"); + devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[0]); + return ret; + } + ret = devm_led_classdev_multicolor_register(&dev->dev, &clevo_mcled_cdevs[2]); + if(ret) { + pr_err("Registering three zone rgb zone 2 leds interface failed\n"); + devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[0]); + devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[1]); + return ret; + } + } + + leds_initiaized = true; + return 0; +} +EXPORT_SYMBOL(clevo_leds_init); + +int clevo_leds_remove(struct platform_device *dev) { + if (leds_initiaized) { + if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { + led_classdev_unregister(&clevo_led_cdev); + } + else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { + devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[0]); + } + else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_3_ZONE_RGB) { + devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[0]); + devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[1]); + devm_led_classdev_multicolor_unregister(&dev->dev, &clevo_mcled_cdevs[2]); + } + } + + return 0; +} +EXPORT_SYMBOL(clevo_leds_remove); + +enum clevo_kb_backlight_types clevo_leds_get_backlight_type() { + return clevo_kb_backlight_type; +} +EXPORT_SYMBOL(clevo_leds_get_backlight_type); + +void clevo_leds_set_brightness_extern(u32 brightness) { + if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { + clevo_led_cdev.brightness_set(&clevo_led_cdev, brightness); + } + else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { + clevo_mcled_cdevs[0].led_cdev.brightness_set(&clevo_mcled_cdevs[0].led_cdev, brightness); + } + else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_3_ZONE_RGB) { + clevo_mcled_cdevs[0].led_cdev.brightness_set(&clevo_mcled_cdevs[0].led_cdev, brightness); + clevo_mcled_cdevs[1].led_cdev.brightness_set(&clevo_mcled_cdevs[1].led_cdev, brightness); + clevo_mcled_cdevs[2].led_cdev.brightness_set(&clevo_mcled_cdevs[2].led_cdev, brightness); + } +} +EXPORT_SYMBOL(clevo_leds_set_brightness_extern); + +void clevo_leds_set_color_extern(u32 color) { + if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { + clevo_mcled_cdevs[0].subled_info[0].intensity = (color >> 16) & 0xff; + clevo_mcled_cdevs[0].subled_info[1].intensity = (color >> 8) & 0xff; + clevo_mcled_cdevs[0].subled_info[2].intensity = color & 0xff; + clevo_mcled_cdevs[0].led_cdev.brightness_set(&clevo_mcled_cdevs[0].led_cdev, clevo_mcled_cdevs[0].led_cdev.brightness); + } + else if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_3_ZONE_RGB) { + clevo_mcled_cdevs[0].subled_info[0].intensity = (color >> 16) & 0xff; + clevo_mcled_cdevs[0].subled_info[1].intensity = (color >> 8) & 0xff; + clevo_mcled_cdevs[0].subled_info[2].intensity = color & 0xff; + clevo_mcled_cdevs[0].led_cdev.brightness_set(&clevo_mcled_cdevs[0].led_cdev, clevo_mcled_cdevs[0].led_cdev.brightness); + clevo_mcled_cdevs[1].subled_info[0].intensity = (color >> 16) & 0xff; + clevo_mcled_cdevs[1].subled_info[1].intensity = (color >> 8) & 0xff; + clevo_mcled_cdevs[1].subled_info[2].intensity = color & 0xff; + clevo_mcled_cdevs[1].led_cdev.brightness_set(&clevo_mcled_cdevs[1].led_cdev, clevo_mcled_cdevs[0].led_cdev.brightness); + clevo_mcled_cdevs[2].subled_info[0].intensity = (color >> 16) & 0xff; + clevo_mcled_cdevs[2].subled_info[1].intensity = (color >> 8) & 0xff; + clevo_mcled_cdevs[2].subled_info[2].intensity = color & 0xff; + clevo_mcled_cdevs[2].led_cdev.brightness_set(&clevo_mcled_cdevs[2].led_cdev, clevo_mcled_cdevs[0].led_cdev.brightness); + } +} +EXPORT_SYMBOL(clevo_leds_set_color_extern); + +MODULE_LICENSE("GPL"); + #endif // CLEVO_LEDS_H diff --git a/tuxedo_keyboard.conf b/tuxedo_keyboard.conf index b257600..57d0ea6 100644 --- a/tuxedo_keyboard.conf +++ b/tuxedo_keyboard.conf @@ -1 +1 @@ -options tuxedo-keyboard mode=0 brightness=255 color_left=0xFFFFFF color_center=0xFFFFFF color_right=0xFFFFFF +options tuxedo-keyboard kbd_backlight_mode=0 brightness=255