in leds-pwm.c [61:133]
static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
struct led_pwm *led, struct fwnode_handle *fwnode)
{
struct led_pwm_data *led_data = &priv->leds[priv->num_leds];
struct led_init_data init_data = { .fwnode = fwnode };
int ret;
led_data->active_low = led->active_low;
led_data->cdev.name = led->name;
led_data->cdev.brightness = LED_OFF;
led_data->cdev.max_brightness = led->max_brightness;
led_data->cdev.flags = LED_CORE_SUSPENDRESUME;
led_data->pwm = devm_fwnode_pwm_get(dev, fwnode, NULL);
if (IS_ERR(led_data->pwm))
return dev_err_probe(dev, PTR_ERR(led_data->pwm),
"unable to request PWM for %s\n",
led->name);
led_data->cdev.brightness_set_blocking = led_pwm_set;
/* init PWM state */
switch (led->default_state) {
case LEDS_DEFSTATE_KEEP:
pwm_get_state(led_data->pwm, &led_data->pwmstate);
if (led_data->pwmstate.period)
break;
led->default_state = LEDS_DEFSTATE_OFF;
dev_warn(dev,
"failed to read period for %s, default to off",
led->name);
fallthrough;
default:
pwm_init_state(led_data->pwm, &led_data->pwmstate);
break;
}
/* set brightness */
switch (led->default_state) {
case LEDS_DEFSTATE_ON:
led_data->cdev.brightness = led->max_brightness;
break;
case LEDS_DEFSTATE_KEEP:
{
uint64_t brightness;
brightness = led->max_brightness;
brightness *= led_data->pwmstate.duty_cycle;
do_div(brightness, led_data->pwmstate.period);
led_data->cdev.brightness = brightness;
}
break;
}
ret = devm_led_classdev_register_ext(dev, &led_data->cdev, &init_data);
if (ret) {
dev_err(dev, "failed to register PWM led for %s: %d\n",
led->name, ret);
return ret;
}
if (led->default_state != LEDS_DEFSTATE_KEEP) {
ret = led_pwm_set(&led_data->cdev, led_data->cdev.brightness);
if (ret) {
dev_err(dev, "failed to set led PWM value for %s: %d",
led->name, ret);
return ret;
}
}
priv->num_leds++;
return 0;
}