Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2dbfca5a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull LED subsystem update from Bryan Wu:
 "We got some cleanup and driver for LP8860 as well as some patches for
  LED Flash Class"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds:
  leds: lp8860: Fix module dependency
  leds: lp8860: Introduce TI lp8860 4 channel LED driver
  leds: Add support for setting brightness in a synchronous way
  leds: implement sysfs interface locking mechanism
  leds: syscon: handle multiple syscon instances
  leds: delete copy/paste mistake
  leds: regulator: Convert to devm_regulator_get_exclusive
parents dab363f9 2969bb18
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
* Texas Instruments - lp8860 4-Channel LED Driver

The LP8860-Q1 is an high-efficiency LED
driver with boost controller. It has 4 high-precision
current sinks that can be controlled by a PWM input
signal, a SPI/I2C master, or both.

Required properties:
	- compatible:
		"ti,lp8860"
	- reg -  I2C slave address
	- label - Used for naming LEDs

Optional properties:
	- enable-gpio - gpio pin to enable/disable the device.
	- supply - "vled" - LED supply

Example:

leds: leds@6 {
	compatible = "ti,lp8860";
	reg = <0x2d>;
	label = "display_cluster";
	enable-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
	vled-supply = <&vbatt>;
}

For more product information please see the link below:
http://www.ti.com/product/lp8860-q1
+11 −0
Original line number Diff line number Diff line
@@ -250,6 +250,17 @@ config LEDS_LP8788
	help
	  This option enables support for the Keyboard LEDs on the LP8788 PMIC.

config LEDS_LP8860
	tristate "LED support for the TI LP8860 4 channel LED driver"
	depends on LEDS_CLASS && I2C
	select REGMAP_I2C
	help
	  If you say yes here you get support for the TI LP8860 4 channel
	  LED driver.
	  This option enables support for the display cluster LEDs
	  on the LP8860 4 channel LED driver using the I2C communication
	  bus.

config LEDS_CLEVO_MAIL
	tristate "Mail LED on Clevo notebook"
	depends on LEDS_CLASS
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o
obj-$(CONFIG_LEDS_LP5562)		+= leds-lp5562.o
obj-$(CONFIG_LEDS_LP8501)		+= leds-lp8501.o
obj-$(CONFIG_LEDS_LP8788)		+= leds-lp8788.o
obj-$(CONFIG_LEDS_LP8860)		+= leds-lp8860.o
obj-$(CONFIG_LEDS_TCA6507)		+= leds-tca6507.o
obj-$(CONFIG_LEDS_CLEVO_MAIL)		+= leds-clevo-mail.o
obj-$(CONFIG_LEDS_IPAQ_MICRO)		+= leds-ipaq-micro.o
+22 −7
Original line number Diff line number Diff line
@@ -40,17 +40,27 @@ static ssize_t brightness_store(struct device *dev,
{
	struct led_classdev *led_cdev = dev_get_drvdata(dev);
	unsigned long state;
	ssize_t ret = -EINVAL;
	ssize_t ret;

	mutex_lock(&led_cdev->led_access);

	if (led_sysfs_is_disabled(led_cdev)) {
		ret = -EBUSY;
		goto unlock;
	}

	ret = kstrtoul(buf, 10, &state);
	if (ret)
		return ret;
		goto unlock;

	if (state == LED_OFF)
		led_trigger_remove(led_cdev);
	__led_set_brightness(led_cdev, state);
	led_set_brightness(led_cdev, state);

	return size;
	ret = size;
unlock:
	mutex_unlock(&led_cdev->led_access);
	return ret;
}
static DEVICE_ATTR_RW(brightness);

@@ -99,7 +109,7 @@ static void led_timer_function(unsigned long data)
	unsigned long delay;

	if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) {
		__led_set_brightness(led_cdev, LED_OFF);
		led_set_brightness_async(led_cdev, LED_OFF);
		return;
	}

@@ -122,7 +132,7 @@ static void led_timer_function(unsigned long data)
		delay = led_cdev->blink_delay_off;
	}

	__led_set_brightness(led_cdev, brightness);
	led_set_brightness_async(led_cdev, brightness);

	/* Return in next iteration if led is in one-shot mode and we are in
	 * the final blink state so that the led is toggled each delay_on +
@@ -148,7 +158,7 @@ static void set_brightness_delayed(struct work_struct *ws)

	led_stop_software_blink(led_cdev);

	__led_set_brightness(led_cdev, led_cdev->delayed_set_value);
	led_set_brightness_async(led_cdev, led_cdev->delayed_set_value);
}

/**
@@ -214,6 +224,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
#ifdef CONFIG_LEDS_TRIGGERS
	init_rwsem(&led_cdev->trigger_lock);
#endif
	mutex_init(&led_cdev->led_access);
	/* add to the list of leds */
	down_write(&leds_list_lock);
	list_add_tail(&led_cdev->node, &leds_list);
@@ -222,6 +233,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
	if (!led_cdev->max_brightness)
		led_cdev->max_brightness = LED_FULL;

	led_cdev->flags |= SET_BRIGHTNESS_ASYNC;

	led_update_brightness(led_cdev);

	INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
@@ -267,6 +280,8 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
	down_write(&leds_list_lock);
	list_del(&led_cdev->node);
	up_write(&leds_list_lock);

	mutex_destroy(&led_cdev->led_access);
}
EXPORT_SYMBOL_GPL(led_classdev_unregister);

+33 −3
Original line number Diff line number Diff line
@@ -42,13 +42,13 @@ static void led_set_software_blink(struct led_classdev *led_cdev,

	/* never on - just set to off */
	if (!delay_on) {
		__led_set_brightness(led_cdev, LED_OFF);
		led_set_brightness_async(led_cdev, LED_OFF);
		return;
	}

	/* never off - just set to brightness */
	if (!delay_off) {
		__led_set_brightness(led_cdev, led_cdev->blink_brightness);
		led_set_brightness_async(led_cdev, led_cdev->blink_brightness);
		return;
	}

@@ -117,6 +117,8 @@ EXPORT_SYMBOL_GPL(led_stop_software_blink);
void led_set_brightness(struct led_classdev *led_cdev,
			enum led_brightness brightness)
{
	int ret = 0;

	/* delay brightness setting if need to stop soft-blink timer */
	if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) {
		led_cdev->delayed_set_value = brightness;
@@ -124,7 +126,17 @@ void led_set_brightness(struct led_classdev *led_cdev,
		return;
	}

	__led_set_brightness(led_cdev, brightness);
	if (led_cdev->flags & SET_BRIGHTNESS_ASYNC) {
		led_set_brightness_async(led_cdev, brightness);
		return;
	} else if (led_cdev->flags & SET_BRIGHTNESS_SYNC)
		ret = led_set_brightness_sync(led_cdev, brightness);
	else
		ret = -EINVAL;

	if (ret < 0)
		dev_dbg(led_cdev->dev, "Setting LED brightness failed (%d)\n",
			ret);
}
EXPORT_SYMBOL(led_set_brightness);

@@ -143,3 +155,21 @@ int led_update_brightness(struct led_classdev *led_cdev)
	return ret;
}
EXPORT_SYMBOL(led_update_brightness);

/* Caller must ensure led_cdev->led_access held */
void led_sysfs_disable(struct led_classdev *led_cdev)
{
	lockdep_assert_held(&led_cdev->led_access);

	led_cdev->flags |= LED_SYSFS_DISABLE;
}
EXPORT_SYMBOL_GPL(led_sysfs_disable);

/* Caller must ensure led_cdev->led_access held */
void led_sysfs_enable(struct led_classdev *led_cdev)
{
	lockdep_assert_held(&led_cdev->led_access);

	led_cdev->flags &= ~LED_SYSFS_DISABLE;
}
EXPORT_SYMBOL_GPL(led_sysfs_enable);
Loading