diff options
Diffstat (limited to 'drivers/leds')
| -rw-r--r-- | drivers/leds/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/leds/flash/leds-rt4505.c | 2 | ||||
| -rw-r--r-- | drivers/leds/flash/leds-rt8515.c | 2 | ||||
| -rw-r--r-- | drivers/leds/flash/leds-sgm3140.c | 3 | ||||
| -rw-r--r-- | drivers/leds/flash/leds-tps6131x.c | 2 | ||||
| -rw-r--r-- | drivers/leds/led-class.c | 6 | ||||
| -rw-r--r-- | drivers/leds/leds-cros_ec.c | 5 | ||||
| -rw-r--r-- | drivers/leds/leds-lp50xx.c | 67 | ||||
| -rw-r--r-- | drivers/leds/leds-max5970.c | 2 | ||||
| -rw-r--r-- | drivers/leds/leds-max77705.c | 2 | ||||
| -rw-r--r-- | drivers/leds/leds-netxbig.c | 36 | ||||
| -rw-r--r-- | drivers/leds/leds-pwm.c | 27 | ||||
| -rw-r--r-- | drivers/leds/leds-upboard.c | 2 | ||||
| -rw-r--r-- | drivers/leds/rgb/leds-ktd202x.c | 4 | ||||
| -rw-r--r-- | drivers/leds/rgb/leds-ncp5623.c | 2 | ||||
| -rw-r--r-- | drivers/leds/rgb/leds-qcom-lpg.c | 10 | ||||
| -rw-r--r-- | drivers/leds/trigger/ledtrig-input-events.c | 2 |
17 files changed, 116 insertions, 66 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 06e6291be11b..11e7282dc297 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -214,10 +214,6 @@ config LEDS_EL15203000 To compile this driver as a module, choose M here: the module will be called leds-el15203000. -config LEDS_EXPRESSWIRE - bool - depends on GPIOLIB - config LEDS_TURRIS_OMNIA tristate "LED support for CZ.NIC's Turris Omnia" depends on LEDS_CLASS_MULTICOLOR @@ -443,8 +439,8 @@ config LEDS_LP55XX_COMMON depends on LEDS_CLASS_MULTICOLOR depends on OF depends on I2C - select FW_LOADER - select FW_LOADER_USER_HELPER + imply FW_LOADER + imply FW_LOADER_USER_HELPER help This option supports common operations for LP5521/5523/55231/5562/5569/ 8501 devices. diff --git a/drivers/leds/flash/leds-rt4505.c b/drivers/leds/flash/leds-rt4505.c index f16358b8dfc1..18fd5b7e528f 100644 --- a/drivers/leds/flash/leds-rt4505.c +++ b/drivers/leds/flash/leds-rt4505.c @@ -365,7 +365,7 @@ static int rt4505_probe(struct i2c_client *client) return ret; } - child = fwnode_get_next_available_child_node(client->dev.fwnode, NULL); + child = device_get_next_child_node(&client->dev, NULL); if (!child) { dev_err(priv->dev, "Failed to get child node\n"); return -EINVAL; diff --git a/drivers/leds/flash/leds-rt8515.c b/drivers/leds/flash/leds-rt8515.c index 6af0d2c7fc56..f6b439674c03 100644 --- a/drivers/leds/flash/leds-rt8515.c +++ b/drivers/leds/flash/leds-rt8515.c @@ -304,7 +304,7 @@ static int rt8515_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(rt->enable_torch), "cannot get ENT (enable torch) GPIO\n"); - child = fwnode_get_next_available_child_node(dev->fwnode, NULL); + child = device_get_next_child_node(dev, NULL); if (!child) { dev_err(dev, "No fwnode child node found for connected LED.\n"); diff --git a/drivers/leds/flash/leds-sgm3140.c b/drivers/leds/flash/leds-sgm3140.c index 3e83200675f2..dc6840357370 100644 --- a/drivers/leds/flash/leds-sgm3140.c +++ b/drivers/leds/flash/leds-sgm3140.c @@ -214,8 +214,7 @@ static int sgm3140_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, ret, "Failed to request regulator\n"); - child_node = fwnode_get_next_available_child_node(pdev->dev.fwnode, - NULL); + child_node = device_get_next_child_node(&pdev->dev, NULL); if (!child_node) { dev_err(&pdev->dev, "No fwnode child node found for connected LED.\n"); diff --git a/drivers/leds/flash/leds-tps6131x.c b/drivers/leds/flash/leds-tps6131x.c index 6f4d4fd55361..f0f1f2b77d5a 100644 --- a/drivers/leds/flash/leds-tps6131x.c +++ b/drivers/leds/flash/leds-tps6131x.c @@ -544,7 +544,7 @@ static int tps6131x_parse_node(struct tps6131x *tps6131x) tps6131x->valley_current_limit = device_property_read_bool(dev, "ti,valley-current-limit"); - tps6131x->led_node = fwnode_get_next_available_child_node(dev->fwnode, NULL); + tps6131x->led_node = device_get_next_child_node(dev, NULL); if (!tps6131x->led_node) { dev_err(dev, "Missing LED node\n"); return -EINVAL; diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index f3faf37f9a08..885399ed0776 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -38,7 +38,7 @@ static ssize_t brightness_show(struct device *dev, brightness = led_cdev->brightness; mutex_unlock(&led_cdev->led_access); - return sprintf(buf, "%u\n", brightness); + return sysfs_emit(buf, "%u\n", brightness); } static ssize_t brightness_store(struct device *dev, @@ -80,7 +80,7 @@ static ssize_t max_brightness_show(struct device *dev, max_brightness = led_cdev->max_brightness; mutex_unlock(&led_cdev->led_access); - return sprintf(buf, "%u\n", max_brightness); + return sysfs_emit(buf, "%u\n", max_brightness); } static DEVICE_ATTR_RO(max_brightness); @@ -122,7 +122,7 @@ static ssize_t brightness_hw_changed_show(struct device *dev, if (led_cdev->brightness_hw_changed == -1) return -ENODATA; - return sprintf(buf, "%u\n", led_cdev->brightness_hw_changed); + return sysfs_emit(buf, "%u\n", led_cdev->brightness_hw_changed); } static DEVICE_ATTR_RO(brightness_hw_changed); diff --git a/drivers/leds/leds-cros_ec.c b/drivers/leds/leds-cros_ec.c index 377cf04e202a..bea3cc3fbfd2 100644 --- a/drivers/leds/leds-cros_ec.c +++ b/drivers/leds/leds-cros_ec.c @@ -142,9 +142,6 @@ static int cros_ec_led_count_subleds(struct device *dev, } } - if (!num_subleds) - return -EINVAL; - *max_brightness = common_range; return num_subleds; } @@ -189,6 +186,8 @@ static int cros_ec_led_probe_one(struct device *dev, struct cros_ec_device *cros &priv->led_mc_cdev.led_cdev.max_brightness); if (num_subleds < 0) return num_subleds; + if (num_subleds == 0) + return 0; /* LED without any colors, skip */ priv->cros_ec = cros_ec; priv->led_id = id; diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c index 94f8ef6b482c..e2a9c8592953 100644 --- a/drivers/leds/leds-lp50xx.c +++ b/drivers/leds/leds-lp50xx.c @@ -50,11 +50,17 @@ #define LP50XX_SW_RESET 0xff #define LP50XX_CHIP_EN BIT(6) +#define LP50XX_CHIP_DISABLE 0x00 +#define LP50XX_START_TIME_US 500 +#define LP50XX_RESET_TIME_US 3 + +#define LP50XX_EN_GPIO_LOW 0 +#define LP50XX_EN_GPIO_HIGH 1 /* There are 3 LED outputs per bank */ #define LP50XX_LEDS_PER_MODULE 3 -#define LP5009_MAX_LED_MODULES 2 +#define LP5009_MAX_LED_MODULES 3 #define LP5012_MAX_LED_MODULES 4 #define LP5018_MAX_LED_MODULES 6 #define LP5024_MAX_LED_MODULES 8 @@ -341,17 +347,15 @@ out: return ret; } -static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[]) +static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[], int num_leds) { u8 led_config_lo, led_config_hi; u32 bank_enable_mask = 0; int ret; int i; - for (i = 0; i < priv->chip_info->max_modules; i++) { - if (led_banks[i]) - bank_enable_mask |= (1 << led_banks[i]); - } + for (i = 0; i < num_leds; i++) + bank_enable_mask |= (1 << led_banks[i]); led_config_lo = bank_enable_mask; led_config_hi = bank_enable_mask >> 8; @@ -371,19 +375,42 @@ static int lp50xx_reset(struct lp50xx *priv) return regmap_write(priv->regmap, priv->chip_info->reset_reg, LP50XX_SW_RESET); } -static int lp50xx_enable_disable(struct lp50xx *priv, int enable_disable) +static int lp50xx_enable(struct lp50xx *priv) { int ret; - ret = gpiod_direction_output(priv->enable_gpio, enable_disable); + if (priv->enable_gpio) { + ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_HIGH); + if (ret) + return ret; + + udelay(LP50XX_START_TIME_US); + } + + ret = lp50xx_reset(priv); if (ret) return ret; - if (enable_disable) - return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); - else - return regmap_write(priv->regmap, LP50XX_DEV_CFG0, 0); + return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); +} + +static int lp50xx_disable(struct lp50xx *priv) +{ + int ret; + + ret = regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_DISABLE); + if (ret) + return ret; + if (priv->enable_gpio) { + ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_LOW); + if (ret) + return ret; + + udelay(LP50XX_RESET_TIME_US); + } + + return 0; } static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv, @@ -405,7 +432,7 @@ static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv, return ret; } - ret = lp50xx_set_banks(priv, led_banks); + ret = lp50xx_set_banks(priv, led_banks, num_leds); if (ret) { dev_err(priv->dev, "Cannot setup banked LEDs\n"); return ret; @@ -447,6 +474,10 @@ static int lp50xx_probe_dt(struct lp50xx *priv) return dev_err_probe(priv->dev, PTR_ERR(priv->enable_gpio), "Failed to get enable GPIO\n"); + ret = lp50xx_enable(priv); + if (ret) + return ret; + priv->regulator = devm_regulator_get(priv->dev, "vled"); if (IS_ERR(priv->regulator)) priv->regulator = NULL; @@ -547,14 +578,6 @@ static int lp50xx_probe(struct i2c_client *client) return ret; } - ret = lp50xx_reset(led); - if (ret) - return ret; - - ret = lp50xx_enable_disable(led, 1); - if (ret) - return ret; - return lp50xx_probe_dt(led); } @@ -563,7 +586,7 @@ static void lp50xx_remove(struct i2c_client *client) struct lp50xx *led = i2c_get_clientdata(client); int ret; - ret = lp50xx_enable_disable(led, 0); + ret = lp50xx_disable(led); if (ret) dev_err(led->dev, "Failed to disable chip\n"); diff --git a/drivers/leds/leds-max5970.c b/drivers/leds/leds-max5970.c index 285074c53b23..a1e91a06249c 100644 --- a/drivers/leds/leds-max5970.c +++ b/drivers/leds/leds-max5970.c @@ -60,7 +60,7 @@ static int max5970_led_probe(struct platform_device *pdev) if (!led_node) return -ENODEV; - fwnode_for_each_available_child_node(led_node, child) { + fwnode_for_each_child_node(led_node, child) { u32 reg; if (fwnode_property_read_u32(child, "reg", ®)) diff --git a/drivers/leds/leds-max77705.c b/drivers/leds/leds-max77705.c index b7403b3fcf5e..1e2054c1bf80 100644 --- a/drivers/leds/leds-max77705.c +++ b/drivers/leds/leds-max77705.c @@ -191,7 +191,7 @@ static int max77705_add_led(struct device *dev, struct regmap *regmap, struct fw cdev->brightness_set_blocking = max77705_led_brightness_set_multi; cdev->blink_set = max77705_rgb_blink; - fwnode_for_each_available_child_node(np, child) { + fwnode_for_each_child_node(np, child) { ret = max77705_parse_subled(dev, child, &info[i]); if (ret < 0) return ret; diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index e95287416ef8..99df46f2d9f5 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c @@ -364,6 +364,9 @@ static int netxbig_gpio_ext_get(struct device *dev, if (!addr) return -ENOMEM; + gpio_ext->addr = addr; + gpio_ext->num_addr = 0; + /* * We cannot use devm_ managed resources with these GPIO descriptors * since they are associated with the "GPIO extension device" which @@ -375,45 +378,58 @@ static int netxbig_gpio_ext_get(struct device *dev, gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, GPIOD_OUT_LOW); if (IS_ERR(gpiod)) - return PTR_ERR(gpiod); + goto err_set_code; gpiod_set_consumer_name(gpiod, "GPIO extension addr"); addr[i] = gpiod; + gpio_ext->num_addr++; } - gpio_ext->addr = addr; - gpio_ext->num_addr = num_addr; ret = gpiod_count(gpio_ext_dev, "data"); if (ret < 0) { dev_err(dev, "Failed to count GPIOs in DT property data-gpios\n"); - return ret; + goto err_free_addr; } num_data = ret; data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; + if (!data) { + ret = -ENOMEM; + goto err_free_addr; + } + + gpio_ext->data = data; + gpio_ext->num_data = 0; for (i = 0; i < num_data; i++) { gpiod = gpiod_get_index(gpio_ext_dev, "data", i, GPIOD_OUT_LOW); if (IS_ERR(gpiod)) - return PTR_ERR(gpiod); + goto err_free_data; gpiod_set_consumer_name(gpiod, "GPIO extension data"); data[i] = gpiod; + gpio_ext->num_data++; } - gpio_ext->data = data; - gpio_ext->num_data = num_data; gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(gpiod)) { dev_err(dev, "Failed to get GPIO from DT property enable-gpio\n"); - return PTR_ERR(gpiod); + goto err_free_data; } gpiod_set_consumer_name(gpiod, "GPIO extension enable"); gpio_ext->enable = gpiod; return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); + +err_free_data: + for (i = 0; i < gpio_ext->num_data; i++) + gpiod_put(gpio_ext->data[i]); +err_set_code: + ret = PTR_ERR(gpiod); +err_free_addr: + for (i = 0; i < gpio_ext->num_addr; i++) + gpiod_put(gpio_ext->addr[i]); + return ret; } static int netxbig_leds_get_of_pdata(struct device *dev, diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index c73134e7b951..6c1f2f50ff85 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -9,12 +9,13 @@ * based on leds-gpio.c by Raphael Assenat <raph@8d.com> */ -#include <linux/module.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> #include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/of.h> #include <linux/leds.h> -#include <linux/err.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/pwm.h> #include <linux/slab.h> @@ -26,6 +27,7 @@ struct led_pwm { }; struct led_pwm_data { + struct gpio_desc *enable_gpio; struct led_classdev cdev; struct pwm_device *pwm; struct pwm_state pwmstate; @@ -51,6 +53,8 @@ static int led_pwm_set(struct led_classdev *led_cdev, if (led_dat->active_low) duty = led_dat->pwmstate.period - duty; + gpiod_set_value_cansleep(led_dat->enable_gpio, !!brightness); + led_dat->pwmstate.duty_cycle = duty; /* * Disabling a PWM doesn't guarantee that it emits the inactive level. @@ -132,6 +136,21 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv, break; } + /* + * Claim the GPIO as GPIOD_ASIS and set the value + * later on to honor the different default states + */ + led_data->enable_gpio = devm_fwnode_gpiod_get(dev, fwnode, "enable", GPIOD_ASIS, NULL); + if (IS_ERR(led_data->enable_gpio)) { + if (PTR_ERR(led_data->enable_gpio) == -ENOENT) + /* Enable GPIO is optional */ + led_data->enable_gpio = NULL; + else + return PTR_ERR(led_data->enable_gpio); + } + + gpiod_direction_output(led_data->enable_gpio, !!led_data->cdev.brightness); + 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", diff --git a/drivers/leds/leds-upboard.c b/drivers/leds/leds-upboard.c index b350eb294280..12989b2f1953 100644 --- a/drivers/leds/leds-upboard.c +++ b/drivers/leds/leds-upboard.c @@ -123,4 +123,4 @@ MODULE_AUTHOR("Gary Wang <garywang@aaeon.com.tw>"); MODULE_AUTHOR("Thomas Richard <thomas.richard@bootlin.com>"); MODULE_DESCRIPTION("UP Board LED driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:upboard-led"); +MODULE_ALIAS("platform:upboard-leds"); diff --git a/drivers/leds/rgb/leds-ktd202x.c b/drivers/leds/rgb/leds-ktd202x.c index 04e62faa3a00..e4f0f25a5e45 100644 --- a/drivers/leds/rgb/leds-ktd202x.c +++ b/drivers/leds/rgb/leds-ktd202x.c @@ -391,7 +391,7 @@ static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct fwnode_handle *fwn int i = 0; num_channels = 0; - fwnode_for_each_available_child_node(fwnode, child) + fwnode_for_each_child_node(fwnode, child) num_channels++; if (!num_channels || num_channels > chip->num_leds) @@ -401,7 +401,7 @@ static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct fwnode_handle *fwn if (!info) return -ENOMEM; - fwnode_for_each_available_child_node(fwnode, child) { + fwnode_for_each_child_node(fwnode, child) { u32 mono_color; u32 reg; int ret; diff --git a/drivers/leds/rgb/leds-ncp5623.c b/drivers/leds/rgb/leds-ncp5623.c index 7c7d44623a9e..85d6be6fff2b 100644 --- a/drivers/leds/rgb/leds-ncp5623.c +++ b/drivers/leds/rgb/leds-ncp5623.c @@ -180,7 +180,7 @@ static int ncp5623_probe(struct i2c_client *client) goto release_mc_node; } - fwnode_for_each_available_child_node(mc_node, led_node) { + fwnode_for_each_child_node(mc_node, led_node) { ret = fwnode_property_read_u32(led_node, "color", &color_index); if (ret) goto release_led_node; diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c index 4f2a178e3d26..72da0bf469ad 100644 --- a/drivers/leds/rgb/leds-qcom-lpg.c +++ b/drivers/leds/rgb/leds-qcom-lpg.c @@ -2,7 +2,7 @@ /* * Copyright (c) 2017-2022 Linaro Ltd * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include <linux/bits.h> #include <linux/bitfield.h> @@ -1247,8 +1247,6 @@ static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, lpg_apply(chan); - triled_set(lpg, chan->triled_mask, chan->enabled ? chan->triled_mask : 0); - out_unlock: mutex_unlock(&lpg->lock); @@ -1382,7 +1380,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np) return dev_err_probe(lpg->dev, ret, "failed to parse \"color\" of %pOF\n", np); - if (color == LED_COLOR_ID_RGB) + if (color == LED_COLOR_ID_RGB || color == LED_COLOR_ID_MULTI) num_channels = of_get_available_child_count(np); else num_channels = 1; @@ -1394,7 +1392,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np) led->lpg = lpg; led->num_channels = num_channels; - if (color == LED_COLOR_ID_RGB) { + if (color == LED_COLOR_ID_RGB || color == LED_COLOR_ID_MULTI) { info = devm_kcalloc(lpg->dev, num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; @@ -1454,7 +1452,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np) init_data.fwnode = of_fwnode_handle(np); - if (color == LED_COLOR_ID_RGB) + if (color == LED_COLOR_ID_RGB || color == LED_COLOR_ID_MULTI) ret = devm_led_classdev_multicolor_register_ext(lpg->dev, &led->mcdev, &init_data); else ret = devm_led_classdev_register_ext(lpg->dev, &led->cdev, &init_data); diff --git a/drivers/leds/trigger/ledtrig-input-events.c b/drivers/leds/trigger/ledtrig-input-events.c index 1c79731562c2..3c6414259c27 100644 --- a/drivers/leds/trigger/ledtrig-input-events.c +++ b/drivers/leds/trigger/ledtrig-input-events.c @@ -66,7 +66,7 @@ static void input_events_event(struct input_handle *handle, unsigned int type, spin_unlock_irqrestore(&data->lock, flags); - mod_delayed_work(system_wq, &data->work, led_off_delay); + mod_delayed_work(system_percpu_wq, &data->work, led_off_delay); } static int input_events_connect(struct input_handler *handler, struct input_dev *dev, |
