Merge tag 'leds-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds
Pull LED updates from Pavel Machek: "Most significant here is the driver for Qualcomm LPG. Apparently it drives backlight on some boards, so it is quite important for some people" * tag 'leds-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds: leds: qcom-lpg: Require pattern to follow documentation leds: lp50xx: Remove duplicated error reporting in .remove() leds: qcom-lpg: add missing PWM dependency leds: ktd2692: Make aux-gpios optional dt-bindings: leds: convert ktd2692 bindings to yaml leds: ktd2692: Avoid duplicate error messages on probe deferral leds: is31fl32xx: Improve error reporting in .remove() leds: Move pwm-multicolor driver into rgb directory leds: Add PWM multicolor driver dt-bindings: leds: Add multicolor PWM LED bindings dt-bindings: leds: Optional multi-led unit address leds: regulator: Make probeable from device tree leds: regulator: Add dev helper variable dt-bindings: leds: Add regulator-led binding leds: pca9532: Make pca9532_destroy_devices() return void leds: Add pm8350c support to Qualcomm LPG driver dt-bindings: leds: Add pm8350c pmic support leds: Add driver for Qualcomm LPG dt-bindings: leds: Add Qualcomm Light Pulse Generator binding
This commit is contained in:
87
Documentation/devicetree/bindings/leds/kinetic,ktd2692.yaml
Normal file
87
Documentation/devicetree/bindings/leds/kinetic,ktd2692.yaml
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/leds/kinetic,ktd2692.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: KTD2692 Flash LED Driver from Kinetic Technologies
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Markuss Broks <markuss.broks@gmail.com>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
KTD2692 is the ideal power solution for high-power flash LEDs.
|
||||||
|
It uses ExpressWire single-wire programming for maximum flexibility.
|
||||||
|
|
||||||
|
The ExpressWire interface through CTRL pin can control LED on/off and
|
||||||
|
enable/disable the IC, Movie(max 1/3 of Flash current) / Flash mode current,
|
||||||
|
Flash timeout, LVP(low voltage protection).
|
||||||
|
|
||||||
|
Also, When the AUX pin is pulled high while CTRL pin is high,
|
||||||
|
LED current will be ramped up to the flash-mode current level.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: kinetic,ktd2692
|
||||||
|
|
||||||
|
ctrl-gpios:
|
||||||
|
maxItems: 1
|
||||||
|
description: Specifier of the GPIO connected to CTRL pin.
|
||||||
|
|
||||||
|
aux-gpios:
|
||||||
|
maxItems: 1
|
||||||
|
description: Specifier of the GPIO connected to CTRL pin.
|
||||||
|
|
||||||
|
vin-supply:
|
||||||
|
description: LED supply (2.7V to 5.5V).
|
||||||
|
|
||||||
|
led:
|
||||||
|
type: object
|
||||||
|
$ref: common.yaml#
|
||||||
|
description: Properties for the LED.
|
||||||
|
properties:
|
||||||
|
function: true
|
||||||
|
color: true
|
||||||
|
flash-max-timeout-us:
|
||||||
|
description: Flash LED maximum timeout.
|
||||||
|
|
||||||
|
led-max-microamp:
|
||||||
|
maximum: 300000
|
||||||
|
description: Minimum Threshold for Timer protection
|
||||||
|
is defined internally (Maximum 300mA).
|
||||||
|
|
||||||
|
flash-max-microamp:
|
||||||
|
maximum: 300000
|
||||||
|
description: Flash LED maximum current
|
||||||
|
Formula - I(uA) = 15000000 / Rset.
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- ctrl-gpios
|
||||||
|
- led
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
#include <dt-bindings/leds/common.h>
|
||||||
|
|
||||||
|
ktd2692 {
|
||||||
|
compatible = "kinetic,ktd2692";
|
||||||
|
ctrl-gpios = <&gpc0 1 0>;
|
||||||
|
aux-gpios = <&gpc0 2 0>;
|
||||||
|
vin-supply = <&vbat>;
|
||||||
|
|
||||||
|
led {
|
||||||
|
function = LED_FUNCTION_FLASH;
|
||||||
|
color = <LED_COLOR_ID_WHITE>;
|
||||||
|
flash-max-timeout-us = <250000>;
|
||||||
|
flash-max-microamp = <150000>;
|
||||||
|
led-max-microamp = <25000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
...
|
||||||
@@ -20,7 +20,7 @@ description: |
|
|||||||
within this documentation directory.
|
within this documentation directory.
|
||||||
|
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^multi-led@([0-9a-f])$":
|
"^multi-led(@[0-9a-f])?$":
|
||||||
type: object
|
type: object
|
||||||
description: Represents the LEDs that are to be grouped.
|
description: Represents the LEDs that are to be grouped.
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
* Kinetic Technologies - KTD2692 Flash LED Driver
|
|
||||||
|
|
||||||
KTD2692 is the ideal power solution for high-power flash LEDs.
|
|
||||||
It uses ExpressWire single-wire programming for maximum flexibility.
|
|
||||||
|
|
||||||
The ExpressWire interface through CTRL pin can control LED on/off and
|
|
||||||
enable/disable the IC, Movie(max 1/3 of Flash current) / Flash mode current,
|
|
||||||
Flash timeout, LVP(low voltage protection).
|
|
||||||
|
|
||||||
Also, When the AUX pin is pulled high while CTRL pin is high,
|
|
||||||
LED current will be ramped up to the flash-mode current level.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : Should be "kinetic,ktd2692".
|
|
||||||
- ctrl-gpios : Specifier of the GPIO connected to CTRL pin.
|
|
||||||
- aux-gpios : Specifier of the GPIO connected to AUX pin.
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
- vin-supply : "vin" LED supply (2.7V to 5.5V).
|
|
||||||
See Documentation/devicetree/bindings/regulator/regulator.txt
|
|
||||||
|
|
||||||
A discrete LED element connected to the device must be represented by a child
|
|
||||||
node - See Documentation/devicetree/bindings/leds/common.txt
|
|
||||||
|
|
||||||
Required properties for flash LED child nodes:
|
|
||||||
See Documentation/devicetree/bindings/leds/common.txt
|
|
||||||
- led-max-microamp : Minimum Threshold for Timer protection
|
|
||||||
is defined internally (Maximum 300mA).
|
|
||||||
- flash-max-microamp : Flash LED maximum current
|
|
||||||
Formula : I(mA) = 15000 / Rset.
|
|
||||||
- flash-max-timeout-us : Flash LED maximum timeout.
|
|
||||||
|
|
||||||
Optional properties for flash LED child nodes:
|
|
||||||
- label : See Documentation/devicetree/bindings/leds/common.txt
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
ktd2692 {
|
|
||||||
compatible = "kinetic,ktd2692";
|
|
||||||
ctrl-gpios = <&gpc0 1 0>;
|
|
||||||
aux-gpios = <&gpc0 2 0>;
|
|
||||||
vin-supply = <&vbat>;
|
|
||||||
|
|
||||||
flash-led {
|
|
||||||
label = "ktd2692-flash";
|
|
||||||
led-max-microamp = <300000>;
|
|
||||||
flash-max-microamp = <1500000>;
|
|
||||||
flash-max-timeout-us = <1835000>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/leds/leds-pwm-multicolor.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Multi-color LEDs connected to PWM
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Sven Schwermer <sven.schwermer@disruptive-technologies.com>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
This driver combines several monochrome PWM LEDs into one multi-color
|
||||||
|
LED using the multicolor LED class.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: pwm-leds-multicolor
|
||||||
|
|
||||||
|
multi-led:
|
||||||
|
type: object
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
"^led-[0-9a-z]+$":
|
||||||
|
type: object
|
||||||
|
$ref: common.yaml#
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
properties:
|
||||||
|
pwms:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
pwm-names: true
|
||||||
|
|
||||||
|
color: true
|
||||||
|
|
||||||
|
required:
|
||||||
|
- pwms
|
||||||
|
- color
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: leds-class-multicolor.yaml#
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/leds/common.h>
|
||||||
|
|
||||||
|
led-controller {
|
||||||
|
compatible = "pwm-leds-multicolor";
|
||||||
|
|
||||||
|
multi-led {
|
||||||
|
color = <LED_COLOR_ID_RGB>;
|
||||||
|
function = LED_FUNCTION_INDICATOR;
|
||||||
|
max-brightness = <65535>;
|
||||||
|
|
||||||
|
led-red {
|
||||||
|
pwms = <&pwm1 0 1000000>;
|
||||||
|
color = <LED_COLOR_ID_RED>;
|
||||||
|
};
|
||||||
|
|
||||||
|
led-green {
|
||||||
|
pwms = <&pwm2 0 1000000>;
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
};
|
||||||
|
|
||||||
|
led-blue {
|
||||||
|
pwms = <&pwm3 0 1000000>;
|
||||||
|
color = <LED_COLOR_ID_BLUE>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
...
|
||||||
174
Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
Normal file
174
Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/leds/leds-qcom-lpg.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Qualcomm Light Pulse Generator
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||||
|
|
||||||
|
description: >
|
||||||
|
The Qualcomm Light Pulse Generator consists of three different hardware blocks;
|
||||||
|
a ramp generator with lookup table, the light pulse generator and a three
|
||||||
|
channel current sink. These blocks are found in a wide range of Qualcomm PMICs.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- qcom,pm8150b-lpg
|
||||||
|
- qcom,pm8150l-lpg
|
||||||
|
- qcom,pm8350c-pwm
|
||||||
|
- qcom,pm8916-pwm
|
||||||
|
- qcom,pm8941-lpg
|
||||||
|
- qcom,pm8994-lpg
|
||||||
|
- qcom,pmc8180c-lpg
|
||||||
|
- qcom,pmi8994-lpg
|
||||||
|
- qcom,pmi8998-lpg
|
||||||
|
|
||||||
|
"#pwm-cells":
|
||||||
|
const: 2
|
||||||
|
|
||||||
|
"#address-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#size-cells":
|
||||||
|
const: 0
|
||||||
|
|
||||||
|
qcom,power-source:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
description:
|
||||||
|
power-source used to drive the output, as defined in the datasheet.
|
||||||
|
Should be specified if the TRILED block is present
|
||||||
|
enum: [0, 1, 3]
|
||||||
|
|
||||||
|
qcom,dtest:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32-matrix
|
||||||
|
description: >
|
||||||
|
A list of integer pairs, where each pair represent the dtest line the
|
||||||
|
particular channel should be connected to and the flags denoting how the
|
||||||
|
value should be outputed, as defined in the datasheet. The number of
|
||||||
|
pairs should be the same as the number of channels.
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
- description: dtest line to attach
|
||||||
|
- description: flags for the attachment
|
||||||
|
|
||||||
|
multi-led:
|
||||||
|
type: object
|
||||||
|
$ref: leds-class-multicolor.yaml#
|
||||||
|
properties:
|
||||||
|
"#address-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#size-cells":
|
||||||
|
const: 0
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
"^led@[0-9a-f]$":
|
||||||
|
type: object
|
||||||
|
$ref: common.yaml#
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
"^led@[0-9a-f]$":
|
||||||
|
type: object
|
||||||
|
$ref: common.yaml#
|
||||||
|
|
||||||
|
properties:
|
||||||
|
reg: true
|
||||||
|
|
||||||
|
required:
|
||||||
|
- reg
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/leds/common.h>
|
||||||
|
|
||||||
|
led-controller {
|
||||||
|
compatible = "qcom,pmi8994-lpg";
|
||||||
|
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
qcom,power-source = <1>;
|
||||||
|
|
||||||
|
qcom,dtest = <0 0>,
|
||||||
|
<0 0>,
|
||||||
|
<0 0>,
|
||||||
|
<4 1>;
|
||||||
|
|
||||||
|
led@1 {
|
||||||
|
reg = <1>;
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_INDICATOR;
|
||||||
|
function-enumerator = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
led@2 {
|
||||||
|
reg = <2>;
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_INDICATOR;
|
||||||
|
function-enumerator = <0>;
|
||||||
|
default-state = "on";
|
||||||
|
};
|
||||||
|
|
||||||
|
led@3 {
|
||||||
|
reg = <3>;
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_INDICATOR;
|
||||||
|
function-enumerator = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
led@4 {
|
||||||
|
reg = <4>;
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_INDICATOR;
|
||||||
|
function-enumerator = <3>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/leds/common.h>
|
||||||
|
|
||||||
|
led-controller {
|
||||||
|
compatible = "qcom,pmi8994-lpg";
|
||||||
|
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
qcom,power-source = <1>;
|
||||||
|
|
||||||
|
multi-led {
|
||||||
|
color = <LED_COLOR_ID_RGB>;
|
||||||
|
function = LED_FUNCTION_STATUS;
|
||||||
|
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
led@1 {
|
||||||
|
reg = <1>;
|
||||||
|
color = <LED_COLOR_ID_RED>;
|
||||||
|
};
|
||||||
|
|
||||||
|
led@2 {
|
||||||
|
reg = <2>;
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
};
|
||||||
|
|
||||||
|
led@3 {
|
||||||
|
reg = <3>;
|
||||||
|
color = <LED_COLOR_ID_BLUE>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
- |
|
||||||
|
pwm-controller {
|
||||||
|
compatible = "qcom,pm8916-pwm";
|
||||||
|
#pwm-cells = <2>;
|
||||||
|
};
|
||||||
|
...
|
||||||
55
Documentation/devicetree/bindings/leds/regulator-led.yaml
Normal file
55
Documentation/devicetree/bindings/leds/regulator-led.yaml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/leds/regulator-led.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Device Tree Bindings for Regulator LEDs
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Regulator LEDs are powered by a single regulator such that they can
|
||||||
|
be turned on or off by enabling or disabling the regulator. The available
|
||||||
|
brightness settings will be inferred from the available voltages on the
|
||||||
|
regulator, and any constraints on the voltage or current will need to be
|
||||||
|
specified on the regulator.
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: common.yaml#
|
||||||
|
|
||||||
|
properties:
|
||||||
|
$nodename:
|
||||||
|
pattern: '^led.*$'
|
||||||
|
|
||||||
|
compatible:
|
||||||
|
const: regulator-led
|
||||||
|
|
||||||
|
vled-supply:
|
||||||
|
description:
|
||||||
|
The regulator controlling the current to the LED.
|
||||||
|
|
||||||
|
function: true
|
||||||
|
color: true
|
||||||
|
linux,default-trigger: true
|
||||||
|
default-state: true
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- vled-supply
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/leds/common.h>
|
||||||
|
|
||||||
|
led-heartbeat {
|
||||||
|
compatible = "regulator-led";
|
||||||
|
vled-supply = <®ulator>;
|
||||||
|
function = LED_FUNCTION_STATUS;
|
||||||
|
color = <LED_COLOR_ID_BLUE>;
|
||||||
|
linux,default-trigger = "heartbeat";
|
||||||
|
};
|
||||||
|
...
|
||||||
78
Documentation/leds/leds-qcom-lpg.rst
Normal file
78
Documentation/leds/leds-qcom-lpg.rst
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
==============================
|
||||||
|
Kernel driver for Qualcomm LPG
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The Qualcomm LPG can be found in a variety of Qualcomm PMICs and consists of a
|
||||||
|
number of PWM channels, a programmable pattern lookup table and a RGB LED
|
||||||
|
current sink.
|
||||||
|
|
||||||
|
To facilitate the various use cases, the LPG channels can be exposed as
|
||||||
|
individual LEDs, grouped together as RGB LEDs or otherwise be accessed as PWM
|
||||||
|
channels. The output of each PWM channel is routed to other hardware
|
||||||
|
blocks, such as the RGB current sink, GPIO pins etc.
|
||||||
|
|
||||||
|
The each PWM channel can operate with a period between 27us and 384 seconds and
|
||||||
|
has a 9 bit resolution of the duty cycle.
|
||||||
|
|
||||||
|
In order to provide support for status notifications with the CPU subsystem in
|
||||||
|
deeper idle states the LPG provides pattern support. This consists of a shared
|
||||||
|
lookup table of brightness values and per channel properties to select the
|
||||||
|
range within the table to use, the rate and if the pattern should repeat.
|
||||||
|
|
||||||
|
The pattern for a channel can be programmed using the "pattern" trigger, using
|
||||||
|
the hw_pattern attribute.
|
||||||
|
|
||||||
|
/sys/class/leds/<led>/hw_pattern
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
Specify a hardware pattern for a Qualcomm LPG LED.
|
||||||
|
|
||||||
|
The pattern is a series of brightness and hold-time pairs, with the hold-time
|
||||||
|
expressed in milliseconds. The hold time is a property of the pattern and must
|
||||||
|
therefor be identical for each element in the pattern (except for the pauses
|
||||||
|
described below). As the LPG hardware is not able to perform the linear
|
||||||
|
transitions expected by the leds-trigger-pattern format, each entry in the
|
||||||
|
pattern must be followed a zero-length entry of the same brightness.
|
||||||
|
|
||||||
|
Simple pattern::
|
||||||
|
|
||||||
|
"255 500 255 0 0 500 0 0"
|
||||||
|
|
||||||
|
^
|
||||||
|
|
|
||||||
|
255 +----+ +----+
|
||||||
|
| | | | ...
|
||||||
|
0 | +----+ +----
|
||||||
|
+---------------------->
|
||||||
|
0 5 10 15 time (100ms)
|
||||||
|
|
||||||
|
The LPG supports specifying a longer hold-time for the first and last element
|
||||||
|
in the pattern, the so called "low pause" and "high pause".
|
||||||
|
|
||||||
|
Low-pause pattern::
|
||||||
|
|
||||||
|
"255 1000 255 0 0 500 0 0 255 500 255 0 0 500 0 0"
|
||||||
|
|
||||||
|
^
|
||||||
|
|
|
||||||
|
255 +--------+ +----+ +----+ +--------+
|
||||||
|
| | | | | | | | ...
|
||||||
|
0 | +----+ +----+ +----+ +----
|
||||||
|
+----------------------------->
|
||||||
|
0 5 10 15 20 25 time (100ms)
|
||||||
|
|
||||||
|
Similarily, the last entry can be stretched by using a higher hold-time on the
|
||||||
|
last entry.
|
||||||
|
|
||||||
|
In order to save space in the shared lookup table the LPG supports "ping-pong"
|
||||||
|
mode, in which case each run through the pattern is performed by first running
|
||||||
|
the pattern forward, then backwards. This mode is automatically used by the
|
||||||
|
driver when the given pattern is a palindrome. In this case the "high pause"
|
||||||
|
denotes the wait time before the pattern is run in reverse and as such the
|
||||||
|
specified hold-time of the middle item in the pattern is allowed to have a
|
||||||
|
different hold-time.
|
||||||
@@ -869,6 +869,9 @@ source "drivers/leds/blink/Kconfig"
|
|||||||
comment "Flash and Torch LED drivers"
|
comment "Flash and Torch LED drivers"
|
||||||
source "drivers/leds/flash/Kconfig"
|
source "drivers/leds/flash/Kconfig"
|
||||||
|
|
||||||
|
comment "RGB LED drivers"
|
||||||
|
source "drivers/leds/rgb/Kconfig"
|
||||||
|
|
||||||
comment "LED Triggers"
|
comment "LED Triggers"
|
||||||
source "drivers/leds/trigger/Kconfig"
|
source "drivers/leds/trigger/Kconfig"
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,9 @@ obj-$(CONFIG_LEDS_USER) += uleds.o
|
|||||||
# Flash and Torch LED Drivers
|
# Flash and Torch LED Drivers
|
||||||
obj-$(CONFIG_LEDS_CLASS_FLASH) += flash/
|
obj-$(CONFIG_LEDS_CLASS_FLASH) += flash/
|
||||||
|
|
||||||
|
# RGB LED Drivers
|
||||||
|
obj-$(CONFIG_LEDS_CLASS_MULTICOLOR) += rgb/
|
||||||
|
|
||||||
# LED Triggers
|
# LED Triggers
|
||||||
obj-$(CONFIG_LEDS_TRIGGERS) += trigger/
|
obj-$(CONFIG_LEDS_TRIGGERS) += trigger/
|
||||||
|
|
||||||
|
|||||||
@@ -279,17 +279,12 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev,
|
|||||||
|
|
||||||
led->ctrl_gpio = devm_gpiod_get(dev, "ctrl", GPIOD_ASIS);
|
led->ctrl_gpio = devm_gpiod_get(dev, "ctrl", GPIOD_ASIS);
|
||||||
ret = PTR_ERR_OR_ZERO(led->ctrl_gpio);
|
ret = PTR_ERR_OR_ZERO(led->ctrl_gpio);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "cannot get ctrl-gpios %d\n", ret);
|
return dev_err_probe(dev, ret, "cannot get ctrl-gpios\n");
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
led->aux_gpio = devm_gpiod_get(dev, "aux", GPIOD_ASIS);
|
led->aux_gpio = devm_gpiod_get_optional(dev, "aux", GPIOD_ASIS);
|
||||||
ret = PTR_ERR_OR_ZERO(led->aux_gpio);
|
if (IS_ERR(led->aux_gpio))
|
||||||
if (ret) {
|
return dev_err_probe(dev, PTR_ERR(led->aux_gpio), "cannot get aux-gpios\n");
|
||||||
dev_err(dev, "cannot get aux-gpios %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
led->regulator = devm_regulator_get(dev, "vin");
|
led->regulator = devm_regulator_get(dev, "vin");
|
||||||
if (IS_ERR(led->regulator))
|
if (IS_ERR(led->regulator))
|
||||||
|
|||||||
@@ -460,8 +460,14 @@ static int is31fl32xx_probe(struct i2c_client *client,
|
|||||||
static int is31fl32xx_remove(struct i2c_client *client)
|
static int is31fl32xx_remove(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct is31fl32xx_priv *priv = i2c_get_clientdata(client);
|
struct is31fl32xx_priv *priv = i2c_get_clientdata(client);
|
||||||
|
int ret;
|
||||||
|
|
||||||
return is31fl32xx_reset_regs(priv);
|
ret = is31fl32xx_reset_regs(priv);
|
||||||
|
if (ret)
|
||||||
|
dev_err(&client->dev, "Failed to reset registers on removal (%pe)\n",
|
||||||
|
ERR_PTR(ret));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -569,10 +569,8 @@ static int lp50xx_remove(struct i2c_client *client)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = lp50xx_enable_disable(led, 0);
|
ret = lp50xx_enable_disable(led, 0);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(led->dev, "Failed to disable chip\n");
|
dev_err(led->dev, "Failed to disable chip\n");
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (led->regulator) {
|
if (led->regulator) {
|
||||||
ret = regulator_disable(led->regulator);
|
ret = regulator_disable(led->regulator);
|
||||||
|
|||||||
@@ -318,13 +318,10 @@ static int pca9532_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_LEDS_PCA9532_GPIO */
|
#endif /* CONFIG_LEDS_PCA9532_GPIO */
|
||||||
|
|
||||||
static int pca9532_destroy_devices(struct pca9532_data *data, int n_devs)
|
static void pca9532_destroy_devices(struct pca9532_data *data, int n_devs)
|
||||||
{
|
{
|
||||||
int i = n_devs;
|
int i = n_devs;
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
switch (data->leds[i].type) {
|
switch (data->leds[i].type) {
|
||||||
case PCA9532_TYPE_NONE:
|
case PCA9532_TYPE_NONE:
|
||||||
@@ -346,8 +343,6 @@ static int pca9532_destroy_devices(struct pca9532_data *data, int n_devs)
|
|||||||
if (data->gpio.parent)
|
if (data->gpio.parent)
|
||||||
gpiochip_remove(&data->gpio);
|
gpiochip_remove(&data->gpio);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pca9532_configure(struct i2c_client *client,
|
static int pca9532_configure(struct i2c_client *client,
|
||||||
@@ -555,7 +550,9 @@ static int pca9532_remove(struct i2c_client *client)
|
|||||||
{
|
{
|
||||||
struct pca9532_data *data = i2c_get_clientdata(client);
|
struct pca9532_data *data = i2c_get_clientdata(client);
|
||||||
|
|
||||||
return pca9532_destroy_devices(data, data->chip_info->num_leds);
|
pca9532_destroy_devices(data, data->chip_info->num_leds);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_i2c_driver(pca9532_driver);
|
module_i2c_driver(pca9532_driver);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/mod_devicetable.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
@@ -123,34 +124,37 @@ static int regulator_led_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct led_regulator_platform_data *pdata =
|
struct led_regulator_platform_data *pdata =
|
||||||
dev_get_platdata(&pdev->dev);
|
dev_get_platdata(&pdev->dev);
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct led_init_data init_data = {};
|
||||||
struct regulator_led *led;
|
struct regulator_led *led;
|
||||||
struct regulator *vcc;
|
struct regulator *vcc;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (pdata == NULL) {
|
vcc = devm_regulator_get_exclusive(dev, "vled");
|
||||||
dev_err(&pdev->dev, "no platform data\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
vcc = devm_regulator_get_exclusive(&pdev->dev, "vled");
|
|
||||||
if (IS_ERR(vcc)) {
|
if (IS_ERR(vcc)) {
|
||||||
dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name);
|
dev_err(dev, "Cannot get vcc\n");
|
||||||
return PTR_ERR(vcc);
|
return PTR_ERR(vcc);
|
||||||
}
|
}
|
||||||
|
|
||||||
led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
|
led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
|
||||||
if (led == NULL)
|
if (led == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
init_data.fwnode = dev->fwnode;
|
||||||
|
|
||||||
led->cdev.max_brightness = led_regulator_get_max_brightness(vcc);
|
led->cdev.max_brightness = led_regulator_get_max_brightness(vcc);
|
||||||
if (pdata->brightness > led->cdev.max_brightness) {
|
/* Legacy platform data label assignment */
|
||||||
dev_err(&pdev->dev, "Invalid default brightness %d\n",
|
if (pdata) {
|
||||||
|
if (pdata->brightness > led->cdev.max_brightness) {
|
||||||
|
dev_err(dev, "Invalid default brightness %d\n",
|
||||||
pdata->brightness);
|
pdata->brightness);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
led->cdev.brightness = pdata->brightness;
|
||||||
|
init_data.default_label = pdata->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
led->cdev.brightness_set_blocking = regulator_led_brightness_set;
|
led->cdev.brightness_set_blocking = regulator_led_brightness_set;
|
||||||
led->cdev.name = pdata->name;
|
|
||||||
led->cdev.flags |= LED_CORE_SUSPENDRESUME;
|
led->cdev.flags |= LED_CORE_SUSPENDRESUME;
|
||||||
led->vcc = vcc;
|
led->vcc = vcc;
|
||||||
|
|
||||||
@@ -162,16 +166,10 @@ static int regulator_led_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
platform_set_drvdata(pdev, led);
|
platform_set_drvdata(pdev, led);
|
||||||
|
|
||||||
ret = led_classdev_register(&pdev->dev, &led->cdev);
|
ret = led_classdev_register_ext(dev, &led->cdev, &init_data);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* to expose the default value to userspace */
|
|
||||||
led->cdev.brightness = pdata->brightness;
|
|
||||||
|
|
||||||
/* Set the default led status */
|
|
||||||
regulator_led_brightness_set(&led->cdev, led->cdev.brightness);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,10 +182,17 @@ static int regulator_led_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id regulator_led_of_match[] = {
|
||||||
|
{ .compatible = "regulator-led", },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, regulator_led_of_match);
|
||||||
|
|
||||||
static struct platform_driver regulator_led_driver = {
|
static struct platform_driver regulator_led_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "leds-regulator",
|
.name = "leds-regulator",
|
||||||
},
|
.of_match_table = regulator_led_of_match,
|
||||||
|
},
|
||||||
.probe = regulator_led_probe,
|
.probe = regulator_led_probe,
|
||||||
.remove = regulator_led_remove,
|
.remove = regulator_led_remove,
|
||||||
};
|
};
|
||||||
|
|||||||
29
drivers/leds/rgb/Kconfig
Normal file
29
drivers/leds/rgb/Kconfig
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
if LEDS_CLASS_MULTICOLOR
|
||||||
|
|
||||||
|
config LEDS_PWM_MULTICOLOR
|
||||||
|
tristate "PWM driven multi-color LED Support"
|
||||||
|
depends on PWM
|
||||||
|
help
|
||||||
|
This option enables support for PWM driven monochrome LEDs that are
|
||||||
|
grouped into multicolor LEDs.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the module
|
||||||
|
will be called leds-pwm-multicolor.
|
||||||
|
|
||||||
|
config LEDS_QCOM_LPG
|
||||||
|
tristate "LED support for Qualcomm LPG"
|
||||||
|
depends on OF
|
||||||
|
depends on PWM
|
||||||
|
depends on SPMI
|
||||||
|
help
|
||||||
|
This option enables support for the Light Pulse Generator found in a
|
||||||
|
wide variety of Qualcomm PMICs. The LPG consists of a number of PWM
|
||||||
|
channels and typically a shared pattern lookup table and a current
|
||||||
|
sink, intended to drive RGB LEDs. Each channel can either be used as
|
||||||
|
a LED, grouped to represent a RGB LED or exposed as PWM channels.
|
||||||
|
|
||||||
|
If compiled as a module, the module will be named leds-qcom-lpg.
|
||||||
|
|
||||||
|
endif # LEDS_CLASS_MULTICOLOR
|
||||||
4
drivers/leds/rgb/Makefile
Normal file
4
drivers/leds/rgb/Makefile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
obj-$(CONFIG_LEDS_PWM_MULTICOLOR) += leds-pwm-multicolor.o
|
||||||
|
obj-$(CONFIG_LEDS_QCOM_LPG) += leds-qcom-lpg.o
|
||||||
186
drivers/leds/rgb/leds-pwm-multicolor.c
Normal file
186
drivers/leds/rgb/leds-pwm-multicolor.c
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* PWM-based multi-color LED control
|
||||||
|
*
|
||||||
|
* Copyright 2022 Sven Schwermer <sven.schwermer@disruptive-technologies.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/led-class-multicolor.h>
|
||||||
|
#include <linux/leds.h>
|
||||||
|
#include <linux/mod_devicetable.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/property.h>
|
||||||
|
#include <linux/pwm.h>
|
||||||
|
|
||||||
|
struct pwm_led {
|
||||||
|
struct pwm_device *pwm;
|
||||||
|
struct pwm_state state;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pwm_mc_led {
|
||||||
|
struct led_classdev_mc mc_cdev;
|
||||||
|
struct mutex lock;
|
||||||
|
struct pwm_led leds[];
|
||||||
|
};
|
||||||
|
|
||||||
|
static int led_pwm_mc_set(struct led_classdev *cdev,
|
||||||
|
enum led_brightness brightness)
|
||||||
|
{
|
||||||
|
struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
|
||||||
|
struct pwm_mc_led *priv = container_of(mc_cdev, struct pwm_mc_led, mc_cdev);
|
||||||
|
unsigned long long duty;
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
led_mc_calc_color_components(mc_cdev, brightness);
|
||||||
|
|
||||||
|
mutex_lock(&priv->lock);
|
||||||
|
|
||||||
|
for (i = 0; i < mc_cdev->num_colors; i++) {
|
||||||
|
duty = priv->leds[i].state.period;
|
||||||
|
duty *= mc_cdev->subled_info[i].brightness;
|
||||||
|
do_div(duty, cdev->max_brightness);
|
||||||
|
|
||||||
|
priv->leds[i].state.duty_cycle = duty;
|
||||||
|
priv->leds[i].state.enabled = duty > 0;
|
||||||
|
ret = pwm_apply_state(priv->leds[i].pwm,
|
||||||
|
&priv->leds[i].state);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&priv->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iterate_subleds(struct device *dev, struct pwm_mc_led *priv,
|
||||||
|
struct fwnode_handle *mcnode)
|
||||||
|
{
|
||||||
|
struct mc_subled *subled = priv->mc_cdev.subled_info;
|
||||||
|
struct fwnode_handle *fwnode;
|
||||||
|
struct pwm_led *pwmled;
|
||||||
|
u32 color;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* iterate over the nodes inside the multi-led node */
|
||||||
|
fwnode_for_each_child_node(mcnode, fwnode) {
|
||||||
|
pwmled = &priv->leds[priv->mc_cdev.num_colors];
|
||||||
|
pwmled->pwm = devm_fwnode_pwm_get(dev, fwnode, NULL);
|
||||||
|
if (IS_ERR(pwmled->pwm)) {
|
||||||
|
ret = PTR_ERR(pwmled->pwm);
|
||||||
|
dev_err(dev, "unable to request PWM: %d\n", ret);
|
||||||
|
goto release_fwnode;
|
||||||
|
}
|
||||||
|
pwm_init_state(pwmled->pwm, &pwmled->state);
|
||||||
|
|
||||||
|
ret = fwnode_property_read_u32(fwnode, "color", &color);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "cannot read color: %d\n", ret);
|
||||||
|
goto release_fwnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
subled[priv->mc_cdev.num_colors].color_index = color;
|
||||||
|
priv->mc_cdev.num_colors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
release_fwnode:
|
||||||
|
fwnode_handle_put(fwnode);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int led_pwm_mc_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct fwnode_handle *mcnode, *fwnode;
|
||||||
|
struct led_init_data init_data = {};
|
||||||
|
struct led_classdev *cdev;
|
||||||
|
struct mc_subled *subled;
|
||||||
|
struct pwm_mc_led *priv;
|
||||||
|
int count = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
mcnode = device_get_named_child_node(&pdev->dev, "multi-led");
|
||||||
|
if (!mcnode)
|
||||||
|
return dev_err_probe(&pdev->dev, -ENODEV,
|
||||||
|
"expected multi-led node\n");
|
||||||
|
|
||||||
|
/* count the nodes inside the multi-led node */
|
||||||
|
fwnode_for_each_child_node(mcnode, fwnode)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
priv = devm_kzalloc(&pdev->dev, struct_size(priv, leds, count),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!priv) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto release_mcnode;
|
||||||
|
}
|
||||||
|
mutex_init(&priv->lock);
|
||||||
|
|
||||||
|
subled = devm_kcalloc(&pdev->dev, count, sizeof(*subled), GFP_KERNEL);
|
||||||
|
if (!subled) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto release_mcnode;
|
||||||
|
}
|
||||||
|
priv->mc_cdev.subled_info = subled;
|
||||||
|
|
||||||
|
/* init the multicolor's LED class device */
|
||||||
|
cdev = &priv->mc_cdev.led_cdev;
|
||||||
|
fwnode_property_read_u32(mcnode, "max-brightness",
|
||||||
|
&cdev->max_brightness);
|
||||||
|
cdev->flags = LED_CORE_SUSPENDRESUME;
|
||||||
|
cdev->brightness_set_blocking = led_pwm_mc_set;
|
||||||
|
|
||||||
|
ret = iterate_subleds(&pdev->dev, priv, mcnode);
|
||||||
|
if (ret)
|
||||||
|
goto release_mcnode;
|
||||||
|
|
||||||
|
init_data.fwnode = mcnode;
|
||||||
|
ret = devm_led_classdev_multicolor_register_ext(&pdev->dev,
|
||||||
|
&priv->mc_cdev,
|
||||||
|
&init_data);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"failed to register multicolor PWM led for %s: %d\n",
|
||||||
|
cdev->name, ret);
|
||||||
|
goto release_mcnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = led_pwm_mc_set(cdev, cdev->brightness);
|
||||||
|
if (ret)
|
||||||
|
return dev_err_probe(&pdev->dev, ret,
|
||||||
|
"failed to set led PWM value for %s: %d",
|
||||||
|
cdev->name, ret);
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, priv);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
release_mcnode:
|
||||||
|
fwnode_handle_put(mcnode);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id of_pwm_leds_mc_match[] = {
|
||||||
|
{ .compatible = "pwm-leds-multicolor", },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, of_pwm_leds_mc_match);
|
||||||
|
|
||||||
|
static struct platform_driver led_pwm_mc_driver = {
|
||||||
|
.probe = led_pwm_mc_probe,
|
||||||
|
.driver = {
|
||||||
|
.name = "leds_pwm_multicolor",
|
||||||
|
.of_match_table = of_pwm_leds_mc_match,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module_platform_driver(led_pwm_mc_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Sven Schwermer <sven.schwermer@disruptive-technologies.com>");
|
||||||
|
MODULE_DESCRIPTION("multi-color PWM LED driver");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
|
MODULE_ALIAS("platform:leds-pwm-multicolor");
|
||||||
1451
drivers/leds/rgb/leds-qcom-lpg.c
Normal file
1451
drivers/leds/rgb/leds-qcom-lpg.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user