diff options
Diffstat (limited to 'drivers/led/led-pwm.c')
-rw-r--r-- | drivers/led/led-pwm.c | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/drivers/led/led-pwm.c b/drivers/led/led-pwm.c index 16d22b5569..6f4abf97c8 100644 --- a/drivers/led/led-pwm.c +++ b/drivers/led/led-pwm.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * pwm LED support for barebox * * (C) Copyright 2010 Sascha Hauer, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> #include <malloc.h> @@ -23,52 +10,61 @@ #include <led.h> #include <pwm.h> #include <of.h> -#include <asm-generic/div64.h> +#include <linux/math64.h> struct pwmled { bool active_low; struct led led; struct pwm_device *pwm; - uint32_t period; }; static void led_pwm_set(struct led *led, unsigned int brightness) { struct pwmled *pwmled = container_of(led, struct pwmled, led); - unsigned long long duty = pwmled->period; + unsigned long long duty; + struct pwm_state state; unsigned int max = pwmled->led.max_value; - duty *= brightness; + pwm_get_state(pwmled->pwm, &state); + + duty = state.period * brightness; do_div(duty, max); - pwm_config(pwmled->pwm, duty, pwmled->period); + if (pwmled->active_low) + duty = state.period - duty; + + state.enabled = true; + state.duty_cycle = duty; + + pwm_apply_state(pwmled->pwm, &state); } -static int led_pwm_of_probe(struct device_d *dev) +static int led_pwm_of_probe(struct device *dev) { struct device_node *child; int ret; - for_each_child_of_node(dev->device_node, child) { + for_each_child_of_node(dev->of_node, child) { struct pwmled *pwmled; struct pwm_device *pwm; pwm = of_pwm_request(child, NULL); - if (pwm < 0) + if (IS_ERR(pwm)) continue; pwmled = xzalloc(sizeof(*pwmled)); pwmled->led.name = xstrdup(child->name); pwmled->pwm = pwm; - of_property_read_u32(child, "max-brightness", &pwmled->led.max_value); + ret = of_property_read_u32(child, "max-brightness", &pwmled->led.max_value); + if (ret) + return ret; - pwmled->period = pwm_get_period(pwmled->pwm); + pwmled->active_low = of_property_read_bool(child, "active-low"); pwmled->led.set = led_pwm_set; - pwm_config(pwmled->pwm, 0, pwmled->period); - pwm_enable(pwmled->pwm); + led_pwm_set(&pwmled->led, 0); ret = led_register(&pwmled->led); if (ret) @@ -84,8 +80,9 @@ static struct of_device_id led_pwm_of_ids[] = { { .compatible = "pwm-leds", }, { } }; +MODULE_DEVICE_TABLE(of, led_pwm_of_ids); -static struct driver_d led_pwm_of_driver = { +static struct driver led_pwm_of_driver = { .name = "pwm-leds", .probe = led_pwm_of_probe, .of_compatible = DRV_OF_COMPAT(led_pwm_of_ids), |