struct is31fl319x_chip *chip;
struct led_classdev cdev;
u32 max_microamp;
- bool configured;
+ struct fwnode_handle *fwnode;
} leds[IS31FL319X_MAX_LEDS];
};
};
MODULE_DEVICE_TABLE(of, of_is31fl319x_match);
-static int is31fl319x_parse_child_fw(const struct device *dev,
- const struct fwnode_handle *child,
- struct is31fl319x_led *led,
- struct is31fl319x_chip *is31)
+static void is31_free_fwnode(void *data)
{
- struct led_classdev *cdev = &led->cdev;
- int ret;
-
- if (fwnode_property_read_string(child, "label", &cdev->name))
- cdev->name = fwnode_get_name(child);
+ struct is31fl319x_chip *is31 = data;
+ int i;
- ret = fwnode_property_read_string(child, "linux,default-trigger", &cdev->default_trigger);
- if (ret < 0 && ret != -EINVAL) /* is optional */
- return ret;
+ for (i = 0; i < is31->cdef->num_leds; i++) {
+ if (is31->leds[i].fwnode)
+ fwnode_handle_put(is31->leds[i].fwnode);
- led->max_microamp = is31->cdef->current_default;
- ret = fwnode_property_read_u32(child, "led-max-microamp", &led->max_microamp);
- if (!ret) {
- if (led->max_microamp < is31->cdef->current_min)
- return -EINVAL; /* not supported */
- led->max_microamp = min(led->max_microamp,
- is31->cdef->current_max);
+ is31->leds[i].fwnode = NULL;
}
-
- return 0;
}
static int is31fl319x_parse_fw(struct device *dev, struct is31fl319x_chip *is31)
"Failed to get shutdown gpio\n");
is31->cdef = device_get_match_data(dev);
+ if (!is31->cdef)
+ return -ENODEV;
+
+ ret = devm_add_action_or_reset(dev, is31_free_fwnode, is31);
+ if (ret)
+ return ret;
count = 0;
device_for_each_child_node_scoped(dev, child)
led = &is31->leds[reg - 1];
- if (led->configured)
+ if (led->fwnode)
return dev_err_probe(dev, -EINVAL, "led %u is already configured\n", reg);
- ret = is31fl319x_parse_child_fw(dev, child, led, is31);
- if (ret)
- return dev_err_probe(dev, ret, "led %u DT parsing failed\n", reg);
+ led->max_microamp = is31->cdef->current_default;
+ ret = fwnode_property_read_u32(child, "led-max-microamp", &led->max_microamp);
+ if (!ret) {
+ if (led->max_microamp < is31->cdef->current_min)
+ return dev_err_probe(dev, -EINVAL, "invalid maximum current\n");
+
+ led->max_microamp = min(led->max_microamp,
+ is31->cdef->current_max);
+ }
- led->configured = true;
+ led->fwnode = fwnode_handle_get(child);
}
is31->audio_gain_db = 0;
*/
aggregated_led_microamp = is31->cdef->current_max;
for (i = 0; i < is31->cdef->num_leds; i++)
- if (is31->leds[i].configured &&
+ if (is31->leds[i].fwnode &&
is31->leds[i].max_microamp < aggregated_led_microamp)
aggregated_led_microamp = is31->leds[i].max_microamp;
for (i = 0; i < is31->cdef->num_leds; i++) {
struct is31fl319x_led *led = &is31->leds[i];
+ struct led_init_data init_data = {};
- if (!led->configured)
+ if (!led->fwnode)
continue;
+ init_data.fwnode = led->fwnode;
+
led->chip = is31;
led->cdev.brightness_set_blocking = is31->cdef->brightness_set;
- err = devm_led_classdev_register(&client->dev, &led->cdev);
+ err = devm_led_classdev_register_ext(&client->dev, &led->cdev, &init_data);
if (err < 0)
return err;
}