Use device linked allocator instead and led registering
This commit is contained in:
parent
b2e9dfa0c3
commit
c780a8e857
1 changed files with 88 additions and 123 deletions
|
@ -26,6 +26,7 @@ enum LNP_LED_TYPE {
|
||||||
|
|
||||||
struct lnp_rgb_led {
|
struct lnp_rgb_led {
|
||||||
struct led_classdev_mc cdev;
|
struct led_classdev_mc cdev;
|
||||||
|
int led_index;
|
||||||
uint8_t red;
|
uint8_t red;
|
||||||
uint8_t green;
|
uint8_t green;
|
||||||
uint8_t blue;
|
uint8_t blue;
|
||||||
|
@ -45,122 +46,101 @@ struct lnp_device {
|
||||||
void *fans_data;
|
void *fans_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int lnp_register_rgb_led(struct rgb_led *rgb_led_data,
|
static inline int lnp_register_rgb_led(struct lnp_device *lnp_dev,
|
||||||
int fan_number)
|
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,
|
mc_leds_info = devm_kmalloc_array(&hdev->dev, 3, sizeof(*mc_leds_info),
|
||||||
int fan_number)
|
GFP_KERNEL);
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lnp_register_fan(struct lnp_fan *fan_data, int rgb_leds_count)
|
if (!mc_leds_info)
|
||||||
{
|
return -ENOMEM;
|
||||||
int ret, led_index;
|
|
||||||
|
|
||||||
fan_data->rgb_leds_data = kzalloc(
|
mc_leds_info[0].color_index = LED_COLOR_ID_RED;
|
||||||
sizeof(struct lnp_rgb_led) * rgb_leds_count, GFP_KERNEL);
|
mc_leds_info[1].color_index = LED_COLOR_ID_GREEN;
|
||||||
if (!fan_data->rgb_leds_data) {
|
mc_leds_info[2].color_index = LED_COLOR_ID_BLUE;
|
||||||
ret = -ENOMEM;
|
|
||||||
goto fail_alloc_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (led_index = 0; led_index < fan_data->rgb_leds_count; led_index++) {
|
rgb_led_data->cdev.subled_info = mc_leds_info;
|
||||||
struct lnp_rgb_led *rgb_led_data =
|
rgb_led_data->cdev.num_colors = 3;
|
||||||
fan_data->rgb_leds_data + led_index;
|
|
||||||
|
|
||||||
ret = lnp_register_rgb_led(rgb_led_data, fan_data->fan_index);
|
led_cdev = &rgb_led_data->cdev.led_cdev;
|
||||||
if (ret)
|
led_cdev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
|
||||||
goto fail_register_leds;
|
"ll120:rgb:fan-%d-led-%d",
|
||||||
}
|
fan_data->fan_index,
|
||||||
|
rgb_led_data->led_index);
|
||||||
|
if (!led_cdev->name)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
return 0;
|
led_cdev->brightness = 0;
|
||||||
|
led_cdev->max_brightness = 255;
|
||||||
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);
|
|
||||||
|
|
||||||
|
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 ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lnp_unregister_fan(struct lnp_fan *fan_data)
|
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;
|
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++) {
|
for (led_index = 0; led_index < fan_data->rgb_leds_count; led_index++) {
|
||||||
struct lnp_rgb_led *rgb_led_data =
|
struct lnp_rgb_led *rgb_led_data =
|
||||||
fan_data->rgb_leds_data + led_index;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int lnp_register_fans(struct lnp_device *data, int rgb_leds_count)
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int lnp_register_fans(struct lnp_device *lnp_dev)
|
||||||
{
|
{
|
||||||
int ret, fan_index, led_index;
|
int ret, fan_index;
|
||||||
struct lnp_fan *fans_data = data->fans_data;
|
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;
|
struct lnp_fan *fan_data = fans_data + fan_index;
|
||||||
fan_data->fan_index = 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)
|
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;
|
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;
|
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)
|
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");
|
pr_info("Détection USB pour Lightning Node Pro\n");
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
struct lnp_device *data;
|
struct lnp_device *lnp_dev;
|
||||||
|
|
||||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
lnp_dev = devm_kzalloc(&hdev->dev, sizeof(*lnp_dev), GFP_KERNEL);
|
||||||
if (!data)
|
if (!lnp_dev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
data->hdev = hdev;
|
lnp_dev->hdev = hdev;
|
||||||
mutex_init(&data->lock);
|
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) {
|
lnp_dev->fans_data = devm_kmalloc_array(&lnp_dev->hdev->dev,
|
||||||
case LNP_LED_LL120:
|
lnp_dev->fans_count,
|
||||||
ret = lnp_ll120_register(data);
|
sizeof(struct lnp_fan),
|
||||||
break;
|
GFP_KERNEL | __GFP_ZERO);
|
||||||
default:
|
|
||||||
ret = -ENOSYS;
|
if (!lnp_dev->fans_data)
|
||||||
pr_err("Fan type invalid\n");
|
return -ENOMEM;
|
||||||
break;
|
|
||||||
|
ret = lnp_register_fans(lnp_dev);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(lnp_dev->hdev, "Failed to register device\n");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
hid_set_drvdata(hdev, lnp_dev);
|
||||||
goto free_data;
|
|
||||||
|
|
||||||
hid_set_drvdata(hdev, data);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_data:
|
|
||||||
kfree(data);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lnp_remove(struct hid_device *hdev)
|
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");
|
pr_info("Retrait USB pour Lightning Node Pro\n");
|
||||||
kfree(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hid_device_id lnp_table[] = {
|
static struct hid_device_id lnp_table[] = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue