Commit 545ae665 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull LED updates from Pavel Machek:

 - New driver for TI TPS6105X

 - Add managed API to get a LED from a device driver

 - Misc fixes and updates

* tag 'leds-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds: (22 commits)
  leds: lm3692x: Disable chip on brightness 0
  leds: lm3692x: Split out lm3692x_leds_disable
  leds: lm3692x: Move lm3692x_init and rename to lm3692x_leds_enable
  leds: lm3692x: Make sure we don't exceed the maximum LED current
  dt: bindings: lm3692x: Add led-max-microamp property
  leds: lm3692x: Allow to configure over voltage protection
  dt: bindings: lm3692x: Add ti,ovp-microvolt property
  leds: populate the device's of_node
  leds: Add managed API to get a LED from a device driver
  leds: Add of_led_get() and led_put()
  leds: lm3532: add pointer to documentation and fix typo
  leds: lm3532: use extended registration so that LED can be used for backlight
  leds: lm3642: remove warnings for bad strtol, cleanup gotos
  leds: rb532: cleanup whitespace
  ledtrig-pattern: fix email address quoting in MODULE_AUTHOR()
  dt-bindings: mfd: update TI tps6105x chip bindings
  leds: tps6105x: add driver for MFD chip LED mode
  led: max77650: add of_match table
  leds: bd2802: Convert to use GPIO descriptors
  leds: pca963x: Fix open-drain initialization
  ...
parents 15f8e733 260718b3
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -18,6 +18,10 @@ Required properties:
Optional properties:
	- enable-gpios : gpio pin to enable/disable the device.
	- vled-supply : LED supply
	- ti,ovp-microvolt: Overvoltage protection in
	    micro-volt, can be 17000000, 21000000, 25000000 or
	    29000000. If ti,ovp-microvolt is not specified it
	    defaults to 29000000.

Required child properties:
	- reg : 0 - Will enable all LED sync paths
@@ -31,6 +35,8 @@ Optional child properties:
	- label : see Documentation/devicetree/bindings/leds/common.txt (deprecated)
	- linux,default-trigger :
	   see Documentation/devicetree/bindings/leds/common.txt
	- led-max-microamp :
	   see Documentation/devicetree/bindings/leds/common.txt

Example:

@@ -44,12 +50,14 @@ led-controller@36 {

	enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
	vled-supply = <&vbatt>;
	ti,ovp-microvolt = <29000000>;

	led@0 {
		reg = <0>;
		function = LED_FUNCTION_BACKLIGHT;
		color = <LED_COLOR_ID_WHITE>;
		linux,default-trigger = "backlight";
		led-max-microamp = <20000>;
	};
}

+46 −1
Original line number Diff line number Diff line
@@ -7,7 +7,22 @@ Required properties:
- compatible:		"ti,tps61050" or "ti,tps61052"
- reg:			Specifies the I2C slave address

Example:
Optional sub-node:

This subnode selects the chip's operational mode.
There can be at most one single available subnode.

- regulator: presence of this sub-node puts the chip in regulator mode.
	see ../regulator/regulator.yaml

- led: presence of this sub-node puts the chip in led mode.
	Optional properties:
	- function : see ../leds/common.txt
	- color    : see ../leds/common.txt
	- label    : see ../leds/common.txt
			(deprecated)

Example (GPIO operation only):

i2c0 {
	tps61052@33 {
@@ -15,3 +30,33 @@ i2c0 {
		reg = <0x33>;
	};
};

Example (GPIO + regulator operation):

i2c0 {
	tps61052@33 {
		compatible = "ti,tps61052";
		reg = <0x33>;

		regulator {
			regulator-min-microvolt = <5000000>;
			regulator-max-microvolt = <5000000>;
			regulator-always-on;
		};
	};
};

Example (GPIO + led operation):

#include <dt-bindings/leds/common.h>

i2c0 {
	tps61052@33 {
		compatible = "ti,tps61052";
		reg = <0x33>;

		led {
			color = <LED_COLOR_ID_WHITE>;
		};
	};
};
+10 −0
Original line number Diff line number Diff line
@@ -836,6 +836,16 @@ config LEDS_LM36274
	  Say Y to enable the LM36274 LED driver for TI LMU devices.
	  This supports the LED device LM36274.

config LEDS_TPS6105X
	tristate "LED support for TI TPS6105X"
	depends on LEDS_CLASS
	depends on TPS6105X
	default y if TPS6105X
	help
	  This driver supports TPS61050/TPS61052 LED chips.
	  It is a single boost converter primarily for white LEDs and
	  audio amplifiers.

comment "LED Triggers"
source "drivers/leds/trigger/Kconfig"

+1 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ obj-$(CONFIG_LEDS_LM3601X) += leds-lm3601x.o
obj-$(CONFIG_LEDS_TI_LMU_COMMON)	+= leds-ti-lmu-common.o
obj-$(CONFIG_LEDS_LM3697)		+= leds-lm3697.o
obj-$(CONFIG_LEDS_LM36274)		+= leds-lm36274.o
obj-$(CONFIG_LEDS_TPS6105X)		+= leds-tps6105x.o

# LED SPI Drivers
obj-$(CONFIG_LEDS_CR0014114)		+= leds-cr0014114.o
+96 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <uapi/linux/uleds.h>
#include <linux/of.h>
#include "leds.h"

static struct class *leds_class;
@@ -214,6 +215,98 @@ static int led_resume(struct device *dev)

static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);

/**
 * of_led_get() - request a LED device via the LED framework
 * @np: device node to get the LED device from
 * @index: the index of the LED
 *
 * Returns the LED device parsed from the phandle specified in the "leds"
 * property of a device tree node or a negative error-code on failure.
 */
struct led_classdev *of_led_get(struct device_node *np, int index)
{
	struct device *led_dev;
	struct led_classdev *led_cdev;
	struct device_node *led_node;

	led_node = of_parse_phandle(np, "leds", index);
	if (!led_node)
		return ERR_PTR(-ENOENT);

	led_dev = class_find_device_by_of_node(leds_class, led_node);
	of_node_put(led_node);

	if (!led_dev)
		return ERR_PTR(-EPROBE_DEFER);

	led_cdev = dev_get_drvdata(led_dev);

	if (!try_module_get(led_cdev->dev->parent->driver->owner))
		return ERR_PTR(-ENODEV);

	return led_cdev;
}
EXPORT_SYMBOL_GPL(of_led_get);

/**
 * led_put() - release a LED device
 * @led_cdev: LED device
 */
void led_put(struct led_classdev *led_cdev)
{
	module_put(led_cdev->dev->parent->driver->owner);
}
EXPORT_SYMBOL_GPL(led_put);

static void devm_led_release(struct device *dev, void *res)
{
	struct led_classdev **p = res;

	led_put(*p);
}

/**
 * devm_of_led_get - Resource-managed request of a LED device
 * @dev:	LED consumer
 * @index:	index of the LED to obtain in the consumer
 *
 * The device node of the device is parse to find the request LED device.
 * The LED device returned from this function is automatically released
 * on driver detach.
 *
 * @return a pointer to a LED device or ERR_PTR(errno) on failure.
 */
struct led_classdev *__must_check devm_of_led_get(struct device *dev,
						  int index)
{
	struct led_classdev *led;
	struct led_classdev **dr;

	if (!dev)
		return ERR_PTR(-EINVAL);

	/* Not using device tree? */
	if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
		return ERR_PTR(-ENOTSUPP);

	led = of_led_get(dev->of_node, index);
	if (IS_ERR(led))
		return led;

	dr = devres_alloc(devm_led_release, sizeof(struct led_classdev *),
			  GFP_KERNEL);
	if (!dr) {
		led_put(led);
		return ERR_PTR(-ENOMEM);
	}

	*dr = led;
	devres_add(dev, dr);

	return led;
}
EXPORT_SYMBOL_GPL(devm_of_led_get);

static int led_classdev_next_name(const char *init_name, char *name,
				  size_t len)
{
@@ -276,8 +369,10 @@ int led_classdev_register_ext(struct device *parent,
		mutex_unlock(&led_cdev->led_access);
		return PTR_ERR(led_cdev->dev);
	}
	if (init_data && init_data->fwnode)
	if (init_data && init_data->fwnode) {
		led_cdev->dev->fwnode = init_data->fwnode;
		led_cdev->dev->of_node = to_of_node(init_data->fwnode);
	}

	if (ret)
		dev_warn(parent, "Led %s renamed to %s due to name collision",
Loading