mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'for-leds-next' of https://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/adi,ltc3220.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices LTC3220 LED Driver
|
||||
|
||||
maintainers:
|
||||
- Edelweise Escala <edelweise.escala@analog.com>
|
||||
|
||||
description: >
|
||||
The LTC3220 is a multi-display LED driver, which contains a high-efficiency,
|
||||
low-noise charge pump to provide power to up to 18 LED current sources.
|
||||
The LEDs are individually configurable to 64-step linear brightness control,
|
||||
blinking and gradation control via 2-wire I2C interface.
|
||||
|
||||
For more product information please see the link below
|
||||
https://www.analog.com/en/products/ltc3220.html
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: adi,ltc3220
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
'^led@([1-9a-f]|1[0-2])$':
|
||||
type: object
|
||||
$ref: /schemas/leds/common.yaml#
|
||||
unevaluatedProperties: false
|
||||
properties:
|
||||
reg:
|
||||
description:
|
||||
Output channel for the LED (1-18 maps to LED outputs D1-D18).
|
||||
Unit-address must be in hexadecimal (1-12 hex = 1-18 decimal).
|
||||
For aggregated LED control, define only one LED node with reg = <0x1>
|
||||
and use led-sources to list all controlled outputs. Only reg 1 should
|
||||
be present when using led-sources.
|
||||
items:
|
||||
- minimum: 1
|
||||
maximum: 18
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
if:
|
||||
required:
|
||||
- led-sources
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#address-cells'
|
||||
- '#size-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
// Independent LEDs
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led-controller@1c {
|
||||
compatible = "adi,ltc3220";
|
||||
reg = <0x1c>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reset-gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
|
||||
|
||||
led@1 {
|
||||
reg = <0x1>;
|
||||
function = LED_FUNCTION_INDICATOR;
|
||||
function-enumerator = <1>;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <0x2>;
|
||||
function = LED_FUNCTION_INDICATOR;
|
||||
function-enumerator = <2>;
|
||||
};
|
||||
|
||||
led@3 {
|
||||
reg = <0x3>;
|
||||
function = LED_FUNCTION_INDICATOR;
|
||||
function-enumerator = <3>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
// Aggregated LED
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led-controller@1c {
|
||||
compatible = "adi,ltc3220";
|
||||
reg = <0x1c>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@1 {
|
||||
reg = <0x1>;
|
||||
led-sources = <0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12>;
|
||||
function = LED_FUNCTION_BACKLIGHT;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -0,0 +1,96 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/brcm,bcm6358-leds.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: LEDs connected to Broadcom BCM6358 controller
|
||||
|
||||
description: |
|
||||
This controller is present on BCM6358 and BCM6368.
|
||||
In these SoCs there are Serial LEDs (LEDs connected to a 74x164 controller),
|
||||
which can either be controlled by software (exporting the 74x164 as spi-gpio.
|
||||
See Documentation/devicetree/bindings/gpio/fairchild,74hc595.yaml), or
|
||||
by hardware using this driver.
|
||||
|
||||
maintainers:
|
||||
- Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: brcm,bcm6358-leds
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
brcm,clk-div:
|
||||
description: SCK signal divider.
|
||||
default: 1
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [1, 2, 4, 8]
|
||||
|
||||
brcm,clk-dat-low:
|
||||
description: Makes clock and data signals active low.
|
||||
type: boolean
|
||||
|
||||
patternProperties:
|
||||
"^led@1?[0-9a-f]$":
|
||||
type: object
|
||||
$ref: common.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: Each LED is represented as a sub-node of
|
||||
this device.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: LED pin number (0 to 31).
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/leds/common.h>
|
||||
led-controller@fffe00d0 {
|
||||
compatible = "brcm,bcm6358-leds";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xfffe00d0 0x8>;
|
||||
|
||||
led@0 {
|
||||
reg = <0>;
|
||||
active-low;
|
||||
label = "white:alarm";
|
||||
};
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
active-low;
|
||||
label = "white:tv";
|
||||
};
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
active-low;
|
||||
label = "white:tel";
|
||||
};
|
||||
led@4 {
|
||||
reg = <4>;
|
||||
active-low;
|
||||
label = "white:adsl";
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -73,6 +73,16 @@ properties:
|
||||
- keep
|
||||
default: off
|
||||
|
||||
default-intensity:
|
||||
description:
|
||||
The initial intensity of the LED color component. As the intensity of
|
||||
each sub-LED is multiplied with the overall brightness, without this
|
||||
property on a sub-LED, it may effectively be initialized at minimum
|
||||
brightness regardless of its linux,default-trigger and default-brightness
|
||||
properties.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 0
|
||||
|
||||
linux,default-trigger:
|
||||
description:
|
||||
This parameter, if present, is a string defining the trigger assigned to
|
||||
@@ -106,6 +116,8 @@ properties:
|
||||
- bluetooth-power
|
||||
# LED indicates camera flash state
|
||||
- flash
|
||||
# LED indicates level of GPIO input referenced by trigger-sources
|
||||
- gpio
|
||||
# LED indicated keyboard capslock
|
||||
- kbd-capslock
|
||||
# LED indicates MTD memory activity
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
LEDs connected to Broadcom BCM6358 controller
|
||||
|
||||
This controller is present on BCM6358 and BCM6368.
|
||||
In these SoCs there are Serial LEDs (LEDs connected to a 74x164 controller),
|
||||
which can either be controlled by software (exporting the 74x164 as spi-gpio.
|
||||
See Documentation/devicetree/bindings/gpio/fairchild,74hc595.yaml), or
|
||||
by hardware using this driver.
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "brcm,bcm6358-leds".
|
||||
- #address-cells : must be 1.
|
||||
- #size-cells : must be 0.
|
||||
- reg : BCM6358 LED controller address and size.
|
||||
|
||||
Optional properties:
|
||||
- brcm,clk-div : SCK signal divider. Possible values are 1, 2, 4 and 8.
|
||||
Default : 1
|
||||
- brcm,clk-dat-low : Boolean, makes clock and data signals active low.
|
||||
Default : false
|
||||
|
||||
Each LED is represented as a sub-node of the brcm,bcm6358-leds device.
|
||||
|
||||
LED sub-node required properties:
|
||||
- reg : LED pin number (only LEDs 0 to 31 are valid).
|
||||
|
||||
LED sub-node optional properties:
|
||||
- label : see Documentation/devicetree/bindings/leds/common.txt
|
||||
- default-state : see
|
||||
Documentation/devicetree/bindings/leds/common.txt
|
||||
- linux,default-trigger : see
|
||||
Documentation/devicetree/bindings/leds/common.txt
|
||||
|
||||
Examples:
|
||||
Scenario 1 : BCM6358
|
||||
leds0: led-controller@fffe00d0 {
|
||||
compatible = "brcm,bcm6358-leds";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xfffe00d0 0x8>;
|
||||
|
||||
alarm_white {
|
||||
reg = <0>;
|
||||
active-low;
|
||||
label = "white:alarm";
|
||||
};
|
||||
tv_white {
|
||||
reg = <2>;
|
||||
active-low;
|
||||
label = "white:tv";
|
||||
};
|
||||
tel_white {
|
||||
reg = <3>;
|
||||
active-low;
|
||||
label = "white:tel";
|
||||
};
|
||||
adsl_white {
|
||||
reg = <4>;
|
||||
active-low;
|
||||
label = "white:adsl";
|
||||
};
|
||||
};
|
||||
|
||||
Scenario 2 : BCM6368
|
||||
leds0: led-controller@100000d0 {
|
||||
compatible = "brcm,bcm6358-leds";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x100000d0 0x8>;
|
||||
brcm,pol-low;
|
||||
brcm,clk-div = <4>;
|
||||
|
||||
power_red {
|
||||
reg = <0>;
|
||||
active-low;
|
||||
label = "red:power";
|
||||
};
|
||||
power_green {
|
||||
reg = <1>;
|
||||
active-low;
|
||||
label = "green:power";
|
||||
default-state = "on";
|
||||
};
|
||||
power_blue {
|
||||
reg = <2>;
|
||||
label = "blue:power";
|
||||
};
|
||||
broadband_red {
|
||||
reg = <3>;
|
||||
active-low;
|
||||
label = "red:broadband";
|
||||
};
|
||||
broadband_green {
|
||||
reg = <4>;
|
||||
label = "green:broadband";
|
||||
};
|
||||
broadband_blue {
|
||||
reg = <5>;
|
||||
active-low;
|
||||
label = "blue:broadband";
|
||||
};
|
||||
wireless_red {
|
||||
reg = <6>;
|
||||
active-low;
|
||||
label = "red:wireless";
|
||||
};
|
||||
wireless_green {
|
||||
reg = <7>;
|
||||
active-low;
|
||||
label = "green:wireless";
|
||||
};
|
||||
wireless_blue {
|
||||
reg = <8>;
|
||||
label = "blue:wireless";
|
||||
};
|
||||
phone_red {
|
||||
reg = <9>;
|
||||
active-low;
|
||||
label = "red:phone";
|
||||
};
|
||||
phone_green {
|
||||
reg = <10>;
|
||||
active-low;
|
||||
label = "green:phone";
|
||||
};
|
||||
phone_blue {
|
||||
reg = <11>;
|
||||
label = "blue:phone";
|
||||
};
|
||||
upgrading_red {
|
||||
reg = <12>;
|
||||
active-low;
|
||||
label = "red:upgrading";
|
||||
};
|
||||
upgrading_green {
|
||||
reg = <13>;
|
||||
active-low;
|
||||
label = "green:upgrading";
|
||||
};
|
||||
upgrading_blue {
|
||||
reg = <14>;
|
||||
label = "blue:upgrading";
|
||||
};
|
||||
};
|
||||
@@ -45,6 +45,8 @@ properties:
|
||||
|
||||
color: true
|
||||
|
||||
default-intensity: true
|
||||
|
||||
required:
|
||||
- pwms
|
||||
- color
|
||||
@@ -63,12 +65,14 @@ examples:
|
||||
|
||||
multi-led {
|
||||
color = <LED_COLOR_ID_RGB>;
|
||||
linux,default-trigger = "default-on";
|
||||
function = LED_FUNCTION_INDICATOR;
|
||||
max-brightness = <65535>;
|
||||
|
||||
led-red {
|
||||
pwms = <&pwm1 0 1000000>;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
default-intensity = <65535>;
|
||||
};
|
||||
|
||||
led-green {
|
||||
|
||||
@@ -16,8 +16,9 @@ in terms of PWM duty-cycle and duration (ms).
|
||||
To be compatible with the hardware pattern format, maximum 8 tuples of
|
||||
brightness (PWM) and duration must be written to hw_pattern.
|
||||
|
||||
- Brightness range: 0-255
|
||||
- Min pattern duration: 22 ms
|
||||
- Max pattern duration: 5660 ms
|
||||
- Max pattern duration: 5610 ms
|
||||
|
||||
The format of the hardware pattern values should be:
|
||||
"brightness duration brightness duration ..."
|
||||
@@ -26,9 +27,7 @@ The format of the hardware pattern values should be:
|
||||
----------------------------
|
||||
|
||||
Specify a pattern repeat number, which is common for all channels.
|
||||
Default is 1; negative numbers and 0 are invalid.
|
||||
Default is 1. Writing 0 is invalid. Writing -1 or 255 repeats the
|
||||
pattern indefinitely.
|
||||
|
||||
This file will always return the originally written repeat number.
|
||||
|
||||
When the 255 value is written to it, all patterns will repeat
|
||||
indefinitely.
|
||||
|
||||
@@ -15451,6 +15451,14 @@ W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
|
||||
F: drivers/iio/temperature/ltc2983.c
|
||||
|
||||
LTC3220 LED DRIVER
|
||||
M: Edelweise Escala <edelweise.escala@analog.com>
|
||||
L: linux-leds@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/leds/adi,ltc3220.yaml
|
||||
F: drivers/leds/leds-ltc3220.c
|
||||
|
||||
LTC4282 HARDWARE MONITOR DRIVER
|
||||
M: Nuno Sa <nuno.sa@analog.com>
|
||||
L: linux-hwmon@vger.kernel.org
|
||||
|
||||
@@ -1000,6 +1000,19 @@ config LEDS_ST1202
|
||||
Say Y to enable support for LEDs connected to LED1202
|
||||
LED driver chips accessed via the I2C bus.
|
||||
|
||||
config LEDS_LTC3220
|
||||
tristate "LED Driver for Analog Devices Inc. LTC3220"
|
||||
depends on I2C && LEDS_CLASS
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say Y to enable support for the Analog Devices LTC3220
|
||||
18-channel LED controller with I2C interface.
|
||||
The driver supports individual LED brightness control (64 steps),
|
||||
hardware-assisted blinking and gradation effects.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called leds-ltc3220.
|
||||
|
||||
config LEDS_TPS6105X
|
||||
tristate "LED support for TI TPS6105X"
|
||||
depends on LEDS_CLASS
|
||||
|
||||
@@ -61,6 +61,7 @@ obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
|
||||
obj-$(CONFIG_LEDS_LP8860) += leds-lp8860.o
|
||||
obj-$(CONFIG_LEDS_LP8864) += leds-lp8864.o
|
||||
obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o
|
||||
obj-$(CONFIG_LEDS_LTC3220) += leds-ltc3220.o
|
||||
obj-$(CONFIG_LEDS_MAX5970) += leds-max5970.o
|
||||
obj-$(CONFIG_LEDS_MAX77650) += leds-max77650.o
|
||||
obj-$(CONFIG_LEDS_MAX77705) += leds-max77705.o
|
||||
|
||||
@@ -236,8 +236,8 @@ static void bcm63138_leds_create_led(struct bcm63138_leds *leds,
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(led->cdev.dev);
|
||||
if (IS_ERR(pinctrl) && PTR_ERR(pinctrl) != -ENODEV) {
|
||||
dev_warn(led->cdev.dev, "Failed to select %pOF pinctrl: %ld\n",
|
||||
np, PTR_ERR(pinctrl));
|
||||
dev_warn(led->cdev.dev, "Failed to select %pOF pinctrl: %pe\n",
|
||||
np, pinctrl);
|
||||
}
|
||||
|
||||
bit = BIT(led->pin);
|
||||
|
||||
+35
-17
@@ -9,8 +9,8 @@
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/gpio/legacy.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/overflow.h>
|
||||
@@ -211,7 +211,6 @@ static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,
|
||||
const struct gpio_led *template)
|
||||
{
|
||||
struct gpio_desc *gpiod;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* This means the LED does not come from the device tree
|
||||
@@ -222,16 +221,29 @@ static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,
|
||||
gpiod = devm_gpiod_get_index_optional(dev, NULL, idx, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod))
|
||||
return gpiod;
|
||||
if (gpiod) {
|
||||
gpiod_set_consumer_name(gpiod, template->name);
|
||||
return gpiod;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the legacy code path for platform code that
|
||||
* still uses GPIO numbers. Ultimately we would like to get
|
||||
* rid of this block completely.
|
||||
*/
|
||||
gpiod_set_consumer_name(gpiod, template->name);
|
||||
return gpiod;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GPIOLIB_LEGACY
|
||||
/*
|
||||
* This is the legacy code path for platform code that still uses
|
||||
* GPIO numbers, mainly MIPS and SuperH board files.
|
||||
* Ultimately we would like to get rid of this block completely.
|
||||
*
|
||||
* ppc44x-warp sets the template->gpiod directly instead of
|
||||
* adding a lookup table or device properties. This is not
|
||||
* much better.
|
||||
*/
|
||||
static struct gpio_desc *gpio_led_get_legacy_gpiod(struct device *dev, int idx,
|
||||
const struct gpio_led *template)
|
||||
{
|
||||
struct gpio_desc *gpiod;
|
||||
int ret;
|
||||
|
||||
if (template->gpiod)
|
||||
return template->gpiod;
|
||||
|
||||
/* skip leds that aren't available */
|
||||
if (!gpio_is_valid(template->gpio))
|
||||
@@ -251,6 +263,13 @@ static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,
|
||||
|
||||
return gpiod;
|
||||
}
|
||||
#else
|
||||
static struct gpio_desc *gpio_led_get_legacy_gpiod(struct device *dev, int idx,
|
||||
const struct gpio_led *template)
|
||||
{
|
||||
return template->gpiod ?: ERR_PTR(-ENOENT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int gpio_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
@@ -269,14 +288,13 @@ static int gpio_led_probe(struct platform_device *pdev)
|
||||
const struct gpio_led *template = &pdata->leds[i];
|
||||
struct gpio_led_data *led_dat = &priv->leds[i];
|
||||
|
||||
if (template->gpiod)
|
||||
led_dat->gpiod = template->gpiod;
|
||||
else
|
||||
led_dat->gpiod = gpio_led_get_gpiod(dev, i, template);
|
||||
if (!led_dat->gpiod)
|
||||
led_dat->gpiod =
|
||||
gpio_led_get_gpiod(dev, i, template);
|
||||
gpio_led_get_legacy_gpiod(dev, i, template);
|
||||
if (IS_ERR(led_dat->gpiod)) {
|
||||
dev_info(dev, "Skipping unavailable LED gpio %d (%s)\n",
|
||||
template->gpio, template->name);
|
||||
dev_info(dev, "Skipping unavailable LED gpio %s\n",
|
||||
template->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -327,9 +327,9 @@ static int pca9532_gpio_set_value(struct gpio_chip *gc, unsigned int offset,
|
||||
struct pca9532_led *led = &data->leds[offset];
|
||||
|
||||
if (val)
|
||||
led->state = PCA9532_ON;
|
||||
else
|
||||
led->state = PCA9532_OFF;
|
||||
else
|
||||
led->state = PCA9532_ON;
|
||||
|
||||
pca9532_setled(led);
|
||||
|
||||
@@ -349,7 +349,7 @@ static int pca9532_gpio_get_value(struct gpio_chip *gc, unsigned offset)
|
||||
static int pca9532_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
/* To use as input ensure pin is not driven */
|
||||
pca9532_gpio_set_value(gc, offset, 0);
|
||||
pca9532_gpio_set_value(gc, offset, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -397,10 +397,14 @@ static int pca9532_configure(struct i2c_client *client,
|
||||
for (i = 0; i < 2; i++) {
|
||||
data->pwm[i] = pdata->pwm[i];
|
||||
data->psc[i] = pdata->psc[i];
|
||||
i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, i),
|
||||
data->pwm[i]);
|
||||
i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, i),
|
||||
data->psc[i]);
|
||||
err = i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, i),
|
||||
data->pwm[i]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, i),
|
||||
data->psc[i]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
data->hw_blink = true;
|
||||
|
||||
+63
-39
@@ -31,10 +31,11 @@
|
||||
#define ST1202_ILED_REG0 0x09
|
||||
#define ST1202_MAX_LEDS 12
|
||||
#define ST1202_MAX_PATTERNS 8
|
||||
#define ST1202_MILLIS_PATTERN_DUR_MAX 5660
|
||||
#define ST1202_MILLIS_PATTERN_DUR_MAX (ST1202_MILLIS_PATTERN_DUR_MIN * U8_MAX)
|
||||
#define ST1202_MILLIS_PATTERN_DUR_MIN 22
|
||||
#define ST1202_PATTERN_DUR 0x16
|
||||
#define ST1202_PATTERN_PWM 0x1E
|
||||
#define ST1202_PATTERN_PWM_FULL 0x0FFF
|
||||
#define ST1202_PATTERN_REP 0x15
|
||||
|
||||
struct st1202_led {
|
||||
@@ -85,7 +86,7 @@ static int st1202_write_reg(struct st1202_chip *chip, int reg, uint8_t val)
|
||||
|
||||
static uint8_t st1202_prescalar_to_miliseconds(unsigned int value)
|
||||
{
|
||||
return value / ST1202_MILLIS_PATTERN_DUR_MIN - 1;
|
||||
return value / ST1202_MILLIS_PATTERN_DUR_MIN;
|
||||
}
|
||||
|
||||
static int st1202_pwm_pattern_write(struct st1202_chip *chip, int led_num,
|
||||
@@ -127,37 +128,11 @@ static int st1202_duration_pattern_write(struct st1202_chip *chip, int pattern,
|
||||
st1202_prescalar_to_miliseconds(value));
|
||||
}
|
||||
|
||||
static void st1202_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
struct st1202_led *led = cdev_to_st1202_led(led_cdev);
|
||||
struct st1202_chip *chip = led->chip;
|
||||
|
||||
guard(mutex)(&chip->lock);
|
||||
|
||||
st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
|
||||
}
|
||||
|
||||
static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev)
|
||||
{
|
||||
struct st1202_led *led = cdev_to_st1202_led(led_cdev);
|
||||
struct st1202_chip *chip = led->chip;
|
||||
u8 value = 0;
|
||||
|
||||
guard(mutex)(&chip->lock);
|
||||
|
||||
st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
|
||||
static int __st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
|
||||
{
|
||||
u8 chan_low, chan_high;
|
||||
int ret;
|
||||
|
||||
guard(mutex)(&chip->lock);
|
||||
|
||||
if (led_num <= 7) {
|
||||
ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_LOW, &chan_low);
|
||||
if (ret < 0)
|
||||
@@ -185,6 +160,40 @@ static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
|
||||
{
|
||||
guard(mutex)(&chip->lock);
|
||||
|
||||
return __st1202_channel_set(chip, led_num, active);
|
||||
}
|
||||
|
||||
static void st1202_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
struct st1202_led *led = cdev_to_st1202_led(led_cdev);
|
||||
struct st1202_chip *chip = led->chip;
|
||||
|
||||
guard(mutex)(&chip->lock);
|
||||
|
||||
for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++)
|
||||
st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL);
|
||||
st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
|
||||
__st1202_channel_set(chip, led->led_num, !!value);
|
||||
}
|
||||
|
||||
static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev)
|
||||
{
|
||||
struct st1202_led *led = cdev_to_st1202_led(led_cdev);
|
||||
struct st1202_chip *chip = led->chip;
|
||||
u8 value = 0;
|
||||
|
||||
guard(mutex)(&chip->lock);
|
||||
|
||||
st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static int st1202_led_set(struct led_classdev *ldev, enum led_brightness value)
|
||||
{
|
||||
struct st1202_led *led = cdev_to_st1202_led(ldev);
|
||||
@@ -200,12 +209,16 @@ static int st1202_led_pattern_clear(struct led_classdev *ldev)
|
||||
|
||||
guard(mutex)(&chip->lock);
|
||||
|
||||
ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) {
|
||||
ret = st1202_pwm_pattern_write(chip, led->led_num, patt, LED_OFF);
|
||||
ret = st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = st1202_duration_pattern_write(chip, patt, ST1202_MILLIS_PATTERN_DUR_MIN);
|
||||
ret = st1202_write_reg(chip, ST1202_PATTERN_DUR + patt, 0);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -224,13 +237,19 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
|
||||
if (len > ST1202_MAX_PATTERNS)
|
||||
return -EINVAL;
|
||||
|
||||
guard(mutex)(&chip->lock);
|
||||
|
||||
for (int patt = 0; patt < len; patt++) {
|
||||
if (pattern[patt].delta_t < ST1202_MILLIS_PATTERN_DUR_MIN ||
|
||||
pattern[patt].delta_t > ST1202_MILLIS_PATTERN_DUR_MAX)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
guard(mutex)(&chip->lock);
|
||||
|
||||
ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
for (int patt = 0; patt < len; patt++) {
|
||||
ret = st1202_pwm_pattern_write(chip, led->led_num, patt, pattern[patt].brightness);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
@@ -244,6 +263,10 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = __st1202_channel_set(chip, led->led_num, true);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = st1202_write_reg(chip, ST1202_CONFIG_REG, (ST1202_CONFIG_REG_PATSR |
|
||||
ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_SHFT));
|
||||
if (ret != 0)
|
||||
@@ -256,13 +279,19 @@ static int st1202_dt_init(struct st1202_chip *chip)
|
||||
{
|
||||
struct device *dev = &chip->client->dev;
|
||||
struct st1202_led *led;
|
||||
int err, reg;
|
||||
int err;
|
||||
u32 reg;
|
||||
|
||||
for_each_available_child_of_node_scoped(dev_of_node(dev), child) {
|
||||
err = of_property_read_u32(child, "reg", ®);
|
||||
if (err)
|
||||
return dev_err_probe(dev, err, "Invalid register\n");
|
||||
|
||||
if (reg >= ST1202_MAX_LEDS)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"LED reg %u out of range [0, %d]\n",
|
||||
reg, ST1202_MAX_LEDS - 1);
|
||||
|
||||
led = &chip->leds[reg];
|
||||
led->is_active = true;
|
||||
led->fwnode = of_fwnode_handle(child);
|
||||
@@ -322,11 +351,6 @@ static int st1202_setup(struct st1202_chip *chip)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = st1202_write_reg(chip, ST1202_CONFIG_REG,
|
||||
ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_PATSR);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -204,9 +204,9 @@ int lp5860_device_init(struct device *dev)
|
||||
mutex_lock(&lp->lock);
|
||||
ret = regmap_update_bits(lp->regmap, LP5860_REG_DEV_INITIAL, LP5860_MODE_MASK,
|
||||
LP5860_MODE_1 << LP5860_MODE_SHIFT);
|
||||
mutex_unlock(&lp->lock);
|
||||
if (ret)
|
||||
goto err_disable;
|
||||
mutex_unlock(&lp->lock);
|
||||
|
||||
ret = lp5860_init_dt(lp);
|
||||
if (ret)
|
||||
@@ -215,7 +215,6 @@ int lp5860_device_init(struct device *dev)
|
||||
return 0;
|
||||
|
||||
err_disable:
|
||||
mutex_unlock(&lp->lock);
|
||||
lp5860_chip_enable(lp, LP5860_CHIP_DISABLE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ static int lp5860_probe(struct spi_device *spi)
|
||||
struct device *dev = &spi->dev;
|
||||
struct lp5860 *lp5860;
|
||||
unsigned int multi_leds;
|
||||
int ret;
|
||||
|
||||
multi_leds = device_get_child_node_count(dev);
|
||||
if (!multi_leds) {
|
||||
@@ -61,7 +62,10 @@ static int lp5860_probe(struct spi_device *spi)
|
||||
"Failed to initialise Regmap.\n");
|
||||
|
||||
lp5860->dev = dev;
|
||||
mutex_init(&lp5860->lock);
|
||||
|
||||
ret = devm_mutex_init(dev, &lp5860->lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spi_set_drvdata(spi, lp5860);
|
||||
|
||||
@@ -70,10 +74,6 @@ static int lp5860_probe(struct spi_device *spi)
|
||||
|
||||
static void lp5860_remove(struct spi_device *spi)
|
||||
{
|
||||
struct lp5860 *lp5860 = spi_get_drvdata(spi);
|
||||
|
||||
mutex_destroy(&lp5860->lock);
|
||||
|
||||
lp5860_device_remove(&spi->dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,8 @@ static int iterate_subleds(struct device *dev, struct pwm_mc_led *priv,
|
||||
}
|
||||
|
||||
subled[priv->mc_cdev.num_colors].color_index = color;
|
||||
fwnode_property_read_u32(fwnode, "default-intensity",
|
||||
&subled[priv->mc_cdev.num_colors].intensity);
|
||||
priv->mc_cdev.num_colors++;
|
||||
}
|
||||
|
||||
|
||||
@@ -129,6 +129,22 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
|
||||
trigger_data->link_speed == SPEED_10000)
|
||||
blink_on = true;
|
||||
|
||||
if (test_bit(TRIGGER_NETDEV_LINK_25000, &trigger_data->mode) &&
|
||||
trigger_data->link_speed == SPEED_25000)
|
||||
blink_on = true;
|
||||
|
||||
if (test_bit(TRIGGER_NETDEV_LINK_40000, &trigger_data->mode) &&
|
||||
trigger_data->link_speed == SPEED_40000)
|
||||
blink_on = true;
|
||||
|
||||
if (test_bit(TRIGGER_NETDEV_LINK_50000, &trigger_data->mode) &&
|
||||
trigger_data->link_speed == SPEED_50000)
|
||||
blink_on = true;
|
||||
|
||||
if (test_bit(TRIGGER_NETDEV_LINK_100000, &trigger_data->mode) &&
|
||||
trigger_data->link_speed == SPEED_100000)
|
||||
blink_on = true;
|
||||
|
||||
if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) &&
|
||||
trigger_data->duplex == DUPLEX_HALF)
|
||||
blink_on = true;
|
||||
@@ -342,6 +358,10 @@ static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
|
||||
case TRIGGER_NETDEV_LINK_2500:
|
||||
case TRIGGER_NETDEV_LINK_5000:
|
||||
case TRIGGER_NETDEV_LINK_10000:
|
||||
case TRIGGER_NETDEV_LINK_25000:
|
||||
case TRIGGER_NETDEV_LINK_40000:
|
||||
case TRIGGER_NETDEV_LINK_50000:
|
||||
case TRIGGER_NETDEV_LINK_100000:
|
||||
case TRIGGER_NETDEV_HALF_DUPLEX:
|
||||
case TRIGGER_NETDEV_FULL_DUPLEX:
|
||||
case TRIGGER_NETDEV_TX:
|
||||
@@ -378,6 +398,10 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
|
||||
case TRIGGER_NETDEV_LINK_2500:
|
||||
case TRIGGER_NETDEV_LINK_5000:
|
||||
case TRIGGER_NETDEV_LINK_10000:
|
||||
case TRIGGER_NETDEV_LINK_25000:
|
||||
case TRIGGER_NETDEV_LINK_40000:
|
||||
case TRIGGER_NETDEV_LINK_50000:
|
||||
case TRIGGER_NETDEV_LINK_100000:
|
||||
case TRIGGER_NETDEV_HALF_DUPLEX:
|
||||
case TRIGGER_NETDEV_FULL_DUPLEX:
|
||||
case TRIGGER_NETDEV_TX:
|
||||
@@ -401,7 +425,11 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
|
||||
test_bit(TRIGGER_NETDEV_LINK_1000, &mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_2500, &mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_5000, &mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_10000, &mode)))
|
||||
test_bit(TRIGGER_NETDEV_LINK_10000, &mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_25000, &mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_40000, &mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_50000, &mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_100000, &mode)))
|
||||
return -EINVAL;
|
||||
|
||||
cancel_delayed_work_sync(&trigger_data->work);
|
||||
@@ -438,6 +466,10 @@ DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000);
|
||||
DEFINE_NETDEV_TRIGGER(link_2500, TRIGGER_NETDEV_LINK_2500);
|
||||
DEFINE_NETDEV_TRIGGER(link_5000, TRIGGER_NETDEV_LINK_5000);
|
||||
DEFINE_NETDEV_TRIGGER(link_10000, TRIGGER_NETDEV_LINK_10000);
|
||||
DEFINE_NETDEV_TRIGGER(link_25000, TRIGGER_NETDEV_LINK_25000);
|
||||
DEFINE_NETDEV_TRIGGER(link_40000, TRIGGER_NETDEV_LINK_40000);
|
||||
DEFINE_NETDEV_TRIGGER(link_50000, TRIGGER_NETDEV_LINK_50000);
|
||||
DEFINE_NETDEV_TRIGGER(link_100000, TRIGGER_NETDEV_LINK_100000);
|
||||
DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX);
|
||||
DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX);
|
||||
DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
|
||||
@@ -526,6 +558,10 @@ static umode_t netdev_trig_link_speed_visible(struct kobject *kobj,
|
||||
CHECK_LINK_MODE_ATTR(2500);
|
||||
CHECK_LINK_MODE_ATTR(5000);
|
||||
CHECK_LINK_MODE_ATTR(10000);
|
||||
CHECK_LINK_MODE_ATTR(25000);
|
||||
CHECK_LINK_MODE_ATTR(40000);
|
||||
CHECK_LINK_MODE_ATTR(50000);
|
||||
CHECK_LINK_MODE_ATTR(100000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -538,6 +574,10 @@ static struct attribute *netdev_trig_link_speed_attrs[] = {
|
||||
&dev_attr_link_2500.attr,
|
||||
&dev_attr_link_5000.attr,
|
||||
&dev_attr_link_10000.attr,
|
||||
&dev_attr_link_25000.attr,
|
||||
&dev_attr_link_40000.attr,
|
||||
&dev_attr_link_50000.attr,
|
||||
&dev_attr_link_100000.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -673,6 +713,10 @@ static void netdev_trig_work(struct work_struct *work)
|
||||
test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_25000, &trigger_data->mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_40000, &trigger_data->mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_50000, &trigger_data->mode) ||
|
||||
test_bit(TRIGGER_NETDEV_LINK_100000, &trigger_data->mode) ||
|
||||
test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) ||
|
||||
test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode);
|
||||
interval = jiffies_to_msecs(
|
||||
|
||||
@@ -607,6 +607,10 @@ enum led_trigger_netdev_modes {
|
||||
TRIGGER_NETDEV_LINK_2500,
|
||||
TRIGGER_NETDEV_LINK_5000,
|
||||
TRIGGER_NETDEV_LINK_10000,
|
||||
TRIGGER_NETDEV_LINK_25000,
|
||||
TRIGGER_NETDEV_LINK_40000,
|
||||
TRIGGER_NETDEV_LINK_50000,
|
||||
TRIGGER_NETDEV_LINK_100000,
|
||||
TRIGGER_NETDEV_HALF_DUPLEX,
|
||||
TRIGGER_NETDEV_FULL_DUPLEX,
|
||||
TRIGGER_NETDEV_TX,
|
||||
@@ -676,8 +680,10 @@ typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state,
|
||||
struct gpio_led {
|
||||
const char *name;
|
||||
const char *default_trigger;
|
||||
#ifdef CONFIG_GPIOLIB_LEGACY
|
||||
unsigned gpio;
|
||||
unsigned active_low : 1;
|
||||
#endif
|
||||
unsigned retain_state_suspended : 1;
|
||||
unsigned panic_indicator : 1;
|
||||
unsigned default_state : 2;
|
||||
|
||||
Reference in New Issue
Block a user