Changes for 5.11-rc1. Small cleanups/fixes mostly thanks to Marek,
nothing major made it in this time. -----BEGIN PGP SIGNATURE----- iF0EABECAB0WIQRPfPO7r0eAhk010v0w5/Bqldv68gUCX9oo1gAKCRAw5/Bqldv6 8nrCAKCZAnzevI69ivQujVm1yVpyt4sJKQCfRM/yEm+G+OFVV+IFUthfGictxFo= =ZcdU -----END PGP SIGNATURE----- Merge tag 'leds-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds Pull LED updates from Pavel Machek: "Small cleanups/fixes mostly thanks to Marek, nothing major made it in this time" * tag 'leds-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds: leds: turris-omnia: check for LED_COLOR_ID_RGB instead LED_COLOR_ID_MULTI leds: turris-omnia: fix checkpatch warning leds: turris-omnia: wrap to 80 columns leds: turris-omnia: use constants instead of macros for color command dt-bindings: leds: Convert pwm to yaml leds: lp50xx: Fix an error handling path in 'lp50xx_probe_dt()' leds: netxbig: add missing put_device() call in netxbig_leds_get_of_pdata() Documentation: leds: remove invalidated information
This commit is contained in:
commit
945433be36
|
@ -1,50 +0,0 @@
|
|||
LED connected to PWM
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "pwm-leds".
|
||||
|
||||
Each LED is represented as a sub-node of the pwm-leds device. Each
|
||||
node's name represents the name of the corresponding LED.
|
||||
|
||||
LED sub-node properties:
|
||||
- pwms : PWM property to point to the PWM device (phandle)/port (id) and to
|
||||
specify the period time to be used: <&phandle id period_ns>;
|
||||
- pwm-names : (optional) Name to be used by the PWM subsystem for the PWM device
|
||||
For the pwms and pwm-names property please refer to:
|
||||
Documentation/devicetree/bindings/pwm/pwm.txt
|
||||
- max-brightness : Maximum brightness possible for the LED
|
||||
- active-low : (optional) For PWMs where the LED is wired to supply
|
||||
rather than ground.
|
||||
- label : (optional)
|
||||
see Documentation/devicetree/bindings/leds/common.txt
|
||||
- linux,default-trigger : (optional)
|
||||
see Documentation/devicetree/bindings/leds/common.txt
|
||||
|
||||
Example:
|
||||
|
||||
twl_pwm: pwm {
|
||||
/* provides two PWMs (id 0, 1 for PWM1 and PWM2) */
|
||||
compatible = "ti,twl6030-pwm";
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
twl_pwmled: pwmled {
|
||||
/* provides one PWM (id 0 for Charing indicator LED) */
|
||||
compatible = "ti,twl6030-pwmled";
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
kpad {
|
||||
label = "omap4::keypad";
|
||||
pwms = <&twl_pwm 0 7812500>;
|
||||
max-brightness = <127>;
|
||||
};
|
||||
|
||||
charging {
|
||||
label = "omap4:green:chrg";
|
||||
pwms = <&twl_pwmled 0 7812500>;
|
||||
max-brightness = <255>;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,70 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/leds-pwm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: LEDs connected to PWM
|
||||
|
||||
maintainers:
|
||||
- Pavel Machek <pavel@ucw.cz>
|
||||
|
||||
description:
|
||||
Each LED is represented as a sub-node of the pwm-leds device. Each
|
||||
node's name represents the name of the corresponding LED.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: pwm-leds
|
||||
|
||||
patternProperties:
|
||||
"^led(-[0-9a-f]+)?$":
|
||||
type: object
|
||||
|
||||
$ref: common.yaml#
|
||||
|
||||
properties:
|
||||
pwms:
|
||||
maxItems: 1
|
||||
|
||||
pwm-names: true
|
||||
|
||||
max-brightness:
|
||||
description:
|
||||
Maximum brightness possible for the LED
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
active-low:
|
||||
description:
|
||||
For PWMs where the LED is wired to supply rather than ground.
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- pwms
|
||||
- max-brightness
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
led-controller {
|
||||
compatible = "pwm-leds";
|
||||
|
||||
led-1 {
|
||||
label = "omap4::keypad";
|
||||
pwms = <&twl_pwm 0 7812500>;
|
||||
max-brightness = <127>;
|
||||
};
|
||||
|
||||
led-2 {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_CHARGING;
|
||||
pwms = <&twl_pwmled 0 7812500>;
|
||||
max-brightness = <255>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -177,13 +177,3 @@ The LED Trigger core cannot be a module as the simple trigger functions
|
|||
would cause nightmare dependency issues. I see this as a minor issue
|
||||
compared to the benefits the simple trigger functionality brings. The
|
||||
rest of the LED subsystem can be modular.
|
||||
|
||||
|
||||
Future Development
|
||||
==================
|
||||
|
||||
At the moment, a trigger can't be created specifically for a single LED.
|
||||
There are a number of cases where a trigger might only be mappable to a
|
||||
particular LED (ACPI?). The addition of triggers provided by the LED driver
|
||||
should cover this option and be possible to add without breaking the
|
||||
current interface.
|
||||
|
|
|
@ -487,8 +487,10 @@ static int lp50xx_probe_dt(struct lp50xx *priv)
|
|||
*/
|
||||
mc_led_info = devm_kcalloc(priv->dev, LP50XX_LEDS_PER_MODULE,
|
||||
sizeof(*mc_led_info), GFP_KERNEL);
|
||||
if (!mc_led_info)
|
||||
return -ENOMEM;
|
||||
if (!mc_led_info) {
|
||||
ret = -ENOMEM;
|
||||
goto child_out;
|
||||
}
|
||||
|
||||
fwnode_for_each_child_node(child, led_node) {
|
||||
ret = fwnode_property_read_u32(led_node, "color",
|
||||
|
|
|
@ -448,31 +448,39 @@ static int netxbig_leds_get_of_pdata(struct device *dev,
|
|||
gpio_ext = devm_kzalloc(dev, sizeof(*gpio_ext), GFP_KERNEL);
|
||||
if (!gpio_ext) {
|
||||
of_node_put(gpio_ext_np);
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto put_device;
|
||||
}
|
||||
ret = netxbig_gpio_ext_get(dev, gpio_ext_dev, gpio_ext);
|
||||
of_node_put(gpio_ext_np);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto put_device;
|
||||
pdata->gpio_ext = gpio_ext;
|
||||
|
||||
/* Timers (optional) */
|
||||
ret = of_property_count_u32_elems(np, "timers");
|
||||
if (ret > 0) {
|
||||
if (ret % 3)
|
||||
return -EINVAL;
|
||||
if (ret % 3) {
|
||||
ret = -EINVAL;
|
||||
goto put_device;
|
||||
}
|
||||
|
||||
num_timers = ret / 3;
|
||||
timers = devm_kcalloc(dev, num_timers, sizeof(*timers),
|
||||
GFP_KERNEL);
|
||||
if (!timers)
|
||||
return -ENOMEM;
|
||||
if (!timers) {
|
||||
ret = -ENOMEM;
|
||||
goto put_device;
|
||||
}
|
||||
for (i = 0; i < num_timers; i++) {
|
||||
u32 tmp;
|
||||
|
||||
of_property_read_u32_index(np, "timers", 3 * i,
|
||||
&timers[i].mode);
|
||||
if (timers[i].mode >= NETXBIG_LED_MODE_NUM)
|
||||
return -EINVAL;
|
||||
if (timers[i].mode >= NETXBIG_LED_MODE_NUM) {
|
||||
ret = -EINVAL;
|
||||
goto put_device;
|
||||
}
|
||||
of_property_read_u32_index(np, "timers",
|
||||
3 * i + 1, &tmp);
|
||||
timers[i].delay_on = tmp;
|
||||
|
@ -488,12 +496,15 @@ static int netxbig_leds_get_of_pdata(struct device *dev,
|
|||
num_leds = of_get_available_child_count(np);
|
||||
if (!num_leds) {
|
||||
dev_err(dev, "No LED subnodes found in DT\n");
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto put_device;
|
||||
}
|
||||
|
||||
leds = devm_kcalloc(dev, num_leds, sizeof(*leds), GFP_KERNEL);
|
||||
if (!leds)
|
||||
return -ENOMEM;
|
||||
if (!leds) {
|
||||
ret = -ENOMEM;
|
||||
goto put_device;
|
||||
}
|
||||
|
||||
led = leds;
|
||||
for_each_available_child_of_node(np, child) {
|
||||
|
@ -574,6 +585,8 @@ static int netxbig_leds_get_of_pdata(struct device *dev,
|
|||
|
||||
err_node_put:
|
||||
of_node_put(child);
|
||||
put_device:
|
||||
put_device(gpio_ext_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,28 +12,20 @@
|
|||
#include <linux/of.h>
|
||||
#include "leds.h"
|
||||
|
||||
#define OMNIA_BOARD_LEDS 12
|
||||
#define OMNIA_LED_NUM_CHANNELS 3
|
||||
#define OMNIA_BOARD_LEDS 12
|
||||
#define OMNIA_LED_NUM_CHANNELS 3
|
||||
|
||||
#define CMD_LED_MODE 3
|
||||
#define CMD_LED_MODE_LED(l) ((l) & 0x0f)
|
||||
#define CMD_LED_MODE_USER 0x10
|
||||
#define CMD_LED_MODE 3
|
||||
#define CMD_LED_MODE_LED(l) ((l) & 0x0f)
|
||||
#define CMD_LED_MODE_USER 0x10
|
||||
|
||||
#define CMD_LED_STATE 4
|
||||
#define CMD_LED_STATE_LED(l) ((l) & 0x0f)
|
||||
#define CMD_LED_STATE_ON 0x10
|
||||
#define CMD_LED_STATE 4
|
||||
#define CMD_LED_STATE_LED(l) ((l) & 0x0f)
|
||||
#define CMD_LED_STATE_ON 0x10
|
||||
|
||||
#define CMD_LED_COLOR 5
|
||||
#define CMD_LED_SET_BRIGHTNESS 7
|
||||
#define CMD_LED_GET_BRIGHTNESS 8
|
||||
|
||||
#define OMNIA_CMD 0
|
||||
|
||||
#define OMNIA_CMD_LED_COLOR_LED 1
|
||||
#define OMNIA_CMD_LED_COLOR_R 2
|
||||
#define OMNIA_CMD_LED_COLOR_G 3
|
||||
#define OMNIA_CMD_LED_COLOR_B 4
|
||||
#define OMNIA_CMD_LED_COLOR_LEN 5
|
||||
#define CMD_LED_COLOR 5
|
||||
#define CMD_LED_SET_BRIGHTNESS 7
|
||||
#define CMD_LED_GET_BRIGHTNESS 8
|
||||
|
||||
struct omnia_led {
|
||||
struct led_classdev_mc mc_cdev;
|
||||
|
@ -41,7 +33,7 @@ struct omnia_led {
|
|||
int reg;
|
||||
};
|
||||
|
||||
#define to_omnia_led(l) container_of(l, struct omnia_led, mc_cdev)
|
||||
#define to_omnia_led(l) container_of(l, struct omnia_led, mc_cdev)
|
||||
|
||||
struct omnia_leds {
|
||||
struct i2c_client *client;
|
||||
|
@ -55,21 +47,21 @@ static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
|
|||
struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
|
||||
struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
|
||||
struct omnia_led *led = to_omnia_led(mc_cdev);
|
||||
u8 buf[OMNIA_CMD_LED_COLOR_LEN], state;
|
||||
u8 buf[5], state;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&leds->lock);
|
||||
|
||||
led_mc_calc_color_components(&led->mc_cdev, brightness);
|
||||
|
||||
buf[OMNIA_CMD] = CMD_LED_COLOR;
|
||||
buf[OMNIA_CMD_LED_COLOR_LED] = led->reg;
|
||||
buf[OMNIA_CMD_LED_COLOR_R] = mc_cdev->subled_info[0].brightness;
|
||||
buf[OMNIA_CMD_LED_COLOR_G] = mc_cdev->subled_info[1].brightness;
|
||||
buf[OMNIA_CMD_LED_COLOR_B] = mc_cdev->subled_info[2].brightness;
|
||||
buf[0] = CMD_LED_COLOR;
|
||||
buf[1] = led->reg;
|
||||
buf[2] = mc_cdev->subled_info[0].brightness;
|
||||
buf[3] = mc_cdev->subled_info[1].brightness;
|
||||
buf[4] = mc_cdev->subled_info[2].brightness;
|
||||
|
||||
state = CMD_LED_STATE_LED(led->reg);
|
||||
if (buf[OMNIA_CMD_LED_COLOR_R] || buf[OMNIA_CMD_LED_COLOR_G] || buf[OMNIA_CMD_LED_COLOR_B])
|
||||
if (buf[2] || buf[3] || buf[4])
|
||||
state |= CMD_LED_STATE_ON;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_STATE, state);
|
||||
|
@ -98,9 +90,9 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
|
|||
}
|
||||
|
||||
ret = of_property_read_u32(np, "color", &color);
|
||||
if (ret || color != LED_COLOR_ID_MULTI) {
|
||||
if (ret || color != LED_COLOR_ID_RGB) {
|
||||
dev_warn(dev,
|
||||
"Node %pOF: must contain 'color' property with value LED_COLOR_ID_MULTI\n",
|
||||
"Node %pOF: must contain 'color' property with value LED_COLOR_ID_RGB\n",
|
||||
np);
|
||||
return 0;
|
||||
}
|
||||
|
@ -126,18 +118,21 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
|
|||
CMD_LED_MODE_LED(led->reg) |
|
||||
CMD_LED_MODE_USER);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np, ret);
|
||||
dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np,
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* disable the LED */
|
||||
ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE, CMD_LED_STATE_LED(led->reg));
|
||||
ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE,
|
||||
CMD_LED_STATE_LED(led->reg));
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev, &init_data);
|
||||
ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev,
|
||||
&init_data);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Cannot register LED %pOF: %i\n", np, ret);
|
||||
return ret;
|
||||
|
@ -157,7 +152,8 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
|
|||
* file lives in the device directory of the LED controller, not an individual
|
||||
* LED, so it should not confuse users.
|
||||
*/
|
||||
static ssize_t brightness_show(struct device *dev, struct device_attribute *a, char *buf)
|
||||
static ssize_t brightness_show(struct device *dev, struct device_attribute *a,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct omnia_leds *leds = i2c_get_clientdata(client);
|
||||
|
@ -173,22 +169,23 @@ static ssize_t brightness_show(struct device *dev, struct device_attribute *a, c
|
|||
return sprintf(buf, "%d\n", ret);
|
||||
}
|
||||
|
||||
static ssize_t brightness_store(struct device *dev, struct device_attribute *a, const char *buf,
|
||||
size_t count)
|
||||
static ssize_t brightness_store(struct device *dev, struct device_attribute *a,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct omnia_leds *leds = i2c_get_clientdata(client);
|
||||
unsigned int brightness;
|
||||
unsigned long brightness;
|
||||
int ret;
|
||||
|
||||
if (sscanf(buf, "%u", &brightness) != 1)
|
||||
if (kstrtoul(buf, 10, &brightness))
|
||||
return -EINVAL;
|
||||
|
||||
if (brightness > 100)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&leds->lock);
|
||||
ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS, (u8) brightness);
|
||||
ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS,
|
||||
(u8)brightness);
|
||||
mutex_unlock(&leds->lock);
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -250,18 +247,18 @@ static int omnia_leds_probe(struct i2c_client *client,
|
|||
|
||||
static int omnia_leds_remove(struct i2c_client *client)
|
||||
{
|
||||
u8 buf[OMNIA_CMD_LED_COLOR_LEN];
|
||||
u8 buf[5];
|
||||
|
||||
/* put all LEDs into default (HW triggered) mode */
|
||||
i2c_smbus_write_byte_data(client, CMD_LED_MODE,
|
||||
CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
|
||||
|
||||
/* set all LEDs color to [255, 255, 255] */
|
||||
buf[OMNIA_CMD] = CMD_LED_COLOR;
|
||||
buf[OMNIA_CMD_LED_COLOR_LED] = OMNIA_BOARD_LEDS;
|
||||
buf[OMNIA_CMD_LED_COLOR_R] = 255;
|
||||
buf[OMNIA_CMD_LED_COLOR_G] = 255;
|
||||
buf[OMNIA_CMD_LED_COLOR_B] = 255;
|
||||
buf[0] = CMD_LED_COLOR;
|
||||
buf[1] = OMNIA_BOARD_LEDS;
|
||||
buf[2] = 255;
|
||||
buf[3] = 255;
|
||||
buf[4] = 255;
|
||||
|
||||
i2c_master_send(client, buf, 5);
|
||||
|
||||
|
|
Loading…
Reference in New Issue