From ca62408dc511df47b6890c6ce953d1c5be5d84ff Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Wed, 12 Mar 2025 21:16:00 +0100 Subject: [PATCH] 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;