From a124cb33a8f9b18f18383e8e52392771736d6814 Mon Sep 17 00:00:00 2001
From: Florian RICHER <florian.richer@protonmail.com>
Date: Sun, 9 Mar 2025 20:13:23 +0100
Subject: [PATCH] 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[] = {