From 98c5360b2b80dc380ac8fe376e82cc218d7e08a7 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Sun, 9 Mar 2025 16:45:04 +0100 Subject: [PATCH 01/11] Add drvdata --- .../lightning_node_pro_led.c | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index 2f9ba8f..5b30171 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -5,17 +5,54 @@ #define USB_VENDOR_ID_CORSAIR 0x1b1c #define USB_DEVICE_ID_LIGHTNING_NODE_PRO 0x0c0b +#define NUMBER_OF_ZONES_PER_LL120_FAN 16 +#define LIGHTNODE_PRO_MAX_FAN 6 + +#define MSG_SIZE 64 + +#define RED_COLOR 0x00 +#define BLUE_COLOR 0x01 +#define GREEN_COLOR 0x02 + +static short int number_of_fan = 1; +module_param(number_of_fan, short, 0000); +MODULE_PARM_DESC(number_of_fan, + "Number of LL120 FAN connected to the lightning node pro"); + +struct lightning_node_pro_led_data { + struct hid_device *hdev; + struct mutex lock; +}; + static int lightning_node_pro_led_probe(struct hid_device *hdev, const struct hid_device_id *id) { pr_info("Détection USB pour Lightning Node Pro\n"); + int ret; + struct lightning_node_pro_led_data *data; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->hdev = hdev; + mutex_init(&data->lock); + hid_set_drvdata(hdev, data); + return 0; + +free_ldata: + kfree(data); + + return ret; } -static void lightning_node_pro_led_remove(struct hid_device *dev) +static void lightning_node_pro_led_remove(struct hid_device *hdev) { + struct lightning_node_pro_led_data *data = hid_get_drvdata(hdev); pr_info("Retrait USB pour Lightning Node Pro\n"); + kfree(data); } static struct hid_device_id lightning_node_pro_led_table[] = { From b2e9dfa0c340a2ad4ffef7e95ce470b10794c4d8 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Sun, 9 Mar 2025 18:35:20 +0100 Subject: [PATCH 02/11] Add fans initialization --- .../lightning_node_pro_led.c | 200 ++++++++++++++++-- 1 file changed, 182 insertions(+), 18 deletions(-) diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index 5b30171..aab0f90 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -1,11 +1,12 @@ #include #include #include +#include #define USB_VENDOR_ID_CORSAIR 0x1b1c #define USB_DEVICE_ID_LIGHTNING_NODE_PRO 0x0c0b -#define NUMBER_OF_ZONES_PER_LL120_FAN 16 +#define NUMBER_OF_LEDS_PER_LL120_FAN 16 #define LIGHTNODE_PRO_MAX_FAN 6 #define MSG_SIZE 64 @@ -19,18 +20,155 @@ module_param(number_of_fan, short, 0000); MODULE_PARM_DESC(number_of_fan, "Number of LL120 FAN connected to the lightning node pro"); -struct lightning_node_pro_led_data { - struct hid_device *hdev; - struct mutex lock; +enum LNP_LED_TYPE { + LNP_LED_LL120, }; -static int lightning_node_pro_led_probe(struct hid_device *hdev, - const struct hid_device_id *id) +struct lnp_rgb_led { + struct led_classdev_mc cdev; + uint8_t red; + uint8_t green; + uint8_t blue; +}; + +struct lnp_fan { + int fan_index; + int rgb_leds_count; + struct lnp_rgb_led *rgb_leds_data; +}; + +struct lnp_device { + struct hid_device *hdev; + struct mutex lock; + enum LNP_LED_TYPE type; + int fans_count; + void *fans_data; +}; + +static inline int lnp_register_rgb_led(struct rgb_led *rgb_led_data, + int fan_number) +{ +} + +static inline int lnp_unregister_rgb_led(struct rgb_led *rgb_led_data, + int fan_number) +{ +} + +static inline int lnp_register_fan(struct lnp_fan *fan_data, int rgb_leds_count) +{ + int ret, led_index; + + fan_data->rgb_leds_data = kzalloc( + sizeof(struct lnp_rgb_led) * rgb_leds_count, GFP_KERNEL); + if (!fan_data->rgb_leds_data) { + ret = -ENOMEM; + goto fail_alloc_data; + } + + for (led_index = 0; led_index < fan_data->rgb_leds_count; led_index++) { + struct lnp_rgb_led *rgb_led_data = + fan_data->rgb_leds_data + led_index; + + ret = lnp_register_rgb_led(rgb_led_data, fan_data->fan_index); + if (ret) + goto fail_register_leds; + } + + return 0; + +fail_register_leds: + for (led_index--; led_index >= 0; led_index--) { + struct rgb_led *rgb_led_data = + fan_data->rgb_leds_data + led_index; + lnp_unregister_rgb_led(rgb_led_data, fan_data->fan_index); + } + +fail_alloc_data: + kfree(fan_data->rgb_leds_data); + + return ret; +} + +static inline void lnp_unregister_fan(struct lnp_fan *fan_data) +{ + int ret, led_index; + for (led_index = 0; led_index < fan_data->rgb_leds_count; led_index++) { + struct lnp_rgb_led *rgb_led_data = + fan_data->rgb_leds_data + led_index; + lnp_unregister_rgb_led(rgb_led_data, fan_data->fan_index); + } +} + +static inline int lnp_register_fans(struct lnp_device *data, int rgb_leds_count) +{ + int ret, fan_index, led_index; + struct lnp_fan *fans_data = data->fans_data; + + for (fan_index = 0; fan_index < data->fans_count; fan_index++) { + struct lnp_fan *fan_data = fans_data + fan_index; + fan_data->fan_index = fan_index; + + ret = lnp_register_fan(fan_data, rgb_leds_count); + if (ret) + goto fail; + } + + return 0; + +fail: + for (fan_index--; fan_index >= 0; fan_index--) { + struct ll120_fan *fan_data = fans_data + fan_index; + lnp_unregister_fan(fan_data); + } + return ret; +} + +static inline void lnp_unregister_fans(struct lnp_device *data) +{ + int fan_index; + struct lnp_fan *fans_data = data->fans_data; + + for (fan_index = 0; fan_index < data->fans_count; fan_index++) { + struct lnp_fan *fan_data = fans_data + fan_index; + lnp_unregister_fan(fan_data); + } +} + +static inline int lnp_ll120_register(struct lnp_device *data) +{ + data->fans_count = number_of_fan; + data->fans_data = + kzalloc(sizeof(struct lnp_fan) * data->fans_count, GFP_KERNEL); + + if (!data->fans_data) + return -ENOMEM; + + int ret; + + ret = lnp_register_fans(data, NUMBER_OF_LEDS_PER_LL120_FAN); + if (ret) + goto fans_data_free; + + return 0; + +fans_data_free: + kfree(data->fans_data); + + return ret; +} + +static inline void lnp_ll120_unregister(struct lnp_device *data) +{ + lnp_unregister_fans(data); +} + +static int lnp_probe(struct hid_device *hdev, const struct hid_device_id *id) { pr_info("Détection USB pour Lightning Node Pro\n"); int ret; - struct lightning_node_pro_led_data *data; + struct lnp_device *data; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) @@ -38,40 +176,66 @@ static int lightning_node_pro_led_probe(struct hid_device *hdev, data->hdev = hdev; mutex_init(&data->lock); + + data->type = LNP_LED_LL120; // Only support LL120 for now + + switch (data->type) { + case LNP_LED_LL120: + ret = lnp_ll120_register(data); + break; + default: + ret = -ENOSYS; + pr_err("Fan type invalid\n"); + break; + } + + if (ret) + goto free_data; + hid_set_drvdata(hdev, data); return 0; -free_ldata: +free_data: kfree(data); return ret; } -static void lightning_node_pro_led_remove(struct hid_device *hdev) +static void lnp_remove(struct hid_device *hdev) { - struct lightning_node_pro_led_data *data = hid_get_drvdata(hdev); + struct lnp_device *data = hid_get_drvdata(hdev); + + switch (data->type) { + case LNP_LED_LL120: + lnp_ll120_unregister(data); + break; + default: + pr_err("Fan type invalid\n"); + break; + } + pr_info("Retrait USB pour Lightning Node Pro\n"); kfree(data); } -static struct hid_device_id lightning_node_pro_led_table[] = { +static struct hid_device_id lnp_table[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_LIGHTNING_NODE_PRO) }, {} /* Entrée de terminaison */ }; -MODULE_DEVICE_TABLE(hid, lightning_node_pro_led_table); +MODULE_DEVICE_TABLE(hid, lnp_table); -static struct hid_driver lightning_node_pro_led_driver = { +static struct hid_driver lnp_driver = { .name = "lightning-node-pro", - .id_table = lightning_node_pro_led_table, - .probe = lightning_node_pro_led_probe, - .remove = lightning_node_pro_led_remove, + .id_table = lnp_table, + .probe = lnp_probe, + .remove = lnp_remove, }; -module_hid_driver(lightning_node_pro_led_driver); +module_hid_driver(lnp_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Florian RICHER "); -MODULE_DESCRIPTION("Un module noyau pour utiliser le Lightning Node Pro LED"); +MODULE_DESCRIPTION("Un module noyau pour utiliser le Lightning Node Pro"); MODULE_VERSION("1.0"); \ No newline at end of file From c780a8e8578f82c33e72ebc165dcd008ba2b7816 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Sun, 9 Mar 2025 19:34:00 +0100 Subject: [PATCH 03/11] Use device linked allocator instead and led registering --- .../lightning_node_pro_led.c | 211 ++++++++---------- 1 file changed, 88 insertions(+), 123 deletions(-) diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index aab0f90..cf6e999 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -26,6 +26,7 @@ enum LNP_LED_TYPE { struct lnp_rgb_led { struct led_classdev_mc cdev; + int led_index; uint8_t red; uint8_t green; uint8_t blue; @@ -45,122 +46,101 @@ struct lnp_device { void *fans_data; }; -static inline int lnp_register_rgb_led(struct rgb_led *rgb_led_data, - int fan_number) +static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, + struct lnp_fan *fan_data, + struct lnp_rgb_led *rgb_led_data) { -} + struct hid_device *hdev = lnp_dev->hdev; + struct mc_subled *mc_leds_info; + struct led_classdev *led_cdev; + int ret; -static inline int lnp_unregister_rgb_led(struct rgb_led *rgb_led_data, - int fan_number) -{ -} + mc_leds_info = devm_kmalloc_array(&hdev->dev, 3, sizeof(*mc_leds_info), + GFP_KERNEL); -static inline int lnp_register_fan(struct lnp_fan *fan_data, int rgb_leds_count) -{ - int ret, led_index; + if (!mc_leds_info) + return -ENOMEM; - fan_data->rgb_leds_data = kzalloc( - sizeof(struct lnp_rgb_led) * rgb_leds_count, GFP_KERNEL); - if (!fan_data->rgb_leds_data) { - ret = -ENOMEM; - goto fail_alloc_data; - } + mc_leds_info[0].color_index = LED_COLOR_ID_RED; + mc_leds_info[1].color_index = LED_COLOR_ID_GREEN; + mc_leds_info[2].color_index = LED_COLOR_ID_BLUE; - for (led_index = 0; led_index < fan_data->rgb_leds_count; led_index++) { - struct lnp_rgb_led *rgb_led_data = - fan_data->rgb_leds_data + led_index; + rgb_led_data->cdev.subled_info = mc_leds_info; + rgb_led_data->cdev.num_colors = 3; - ret = lnp_register_rgb_led(rgb_led_data, fan_data->fan_index); - if (ret) - goto fail_register_leds; + led_cdev = &rgb_led_data->cdev.led_cdev; + led_cdev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "ll120:rgb:fan-%d-led-%d", + fan_data->fan_index, + rgb_led_data->led_index); + if (!led_cdev->name) + return -ENOMEM; + + led_cdev->brightness = 0; + led_cdev->max_brightness = 255; + + ret = devm_led_classdev_multicolor_register(&hdev->dev, + &rgb_led_data->cdev); + if (ret < 0) { + hid_err(hdev, "Cannot register multicolor LED device\n"); + return ret; } return 0; - -fail_register_leds: - for (led_index--; led_index >= 0; led_index--) { - struct rgb_led *rgb_led_data = - fan_data->rgb_leds_data + led_index; - lnp_unregister_rgb_led(rgb_led_data, fan_data->fan_index); - } - -fail_alloc_data: - kfree(fan_data->rgb_leds_data); - - return ret; } -static inline void lnp_unregister_fan(struct lnp_fan *fan_data) +static inline int led_number_for_device(struct lnp_device *lnp_dev) +{ + switch (lnp_dev->type) { + case LNP_LED_LL120: + return NUMBER_OF_LEDS_PER_LL120_FAN; + default: + return 0; + } +} + +static inline int lnp_register_fan(struct lnp_device *lnp_dev, + struct lnp_fan *fan_data) { int ret, led_index; + + fan_data->rgb_leds_count = led_number_for_device(lnp_dev); + fan_data->rgb_leds_data = devm_kmalloc_array(&lnp_dev->hdev->dev, + fan_data->rgb_leds_count, + sizeof(struct lnp_rgb_led), + GFP_KERNEL | __GFP_ZERO); + if (!fan_data->rgb_leds_data) { + return -ENOMEM; + } + for (led_index = 0; led_index < fan_data->rgb_leds_count; led_index++) { struct lnp_rgb_led *rgb_led_data = fan_data->rgb_leds_data + led_index; - lnp_unregister_rgb_led(rgb_led_data, fan_data->fan_index); + rgb_led_data->led_index = led_index; + + ret = lnp_register_rgb_led(lnp_dev, fan_data, rgb_led_data); + if (ret) + return ret; } + + return 0; } -static inline int lnp_register_fans(struct lnp_device *data, int rgb_leds_count) +static inline int lnp_register_fans(struct lnp_device *lnp_dev) { - int ret, fan_index, led_index; - struct lnp_fan *fans_data = data->fans_data; + int ret, fan_index; + struct lnp_fan *fans_data = lnp_dev->fans_data; - for (fan_index = 0; fan_index < data->fans_count; fan_index++) { + for (fan_index = 0; fan_index < lnp_dev->fans_count; fan_index++) { struct lnp_fan *fan_data = fans_data + fan_index; fan_data->fan_index = fan_index; - ret = lnp_register_fan(fan_data, rgb_leds_count); + ret = lnp_register_fan(lnp_dev, fan_data); if (ret) - goto fail; + return ret; } return 0; - -fail: - for (fan_index--; fan_index >= 0; fan_index--) { - struct ll120_fan *fan_data = fans_data + fan_index; - lnp_unregister_fan(fan_data); - } - return ret; -} - -static inline void lnp_unregister_fans(struct lnp_device *data) -{ - int fan_index; - struct lnp_fan *fans_data = data->fans_data; - - for (fan_index = 0; fan_index < data->fans_count; fan_index++) { - struct lnp_fan *fan_data = fans_data + fan_index; - lnp_unregister_fan(fan_data); - } -} - -static inline int lnp_ll120_register(struct lnp_device *data) -{ - data->fans_count = number_of_fan; - data->fans_data = - kzalloc(sizeof(struct lnp_fan) * data->fans_count, GFP_KERNEL); - - if (!data->fans_data) - return -ENOMEM; - - int ret; - - ret = lnp_register_fans(data, NUMBER_OF_LEDS_PER_LL120_FAN); - if (ret) - goto fans_data_free; - - return 0; - -fans_data_free: - kfree(data->fans_data); - - return ret; -} - -static inline void lnp_ll120_unregister(struct lnp_device *data) -{ - lnp_unregister_fans(data); } static int lnp_probe(struct hid_device *hdev, const struct hid_device_id *id) @@ -168,55 +148,40 @@ static int lnp_probe(struct hid_device *hdev, const struct hid_device_id *id) pr_info("Détection USB pour Lightning Node Pro\n"); int ret; - struct lnp_device *data; + struct lnp_device *lnp_dev; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) + lnp_dev = devm_kzalloc(&hdev->dev, sizeof(*lnp_dev), GFP_KERNEL); + if (!lnp_dev) return -ENOMEM; - data->hdev = hdev; - mutex_init(&data->lock); + lnp_dev->hdev = hdev; + mutex_init(&lnp_dev->lock); - data->type = LNP_LED_LL120; // Only support LL120 for now + lnp_dev->type = LNP_LED_LL120; // Only support LL120 for now + lnp_dev->fans_count = number_of_fan; - switch (data->type) { - case LNP_LED_LL120: - ret = lnp_ll120_register(data); - break; - default: - ret = -ENOSYS; - pr_err("Fan type invalid\n"); - break; + lnp_dev->fans_data = devm_kmalloc_array(&lnp_dev->hdev->dev, + lnp_dev->fans_count, + sizeof(struct lnp_fan), + GFP_KERNEL | __GFP_ZERO); + + if (!lnp_dev->fans_data) + return -ENOMEM; + + ret = lnp_register_fans(lnp_dev); + if (ret) { + hid_err(lnp_dev->hdev, "Failed to register device\n"); + return ret; } - if (ret) - goto free_data; - - hid_set_drvdata(hdev, data); + hid_set_drvdata(hdev, lnp_dev); return 0; - -free_data: - kfree(data); - - return ret; } static void lnp_remove(struct hid_device *hdev) { - struct lnp_device *data = hid_get_drvdata(hdev); - - switch (data->type) { - case LNP_LED_LL120: - lnp_ll120_unregister(data); - break; - default: - pr_err("Fan type invalid\n"); - break; - } - pr_info("Retrait USB pour Lightning Node Pro\n"); - kfree(data); } static struct hid_device_id lnp_table[] = { From a124cb33a8f9b18f18383e8e52392771736d6814 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Sun, 9 Mar 2025 20:13:23 +0100 Subject: [PATCH 04/11] add dev_name, move rgb_leds_count into device, open hw --- .../lightning_node_pro_led.c | 81 ++++++++++++++----- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index cf6e999..1c74265 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -34,15 +34,18 @@ struct lnp_rgb_led { struct lnp_fan { int fan_index; - int rgb_leds_count; struct lnp_rgb_led *rgb_leds_data; }; struct lnp_device { struct hid_device *hdev; struct mutex lock; + + const char *dev_name; + enum LNP_LED_TYPE type; int fans_count; + int rgb_leds_per_fan_count; void *fans_data; }; @@ -70,8 +73,8 @@ static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, led_cdev = &rgb_led_data->cdev.led_cdev; led_cdev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, - "ll120:rgb:fan-%d-led-%d", - fan_data->fan_index, + "%s:rgb:fan-%d-led-%d", + lnp_dev->dev_name, fan_data->fan_index, rgb_led_data->led_index); if (!led_cdev->name) return -ENOMEM; @@ -89,31 +92,20 @@ static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, return 0; } -static inline int led_number_for_device(struct lnp_device *lnp_dev) -{ - switch (lnp_dev->type) { - case LNP_LED_LL120: - return NUMBER_OF_LEDS_PER_LL120_FAN; - default: - return 0; - } -} - static inline int lnp_register_fan(struct lnp_device *lnp_dev, struct lnp_fan *fan_data) { int ret, led_index; - fan_data->rgb_leds_count = led_number_for_device(lnp_dev); - fan_data->rgb_leds_data = devm_kmalloc_array(&lnp_dev->hdev->dev, - fan_data->rgb_leds_count, - sizeof(struct lnp_rgb_led), - GFP_KERNEL | __GFP_ZERO); + fan_data->rgb_leds_data = devm_kmalloc_array( + &lnp_dev->hdev->dev, lnp_dev->rgb_leds_per_fan_count, + sizeof(struct lnp_rgb_led), GFP_KERNEL | __GFP_ZERO); if (!fan_data->rgb_leds_data) { return -ENOMEM; } - for (led_index = 0; led_index < fan_data->rgb_leds_count; led_index++) { + for (led_index = 0; led_index < lnp_dev->rgb_leds_per_fan_count; + led_index++) { struct lnp_rgb_led *rgb_led_data = fan_data->rgb_leds_data + led_index; rgb_led_data->led_index = led_index; @@ -143,10 +135,8 @@ static inline int lnp_register_fans(struct lnp_device *lnp_dev) return 0; } -static int lnp_probe(struct hid_device *hdev, const struct hid_device_id *id) +static inline int lnp_init(struct hid_device *hdev) { - pr_info("Détection USB pour Lightning Node Pro\n"); - int ret; struct lnp_device *lnp_dev; @@ -155,11 +145,19 @@ static int lnp_probe(struct hid_device *hdev, const struct hid_device_id *id) return -ENOMEM; lnp_dev->hdev = hdev; + lnp_dev->dev_name = dev_name(&hdev->dev); mutex_init(&lnp_dev->lock); lnp_dev->type = LNP_LED_LL120; // Only support LL120 for now lnp_dev->fans_count = number_of_fan; + if (lnp_dev->type == LNP_LED_LL120) { + lnp_dev->rgb_leds_per_fan_count = NUMBER_OF_LEDS_PER_LL120_FAN; + } else { + hid_err(lnp_dev->hdev, "Invalid fan type\n"); + return -ENOSYS; + } + lnp_dev->fans_data = devm_kmalloc_array(&lnp_dev->hdev->dev, lnp_dev->fans_count, sizeof(struct lnp_fan), @@ -179,9 +177,48 @@ static int lnp_probe(struct hid_device *hdev, const struct hid_device_id *id) return 0; } +static int lnp_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + pr_info("Détection USB pour Lightning Node Pro\n"); + + int ret; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "Parse failed\n"); + return ret; + } + + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); + if (ret) { + hid_err(hdev, "Failed to start HID device\n"); + return ret; + } + + ret = hid_hw_open(hdev); + if (ret) { + hid_err(hdev, "Failed to open HID device\n"); + goto err_stop; + } + + ret = lnp_init(hdev); + if (ret) + goto err_close; + + return 0; + +err_close: + hid_hw_close(hdev); +err_stop: + hid_hw_stop(hdev); + return ret; +} + static void lnp_remove(struct hid_device *hdev) { pr_info("Retrait USB pour Lightning Node Pro\n"); + hid_hw_close(hdev); + hid_hw_stop(hdev); } static struct hid_device_id lnp_table[] = { From 5095cabcadb2e63c9db016fff35dd9861019c145 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Sun, 9 Mar 2025 20:51:43 +0100 Subject: [PATCH 05/11] Add more hid_err --- .../lightning_node_pro_led.c | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index 1c74265..5b42122 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -61,8 +61,12 @@ static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, mc_leds_info = devm_kmalloc_array(&hdev->dev, 3, sizeof(*mc_leds_info), GFP_KERNEL); - if (!mc_leds_info) + if (!mc_leds_info) { + hid_err(lnp_dev->hdev, + "Failed to allocate multicolor leds info for LED %d on FAN %d\n", + rgb_led_data->led_index, fan_data->fan_index); return -ENOMEM; + } mc_leds_info[0].color_index = LED_COLOR_ID_RED; mc_leds_info[1].color_index = LED_COLOR_ID_GREEN; @@ -76,8 +80,13 @@ static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, "%s:rgb:fan-%d-led-%d", lnp_dev->dev_name, fan_data->fan_index, rgb_led_data->led_index); - if (!led_cdev->name) + + if (!led_cdev->name) { + hid_err(lnp_dev->hdev, + "Failed to allocate name for LED %d on FAN %d\n", + rgb_led_data->led_index, fan_data->fan_index); return -ENOMEM; + } led_cdev->brightness = 0; led_cdev->max_brightness = 255; @@ -85,7 +94,9 @@ static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, ret = devm_led_classdev_multicolor_register(&hdev->dev, &rgb_led_data->cdev); if (ret < 0) { - hid_err(hdev, "Cannot register multicolor LED device\n"); + hid_err(hdev, + "Cannot register multicolor LED device for LED %d on FAN %d\n", + rgb_led_data->led_index, fan_data->fan_index); return ret; } @@ -100,7 +111,11 @@ static inline int lnp_register_fan(struct lnp_device *lnp_dev, fan_data->rgb_leds_data = devm_kmalloc_array( &lnp_dev->hdev->dev, lnp_dev->rgb_leds_per_fan_count, sizeof(struct lnp_rgb_led), GFP_KERNEL | __GFP_ZERO); + if (!fan_data->rgb_leds_data) { + hid_err(lnp_dev->hdev, + "Failed to allocate rgb leds data for FAN %d\n", + fan_data->fan_index); return -ENOMEM; } @@ -141,8 +156,10 @@ static inline int lnp_init(struct hid_device *hdev) struct lnp_device *lnp_dev; lnp_dev = devm_kzalloc(&hdev->dev, sizeof(*lnp_dev), GFP_KERNEL); - if (!lnp_dev) + if (!lnp_dev) { + hid_err(hdev, "Failed to allocate lnp device data\n"); return -ENOMEM; + } lnp_dev->hdev = hdev; lnp_dev->dev_name = dev_name(&hdev->dev); @@ -154,7 +171,7 @@ static inline int lnp_init(struct hid_device *hdev) if (lnp_dev->type == LNP_LED_LL120) { lnp_dev->rgb_leds_per_fan_count = NUMBER_OF_LEDS_PER_LL120_FAN; } else { - hid_err(lnp_dev->hdev, "Invalid fan type\n"); + hid_err(lnp_dev->hdev, "Invalid fan type %d\n", lnp_dev->type); return -ENOSYS; } @@ -163,8 +180,10 @@ static inline int lnp_init(struct hid_device *hdev) sizeof(struct lnp_fan), GFP_KERNEL | __GFP_ZERO); - if (!lnp_dev->fans_data) + if (!lnp_dev->fans_data) { + hid_err(hdev, "Failed to allocate fans data\n"); return -ENOMEM; + } ret = lnp_register_fans(lnp_dev); if (ret) { @@ -179,8 +198,6 @@ static inline int lnp_init(struct hid_device *hdev) static int lnp_probe(struct hid_device *hdev, const struct hid_device_id *id) { - pr_info("Détection USB pour Lightning Node Pro\n"); - int ret; ret = hid_parse(hdev); @@ -216,7 +233,6 @@ err_stop: static void lnp_remove(struct hid_device *hdev) { - pr_info("Retrait USB pour Lightning Node Pro\n"); hid_hw_close(hdev); hid_hw_stop(hdev); } From 0d285558c3c34e97eec2a10765cad220ecf8ea82 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Mon, 10 Mar 2025 13:58:10 +0100 Subject: [PATCH 06/11] Begin add get lnp_rgb_led from cdev --- .../lightning_node_pro_led.c | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index 5b42122..384e4d4 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -49,6 +49,35 @@ struct lnp_device { void *fans_data; }; +static int lnp_rgb_let_brightness_set(struct led_classdev *cdev, + enum led_brightness) +{ + struct hid_device *hdev = to_hid_device(cdev->dev->parent); + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); + struct lnp_device *lnp_dev = hid_get_drvdata(hdev); + + int ret, fan_index, led_index; + ret = sscanf(cdev->name, "%*[^:]:%*[^:]:fan-%d-led-%d", &fan_index, + &led_index); + if (ret != 2) { + hid_warn(hdev, "Failed to get fan index and led_index for %s", + lnp_dev->dev_name); + return -ENOMSG; + } + + hid_info(hdev, "Fan Index: %d, Led Index: %d", fan_index, led_index); + + struct lnp_fan *lnp_fan = lnp_dev->fans_data + fan_index; + struct lnp_rgb_led *lnp_rgb_led = lnp_fan->rgb_leds_data + led_index; + + return 0; +} + +static enum led_brightness lnp_rgb_let_brightness_get(struct led_classdev *cdev) +{ + return 0; +} + static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, struct lnp_fan *fan_data, struct lnp_rgb_led *rgb_led_data) @@ -90,6 +119,8 @@ static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, led_cdev->brightness = 0; led_cdev->max_brightness = 255; + led_cdev->brightness_get = lnp_rgb_let_brightness_get; + led_cdev->brightness_set_blocking = lnp_rgb_let_brightness_set; ret = devm_led_classdev_multicolor_register(&hdev->dev, &rgb_led_data->cdev); From e29b9e272326e487e4f7ae168ca6ac19a610e8ef Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Tue, 11 Mar 2025 21:29:25 +0100 Subject: [PATCH 07/11] Test and fix extract fan index and led index --- .../lightning_node_pro_led.c | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index 384e4d4..8c1c0be 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -49,6 +49,22 @@ struct lnp_device { void *fans_data; }; +static inline int lnp_extract_fan_and_led_index(struct led_classdev *cdev, + int *fan_index, int *led_index) +{ + int ret; + + char *substr = strstr(cdev->name, "fan-"); + if (!substr) + return -EINVAL; + + ret = ret = sscanf(substr, "fan-%d-led-%d", fan_index, led_index); + if (ret != 2) + return -EINVAL; + + return 0; +} + static int lnp_rgb_let_brightness_set(struct led_classdev *cdev, enum led_brightness) { @@ -57,16 +73,14 @@ static int lnp_rgb_let_brightness_set(struct led_classdev *cdev, struct lnp_device *lnp_dev = hid_get_drvdata(hdev); int ret, fan_index, led_index; - ret = sscanf(cdev->name, "%*[^:]:%*[^:]:fan-%d-led-%d", &fan_index, - &led_index); - if (ret != 2) { + + ret = lnp_extract_fan_and_led_index(cdev, &fan_index, &led_index); + if (ret) { hid_warn(hdev, "Failed to get fan index and led_index for %s", lnp_dev->dev_name); - return -ENOMSG; + return ret; } - hid_info(hdev, "Fan Index: %d, Led Index: %d", fan_index, led_index); - struct lnp_fan *lnp_fan = lnp_dev->fans_data + fan_index; struct lnp_rgb_led *lnp_rgb_led = lnp_fan->rgb_leds_data + led_index; From cc1deb72bf8c25f7b93d3fdabcedc1e93c072516 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Wed, 12 Mar 2025 17:13:37 +0100 Subject: [PATCH 08/11] Add set_led_colors --- .../lightning_node_pro_led.c | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index 8c1c0be..92b5e26 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -39,7 +39,7 @@ struct lnp_fan { struct lnp_device { struct hid_device *hdev; - struct mutex lock; + spinlock_t lock; const char *dev_name; @@ -47,8 +47,33 @@ struct lnp_device { int fans_count; int rgb_leds_per_fan_count; void *fans_data; + bool update_fans_leds; }; +static inline void lnp_schedule_work(struct lnp_device *lnp_dev) +{ + unsigned long flags; + + spin_lock_irqsave(&lnp_dev->lock, flags); + // if (ds->output_worker_initialized) + // schedule_work(&ds->output_worker); + spin_unlock_irqrestore(&lnp_dev->lock, flags); +} + +static void lnp_set_led_colors(struct lnp_device *lnp_dev, + struct lnp_rgb_led *lnp_rgb_led, uint8_t red, + uint8_t green, uint8_t blue) +{ + unsigned long flags; + + spin_lock_irqsave(&lnp_dev->lock, flags); + lnp_dev->update_fans_leds = true; + lnp_rgb_led->red = red; + lnp_rgb_led->green = green; + lnp_rgb_led->blue = blue; + spin_unlock_irqrestore(&lnp_dev->lock, flags); +} + static inline int lnp_extract_fan_and_led_index(struct led_classdev *cdev, int *fan_index, int *led_index) { @@ -58,7 +83,7 @@ static inline int lnp_extract_fan_and_led_index(struct led_classdev *cdev, if (!substr) return -EINVAL; - ret = ret = sscanf(substr, "fan-%d-led-%d", fan_index, led_index); + ret = sscanf(substr, "fan-%d-led-%d", fan_index, led_index); if (ret != 2) return -EINVAL; @@ -66,7 +91,7 @@ static inline int lnp_extract_fan_and_led_index(struct led_classdev *cdev, } static int lnp_rgb_let_brightness_set(struct led_classdev *cdev, - enum led_brightness) + enum led_brightness brightness) { struct hid_device *hdev = to_hid_device(cdev->dev->parent); struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); @@ -83,6 +108,15 @@ static int lnp_rgb_let_brightness_set(struct led_classdev *cdev, struct lnp_fan *lnp_fan = lnp_dev->fans_data + fan_index; struct lnp_rgb_led *lnp_rgb_led = lnp_fan->rgb_leds_data + led_index; + uint8_t red, green, blue; + + led_mc_calc_color_components(mc_cdev, brightness); + + red = mc_cdev->subled_info[0].brightness; + green = mc_cdev->subled_info[1].brightness; + blue = mc_cdev->subled_info[2].brightness; + + lnp_set_led_colors(lnp_dev, lnp_rgb_led, red, green, blue); return 0; } @@ -208,8 +242,6 @@ static inline int lnp_init(struct hid_device *hdev) lnp_dev->hdev = hdev; lnp_dev->dev_name = dev_name(&hdev->dev); - mutex_init(&lnp_dev->lock); - lnp_dev->type = LNP_LED_LL120; // Only support LL120 for now lnp_dev->fans_count = number_of_fan; From ca62408dc511df47b6890c6ce953d1c5be5d84ff Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Wed, 12 Mar 2025 21:16:00 +0100 Subject: [PATCH 09/11] Begin implement packets --- .../lightning_node_pro_led.c | 122 ++++++++++++++++-- 1 file changed, 112 insertions(+), 10 deletions(-) diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index 92b5e26..8be8b5b 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -12,8 +12,8 @@ #define MSG_SIZE 64 #define RED_COLOR 0x00 -#define BLUE_COLOR 0x01 -#define GREEN_COLOR 0x02 +#define GREEN_COLOR 0x01 +#define BLUE_COLOR 0x02 static short int number_of_fan = 1; module_param(number_of_fan, short, 0000); @@ -48,15 +48,107 @@ struct lnp_device { int rgb_leds_per_fan_count; void *fans_data; bool update_fans_leds; + + struct work_struct output_worker; + bool output_worker_initialized; }; +static int lnp_send_reports(struct hid_device *hdev, u8 **pkts, u8 pkts_count) +{ + int i, ret; + + for (i = 0; i < pkts_count; i++) { + u8 *pkt = *(pkts + i); + + ret = hid_hw_output_report(hdev, pkt, MSG_SIZE); + if (ret < 0) + return ret; + } + + return 0; +} + +static int lnp_send_fans_leds_report(struct lnp_device *led_dev) +{ + int ret; + + u8 *packets[7]; + u8 pktcolors[6][MSG_SIZE]; + + // INDEX 1 = r, 2 = g, 3 = b, 4 = s, 5 = t, 6 = u + // s, t, u are R, G, B extended for fans 3-6 + for (u8 i = 1; i <= 6; i++) { + // Prepare the packet in pktcolors[i] + u8 *pktcolor = pktcolors[i]; + + // Initialize the first 4 bytes + pktcolor[0] = 0x32; + pktcolor[1] = 0x00; + // For Fan [1-3]: 0x32, 0x00, 0x00, 0x32 + // For Fan [4-6]: 0x32, 0x00, 0x32, 0x2e + pktcolor[2] = (i > 2) ? 0x32 : 0x00; + pktcolor[3] = (i > 2) ? 0x2e : 0x32; + + // For red color the fifth Bytes must be equals to 0x00 + // For green color the fifth Bytes must be equals to 0x01 + // For blue color the fifth Bytes must be equals to 0x02 + if (i == 1 || i == 4) { + pktcolor[4] = RED_COLOR; + } + if (i == 2 || i == 5) { + pktcolor[4] = GREEN_COLOR; + } + if (i == 3 || i == 6) { + pktcolor[4] = BLUE_COLOR; + } + + packets[i - 1] = pktcolor; + } + + u8 pktend[MSG_SIZE] = { 0x33, 0xff }; + packets[6] = &pktend[0]; + + ret = lnp_send_reports(led_dev->hdev, &packets[0], + 7); // TODO: Check if 2d array usage is correct + if (ret < 0) + return ret; + + return 0; +} + +static int lnp_send_init_report(struct hid_device *hdev) +{ + int ret; + + u8 pkt1[MSG_SIZE] = { 0x37 }; + // 0x35 - Init + u8 pkt2[MSG_SIZE] = { 0x35, 0x00, 0x00, number_of_fan << 4, + 0x00, 0x01, 0x01 }; + u8 pkt3[MSG_SIZE] = { 0x3b, 0x00, 0x01 }; + u8 pkt4[MSG_SIZE] = { 0x38, 0x00, 0x02 }; + u8 pkt5[MSG_SIZE] = { 0x34 }; + u8 pkt6[MSG_SIZE] = { 0x37, 0x01 }; + u8 pkt7[MSG_SIZE] = { 0x34, 0x01 }; + u8 pkt8[MSG_SIZE] = { 0x38, 0x01, 0x01 }; + u8 pkt9[MSG_SIZE] = { 0x33, 0xff }; + + u8 *pkts[9] = { &pkt1[0], &pkt2[0], &pkt3[0], &pkt4[0], &pkt5[0], + &pkt6[0], &pkt7[0], &pkt8[0], &pkt9[0] }; + + ret = lnp_send_reports(hdev, &pkts[0], 9); + if (ret < 0) + return ret; + + return 0; +} + static inline void lnp_schedule_work(struct lnp_device *lnp_dev) { unsigned long flags; spin_lock_irqsave(&lnp_dev->lock, flags); - // if (ds->output_worker_initialized) - // schedule_work(&ds->output_worker); + if (lnp_dev->output_worker_initialized) + schedule_work(&lnp_dev->output_worker); spin_unlock_irqrestore(&lnp_dev->lock, flags); } @@ -121,11 +213,6 @@ static int lnp_rgb_let_brightness_set(struct led_classdev *cdev, return 0; } -static enum led_brightness lnp_rgb_let_brightness_get(struct led_classdev *cdev) -{ - return 0; -} - static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, struct lnp_fan *fan_data, struct lnp_rgb_led *rgb_led_data) @@ -167,7 +254,6 @@ static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev, led_cdev->brightness = 0; led_cdev->max_brightness = 255; - led_cdev->brightness_get = lnp_rgb_let_brightness_get; led_cdev->brightness_set_blocking = lnp_rgb_let_brightness_set; ret = devm_led_classdev_multicolor_register(&hdev->dev, @@ -229,6 +315,19 @@ static inline int lnp_register_fans(struct lnp_device *lnp_dev) return 0; } +static void lnp_output_worker(struct work_struct *work) +{ + struct lnp_device *lnp_dev = + container_of(work, struct lnp_device, output_worker); + unsigned long flags; + + spin_lock_irqsave(&lnp_dev->lock, flags); + + spin_unlock_irqrestore(&lnp_dev->lock, flags); + + // hid_hw_output_report(lnp_dev->hdev, data, len); +} + static inline int lnp_init(struct hid_device *hdev) { int ret; @@ -244,6 +343,9 @@ static inline int lnp_init(struct hid_device *hdev) lnp_dev->dev_name = dev_name(&hdev->dev); lnp_dev->type = LNP_LED_LL120; // Only support LL120 for now lnp_dev->fans_count = number_of_fan; + spin_lock_init(&lnp_dev->lock); + INIT_WORK(&lnp_dev->output_worker, lnp_output_worker); + lnp_dev->output_worker_initialized = true; if (lnp_dev->type == LNP_LED_LL120) { lnp_dev->rgb_leds_per_fan_count = NUMBER_OF_LEDS_PER_LL120_FAN; From f589e28d3e673c415b8187618661e309940545b4 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Thu, 13 Mar 2025 01:01:16 +0100 Subject: [PATCH 10/11] Add docs --- 10_lightning_node_pro_led/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/10_lightning_node_pro_led/README.md b/10_lightning_node_pro_led/README.md index dca7723..10e6fd1 100644 --- a/10_lightning_node_pro_led/README.md +++ b/10_lightning_node_pro_led/README.md @@ -16,4 +16,6 @@ If is attached to driver, it appear here. ## Usefull links -- https://github.com/torvalds/linux/blob/master/drivers/hid/hid-led.c \ No newline at end of file +- https://github.com/torvalds/linux/blob/master/drivers/hid/hid-led.c +- https://github.com/torvalds/linux/blob/master/drivers/hid/hid-playstation.c +- https://github.com/Legion2/CorsairLightingProtocol \ No newline at end of file From afa51c37b34fe2a70287d3bd9f8f8b56f02f2ec8 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Thu, 13 Mar 2025 13:31:22 +0100 Subject: [PATCH 11/11] Get consts from OpenRGB --- 10_lightning_node_pro_led/README.md | 2 + .../lightning_node_pro_led.c | 83 +++++++++++++++++-- 2 files changed, 77 insertions(+), 8 deletions(-) diff --git a/10_lightning_node_pro_led/README.md b/10_lightning_node_pro_led/README.md index 10e6fd1..1ba3d39 100644 --- a/10_lightning_node_pro_led/README.md +++ b/10_lightning_node_pro_led/README.md @@ -18,4 +18,6 @@ If is attached to driver, it appear here. - https://github.com/torvalds/linux/blob/master/drivers/hid/hid-led.c - https://github.com/torvalds/linux/blob/master/drivers/hid/hid-playstation.c +- https://gitlab.com/CalcProgrammer1/OpenRGB/-/blob/master/Controllers/CorsairLightingNodeController/CorsairLightingNodeController.cpp +- https://github.com/benburkhart1/lighting-node-pro - https://github.com/Legion2/CorsairLightingProtocol \ No newline at end of file diff --git a/10_lightning_node_pro_led/lightning_node_pro_led.c b/10_lightning_node_pro_led/lightning_node_pro_led.c index 8be8b5b..cc38eee 100644 --- a/10_lightning_node_pro_led/lightning_node_pro_led.c +++ b/10_lightning_node_pro_led/lightning_node_pro_led.c @@ -11,10 +11,6 @@ #define MSG_SIZE 64 -#define RED_COLOR 0x00 -#define GREEN_COLOR 0x01 -#define BLUE_COLOR 0x02 - static short int number_of_fan = 1; module_param(number_of_fan, short, 0000); MODULE_PARM_DESC(number_of_fan, @@ -24,6 +20,77 @@ enum LNP_LED_TYPE { LNP_LED_LL120, }; +enum { + LNP_PACKET_ID_FIRMWARE = + 0x02, /* Get firmware version */ + LNP_PACKET_ID_DIRECT = 0x32, /* Direct mode LED update packet */ + LNP_PACKET_ID_COMMIT = 0x33, /* Commit changes packet */ + LNP_PACKET_ID_BEGIN = 0x34, /* Begin effect packet */ + LNP_PACKET_ID_EFFECT_CONFIG = + 0x35, /* Effect mode configuration packet */ + LNP_PACKET_ID_TEMPERATURE = + 0x36, /* Update temperature value packet */ + LNP_PACKET_ID_RESET = 0x37, /* Reset channel packet */ + LNP_PACKET_ID_PORT_STATE = + 0x38, /* Set port state packet */ + LNP_PACKET_ID_BRIGHTNESS = + 0x39, /* Set brightness packet */ + LNP_PACKET_ID_LED_COUNT = + 0x3A, /* Set LED count packet */ + LNP_PACKET_ID_PROTOCOL = + 0x3B, /* Set protocol packet */ +}; + +enum { + LNP_DIRECT_CHANNEL_RED = + 0x00, /* Red channel for direct update */ + LNP_DIRECT_CHANNEL_GREEN = + 0x01, /* Green channel for direct update */ + LNP_DIRECT_CHANNEL_BLUE = + 0x02, /* Blue channel for direct update */ +}; + +enum { + LNP_PORT_STATE_HARDWARE = + 0x01, /* Effect hardware control of channel */ + LNP_PORT_STATE_SOFTWARE = + 0x02, /* Direct software control of channel */ +}; + +enum { + LNP_LED_TYPE_LED_STRIP = + 0x0A, /* Corsair LED Strip Type */ + LNP_LED_TYPE_HD_FAN = 0x0C, /* Corsair HD-series Fan Type */ + LNP_LED_TYPE_SP_FAN = 0x01, /* Corsair SP-series Fan Type */ + LNP_LED_TYPE_ML_FAN = 0x02, /* Corsair ML-series Fan Type */ +}; + +enum { + LNP_CHANNEL_1 = 0x00, /* Channel 1 */ + LNP_CHANNEL_2 = 0x01, /* Channel 2 */ + LNP_NUM_CHANNELS = 0x02, /* Number of channels */ +}; + +enum { + LNP_SPEED_FAST = 0x00, /* Fast speed */ + LNP_SPEED_MEDIUM = 0x01, /* Medium speed */ + LNP_SPEED_SLOW = 0x02, /* Slow speed */ +}; + +enum { + LNP_MODE_RAINBOW_WAVE = 0x00, /* Rainbow Wave mode */ + LNP_MODE_COLOR_SHIFT = 0x01, /* Color Shift mode */ + LNP_MODE_COLOR_PULSE = 0x02, /* Color Pulse mode */ + LNP_MODE_COLOR_WAVE = 0x03, /* Color Wave mode */ + LNP_MODE_STATIC = 0x04, /* Static mode */ + LNP_MODE_TEMPERATURE = 0x05, /* Temperature mode */ + LNP_MODE_VISOR = 0x06, /* Visor mode */ + LNP_MODE_MARQUEE = 0x07, /* Marquee mode */ + LNP_MODE_BLINK = 0x08, /* Blink mode */ + LNP_MODE_SEQUENTIAL = 0x09, /* Sequential mode */ + LNP_MODE_RAINBOW = 0x0A, /* Rainbow mode */ +}; + struct lnp_rgb_led { struct led_classdev_mc cdev; int led_index; @@ -93,13 +160,13 @@ static int lnp_send_fans_leds_report(struct lnp_device *led_dev) // For green color the fifth Bytes must be equals to 0x01 // For blue color the fifth Bytes must be equals to 0x02 if (i == 1 || i == 4) { - pktcolor[4] = RED_COLOR; + pktcolor[4] = LNP_DIRECT_CHANNEL_RED; } if (i == 2 || i == 5) { - pktcolor[4] = GREEN_COLOR; + pktcolor[4] = LNP_DIRECT_CHANNEL_GREEN; } if (i == 3 || i == 6) { - pktcolor[4] = BLUE_COLOR; + pktcolor[4] = LNP_DIRECT_CHANNEL_BLUE; } packets[i - 1] = pktcolor; @@ -120,7 +187,7 @@ static int lnp_send_init_report(struct hid_device *hdev) { int ret; - u8 pkt1[MSG_SIZE] = { 0x37 }; + u8 pkt1[MSG_SIZE] = { LNP_PACKET_ID_RESET }; // 0x35 - Init u8 pkt2[MSG_SIZE] = { 0x35, 0x00, 0x00, number_of_fan << 4, 0x00, 0x01, 0x01 };