Add fans initialization
This commit is contained in:
parent
98c5360b2b
commit
b2e9dfa0c3
1 changed files with 182 additions and 18 deletions
|
@ -1,11 +1,12 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/hid.h>
|
#include <linux/hid.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/led-class-multicolor.h>
|
||||||
|
|
||||||
#define USB_VENDOR_ID_CORSAIR 0x1b1c
|
#define USB_VENDOR_ID_CORSAIR 0x1b1c
|
||||||
#define USB_DEVICE_ID_LIGHTNING_NODE_PRO 0x0c0b
|
#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 LIGHTNODE_PRO_MAX_FAN 6
|
||||||
|
|
||||||
#define MSG_SIZE 64
|
#define MSG_SIZE 64
|
||||||
|
@ -19,18 +20,155 @@ module_param(number_of_fan, short, 0000);
|
||||||
MODULE_PARM_DESC(number_of_fan,
|
MODULE_PARM_DESC(number_of_fan,
|
||||||
"Number of LL120 FAN connected to the lightning node pro");
|
"Number of LL120 FAN connected to the lightning node pro");
|
||||||
|
|
||||||
struct lightning_node_pro_led_data {
|
enum LNP_LED_TYPE {
|
||||||
struct hid_device *hdev;
|
LNP_LED_LL120,
|
||||||
struct mutex lock;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int lightning_node_pro_led_probe(struct hid_device *hdev,
|
struct lnp_rgb_led {
|
||||||
const struct hid_device_id *id)
|
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");
|
pr_info("Détection USB pour Lightning Node Pro\n");
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
struct lightning_node_pro_led_data *data;
|
struct lnp_device *data;
|
||||||
|
|
||||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -38,40 +176,66 @@ static int lightning_node_pro_led_probe(struct hid_device *hdev,
|
||||||
|
|
||||||
data->hdev = hdev;
|
data->hdev = hdev;
|
||||||
mutex_init(&data->lock);
|
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);
|
hid_set_drvdata(hdev, data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_ldata:
|
free_data:
|
||||||
kfree(data);
|
kfree(data);
|
||||||
|
|
||||||
return ret;
|
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");
|
pr_info("Retrait USB pour Lightning Node Pro\n");
|
||||||
kfree(data);
|
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,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
|
||||||
USB_DEVICE_ID_LIGHTNING_NODE_PRO) },
|
USB_DEVICE_ID_LIGHTNING_NODE_PRO) },
|
||||||
{} /* Entrée de terminaison */
|
{} /* 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",
|
.name = "lightning-node-pro",
|
||||||
.id_table = lightning_node_pro_led_table,
|
.id_table = lnp_table,
|
||||||
.probe = lightning_node_pro_led_probe,
|
.probe = lnp_probe,
|
||||||
.remove = lightning_node_pro_led_remove,
|
.remove = lnp_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_hid_driver(lightning_node_pro_led_driver);
|
module_hid_driver(lnp_driver);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Florian RICHER <florian.richer@protonmail.com>");
|
MODULE_AUTHOR("Florian RICHER <florian.richer@protonmail.com>");
|
||||||
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");
|
MODULE_VERSION("1.0");
|
Loading…
Add table
Add a link
Reference in a new issue