forked from Minki/linux
LED updates for 5.3-rc1
-----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQUwxxKyE5l/npt8ARiEGxRG/Sl2wUCXRozKAAKCRBiEGxRG/Sl 25okAP9I0Rmscpqjb/+GEeXH4EmL3moGzc9o/BzHRqfeO4wqYAEA+8f7L20xHe8g tvEGfP7mN/oBmcAfqgH5K9F4eJsBRAw= =NkCn -----END PGP SIGNATURE----- Merge tag 'leds-for-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds Pull LED updates from Jacek Anaszewski: - Add a new LED common module for ti-lmu driver family - Modify MFD ti-lmu bindings - add ti,brightness-resolution - add the ramp up/down property - Add regulator support for LM36274 driver to lm363x-regulator.c - New LED class drivers with DT bindings: - leds-spi-byte - leds-lm36274 - leds-lm3697 (move the support from MFD to LED subsystem) - Simplify getting the I2C adapter of a client: - leds-tca6507 - leds-pca955x - Convert LED documentation to ReST * tag 'leds-for-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds: dt: leds-lm36274.txt: fix a broken reference to ti-lmu.txt docs: leds: convert to ReST leds: leds-tca6507: simplify getting the adapter of a client leds: leds-pca955x: simplify getting the adapter of a client leds: lm36274: Introduce the TI LM36274 LED driver dt-bindings: leds: Add LED bindings for the LM36274 regulator: lm363x: Add support for LM36274 mfd: ti-lmu: Add LM36274 support to the ti-lmu dt-bindings: mfd: Add lm36274 bindings to ti-lmu leds: max77650: Remove set but not used variable 'parent' leds: avoid flush_work in atomic context leds: lm3697: Introduce the lm3697 driver mfd: ti-lmu: Remove support for LM3697 dt-bindings: ti-lmu: Modify dt bindings for the LM3697 leds: TI LMU: Add common code for TI LMU devices leds: spi-byte: add single byte SPI LED driver dt-bindings: leds: Add binding for spi-byte LED. dt-bindings: mfd: LMU: Add ti,brightness-resolution dt-bindings: mfd: LMU: Add the ramp up/down property
This commit is contained in:
commit
8a3367cc80
85
Documentation/devicetree/bindings/leds/leds-lm36274.txt
Normal file
85
Documentation/devicetree/bindings/leds/leds-lm36274.txt
Normal file
@ -0,0 +1,85 @@
|
||||
* Texas Instruments LM36274 4-Channel LCD Backlight Driver w/Integrated Bias
|
||||
|
||||
The LM36274 is an integrated four-channel WLED driver and LCD bias supply.
|
||||
The backlight boost provides the power to bias four parallel LED strings with
|
||||
up to 29V total output voltage. The 11-bit LED current is programmable via
|
||||
the I2C bus and/or controlled via a logic level PWM input from 60 uA to 30 mA.
|
||||
|
||||
Parent device properties are documented in
|
||||
Documentation/devicetree/bindings/mfd/ti-lmu.txt
|
||||
|
||||
Regulator properties are documented in
|
||||
Documentation/devicetree/bindings/regulator/lm363x-regulator.txt
|
||||
|
||||
Required backlight properties:
|
||||
- compatible:
|
||||
"ti,lm36274-backlight"
|
||||
- reg : 0
|
||||
- #address-cells : 1
|
||||
- #size-cells : 0
|
||||
- led-sources : Indicates which LED strings will be enabled.
|
||||
Values from 0-3, sources is 0 based so strings will be
|
||||
source value + 1.
|
||||
|
||||
Optional backlight properties:
|
||||
- label : see Documentation/devicetree/bindings/leds/common.txt
|
||||
- linux,default-trigger :
|
||||
see Documentation/devicetree/bindings/leds/common.txt
|
||||
|
||||
Example:
|
||||
|
||||
HVLED string 1 and 3 are controlled by control bank A and HVLED 2 string is
|
||||
controlled by control bank B.
|
||||
|
||||
lm36274@11 {
|
||||
compatible = "ti,lm36274";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x11>;
|
||||
|
||||
enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
regulators {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "ti,lm363x-regulator";
|
||||
|
||||
enable-gpios = <&pioC 0 GPIO_ACTIVE_HIGH>,
|
||||
<&pioC 1 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
vboost {
|
||||
regulator-name = "lcd_boost";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <7150000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vpos {
|
||||
regulator-name = "lcd_vpos";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <6500000>;
|
||||
};
|
||||
|
||||
vneg {
|
||||
regulator-name = "lcd_vneg";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <6500000>;
|
||||
};
|
||||
};
|
||||
|
||||
backlight {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "ti,lm36274-backlight";
|
||||
|
||||
led@0 {
|
||||
reg = <0>;
|
||||
led-sources = <0 2>;
|
||||
label = "white:backlight_cluster";
|
||||
linux,default-trigger = "backlight";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
For more product information please see the link below:
|
||||
http://www.ti.com/lit/ds/symlink/lm36274.pdf
|
73
Documentation/devicetree/bindings/leds/leds-lm3697.txt
Normal file
73
Documentation/devicetree/bindings/leds/leds-lm3697.txt
Normal file
@ -0,0 +1,73 @@
|
||||
* Texas Instruments - LM3697 Highly Efficient White LED Driver
|
||||
|
||||
The LM3697 11-bit LED driver provides high-
|
||||
performance backlight dimming for 1, 2, or 3 series
|
||||
LED strings while delivering up to 90% efficiency.
|
||||
|
||||
This device is suitable for display and keypad lighting
|
||||
|
||||
Required properties:
|
||||
- compatible:
|
||||
"ti,lm3697"
|
||||
- reg : I2C slave address
|
||||
- #address-cells : 1
|
||||
- #size-cells : 0
|
||||
|
||||
Optional properties:
|
||||
- enable-gpios : GPIO pin to enable/disable the device
|
||||
- vled-supply : LED supply
|
||||
|
||||
Required child properties:
|
||||
- reg : 0 - LED is Controlled by bank A
|
||||
1 - LED is Controlled by bank B
|
||||
- led-sources : Indicates which HVLED string is associated to which
|
||||
control bank. This is a zero based property so
|
||||
HVLED1 = 0, HVLED2 = 1, HVLED3 = 2.
|
||||
Additional information is contained
|
||||
in Documentation/devicetree/bindings/leds/common.txt
|
||||
|
||||
Optional child properties:
|
||||
- ti,brightness-resolution - see Documentation/devicetree/bindings/mfd/ti-lmu.txt
|
||||
- ramp-up-us: see Documentation/devicetree/bindings/mfd/ti-lmu.txt
|
||||
- ramp-down-us: see Documentation/devicetree/bindings/mfd/ti-lmu.txt
|
||||
- label : see Documentation/devicetree/bindings/leds/common.txt
|
||||
- linux,default-trigger :
|
||||
see Documentation/devicetree/bindings/leds/common.txt
|
||||
|
||||
Example:
|
||||
|
||||
HVLED string 1 and 3 are controlled by control bank A and HVLED 2 string is
|
||||
controlled by control bank B.
|
||||
|
||||
led-controller@36 {
|
||||
compatible = "ti,lm3697";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x36>;
|
||||
|
||||
enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
|
||||
vled-supply = <&vbatt>;
|
||||
|
||||
led@0 {
|
||||
reg = <0>;
|
||||
led-sources = <0 2>;
|
||||
ti,brightness-resolution = <2047>;
|
||||
ramp-up-us = <5000>;
|
||||
ramp-down-us = <1000>;
|
||||
label = "white:first_backlight_cluster";
|
||||
linux,default-trigger = "backlight";
|
||||
};
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
led-sources = <1>;
|
||||
ti,brightness-resolution = <255>;
|
||||
ramp-up-us = <500>;
|
||||
ramp-down-us = <1000>;
|
||||
label = "white:second_backlight_cluster";
|
||||
linux,default-trigger = "backlight";
|
||||
};
|
||||
}
|
||||
|
||||
For more product information please see the link below:
|
||||
http://www.ti.com/lit/ds/symlink/lm3697.pdf
|
44
Documentation/devicetree/bindings/leds/leds-spi-byte.txt
Normal file
44
Documentation/devicetree/bindings/leds/leds-spi-byte.txt
Normal file
@ -0,0 +1,44 @@
|
||||
* Single Byte SPI LED Device Driver.
|
||||
|
||||
The driver can be used for controllers with a very simple SPI protocol:
|
||||
- one LED is controlled by a single byte on MOSI
|
||||
- the value of the byte gives the brightness between two values (lowest to
|
||||
highest)
|
||||
- no return value is necessary (no MISO signal)
|
||||
|
||||
The value for lowest and highest brightness is dependent on the device and
|
||||
therefore on the compatible string.
|
||||
|
||||
Depending on the compatible string some special functions (like hardware
|
||||
accelerated blinking) might can be supported too.
|
||||
|
||||
The driver currently only supports one LED. The properties of the LED are
|
||||
configured in a sub-node in the device node.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be one of
|
||||
* "ubnt,acb-spi-led" microcontroller (SONiX 8F26E611LA) based device
|
||||
used for example in Ubiquiti airCube ISP
|
||||
|
||||
Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt
|
||||
apply.
|
||||
|
||||
LED sub-node properties:
|
||||
- label:
|
||||
see Documentation/devicetree/bindings/leds/common.txt
|
||||
- default-state:
|
||||
see Documentation/devicetree/bindings/leds/common.txt
|
||||
Only "on" and "off" are supported.
|
||||
|
||||
Example:
|
||||
|
||||
led-controller@0 {
|
||||
compatible = "ubnt,acb-spi-led";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <100000>;
|
||||
|
||||
led {
|
||||
label = "white:status";
|
||||
default-state = "on";
|
||||
};
|
||||
};
|
@ -8,7 +8,7 @@ TI LMU driver supports lighting devices below.
|
||||
LM3632 Backlight and regulator
|
||||
LM3633 Backlight, LED and fault monitor
|
||||
LM3695 Backlight
|
||||
LM3697 Backlight and fault monitor
|
||||
LM36274 Backlight and regulator
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be one of:
|
||||
@ -16,15 +16,32 @@ Required properties:
|
||||
"ti,lm3632"
|
||||
"ti,lm3633"
|
||||
"ti,lm3695"
|
||||
"ti,lm3697"
|
||||
"ti,lm36274"
|
||||
- reg: I2C slave address.
|
||||
0x11 for LM3632
|
||||
0x29 for LM3631
|
||||
0x36 for LM3633, LM3697
|
||||
0x36 for LM3633
|
||||
0x63 for LM3695
|
||||
0x11 for LM36274
|
||||
|
||||
Optional property:
|
||||
Optional properties:
|
||||
- enable-gpios: A GPIO specifier for hardware enable pin.
|
||||
- ramp-up-us: Current ramping from one brightness level to
|
||||
the a higher brightness level.
|
||||
Range from 2048 us - 117.44 s
|
||||
- ramp-down-us: Current ramping from one brightness level to
|
||||
the a lower brightness level.
|
||||
Range from 2048 us - 117.44 s
|
||||
- ti,brightness-resolution - This determines whether to use 8 bit brightness
|
||||
mode or 11 bit brightness mode. If this value is
|
||||
not set the device is defaulted to the preferred
|
||||
8bit brightness mode per 7.3.4.1 of the data
|
||||
sheet. This setting can either be in the parent
|
||||
node or as part of the LED child nodes. This
|
||||
is determined by the part itself if the strings
|
||||
have a common brightness register or individual
|
||||
brightness registers.
|
||||
The values are 255 (8bit) or 2047 (11bit).
|
||||
|
||||
Required node:
|
||||
- backlight: All LMU devices have backlight child nodes.
|
||||
@ -35,14 +52,15 @@ Optional nodes:
|
||||
Required properties:
|
||||
- compatible: Should be one of:
|
||||
"ti,lm3633-fault-monitor"
|
||||
"ti,lm3697-fault-monitor"
|
||||
- leds: LED properties for LM3633. Please refer to [2].
|
||||
LED properties for LM36274. Please refer to [4].
|
||||
- regulators: Regulator properties for LM3631 and LM3632.
|
||||
Please refer to [3].
|
||||
|
||||
[1] ../leds/backlight/ti-lmu-backlight.txt
|
||||
[2] ../leds/leds-lm3633.txt
|
||||
[3] ../regulator/lm363x-regulator.txt
|
||||
[4] ../leds/leds-lm36274.txt
|
||||
|
||||
lm3631@29 {
|
||||
compatible = "ti,lm3631";
|
||||
@ -90,7 +108,7 @@ lm3631@29 {
|
||||
|
||||
lcd_bl {
|
||||
led-sources = <0 1>;
|
||||
ramp-up-msec = <300>;
|
||||
ramp-up-us = <300000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -152,15 +170,15 @@ lm3633@36 {
|
||||
main {
|
||||
label = "main_lcd";
|
||||
led-sources = <1 2>;
|
||||
ramp-up-msec = <500>;
|
||||
ramp-down-msec = <500>;
|
||||
ramp-up-us = <500000>;
|
||||
ramp-down-us = <500000>;
|
||||
};
|
||||
|
||||
front {
|
||||
label = "front_lcd";
|
||||
led-sources = <0>;
|
||||
ramp-up-msec = <1000>;
|
||||
ramp-down-msec = <0>;
|
||||
ramp-up-us = <1000000>;
|
||||
ramp-down-us = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -201,23 +219,51 @@ lm3695@63 {
|
||||
};
|
||||
};
|
||||
|
||||
lm3697@36 {
|
||||
compatible = "ti,lm3697";
|
||||
reg = <0x36>;
|
||||
lm36274@11 {
|
||||
compatible = "ti,lm36274";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x11>;
|
||||
|
||||
enable-gpios = <&pioC 2 GPIO_ACTIVE_HIGH>;
|
||||
regulators {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "ti,lm363x-regulator";
|
||||
|
||||
backlight {
|
||||
compatible = "ti,lm3697-backlight";
|
||||
enable-gpios = <&pioC 0 GPIO_ACTIVE_HIGH>,
|
||||
<&pioC 1 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
lcd {
|
||||
led-sources = <0 1 2>;
|
||||
ramp-up-msec = <200>;
|
||||
ramp-down-msec = <200>;
|
||||
vboost {
|
||||
regulator-name = "lcd_boost";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <7150000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vpos {
|
||||
regulator-name = "lcd_vpos";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <6500000>;
|
||||
};
|
||||
|
||||
vneg {
|
||||
regulator-name = "lcd_vneg";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <6500000>;
|
||||
};
|
||||
};
|
||||
|
||||
fault-monitor {
|
||||
compatible = "ti,lm3697-fault-monitor";
|
||||
backlight {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "ti,lm36274-backlight";
|
||||
|
||||
led@0 {
|
||||
reg = <0>;
|
||||
led-sources = <0 2>;
|
||||
label = "white:backlight_cluster";
|
||||
linux,default-trigger = "backlight";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -679,7 +679,7 @@ status as "unknown". The available commands are:
|
||||
sysfs notes:
|
||||
|
||||
The ThinkLight sysfs interface is documented by the LED class
|
||||
documentation, in Documentation/leds/leds-class.txt. The ThinkLight LED name
|
||||
documentation, in Documentation/leds/leds-class.rst. The ThinkLight LED name
|
||||
is "tpacpi::thinklight".
|
||||
|
||||
Due to limitations in the sysfs LED class, if the status of the ThinkLight
|
||||
@ -779,7 +779,7 @@ All of the above can be turned on and off and can be made to blink.
|
||||
sysfs notes:
|
||||
|
||||
The ThinkPad LED sysfs interface is described in detail by the LED class
|
||||
documentation, in Documentation/leds/leds-class.txt.
|
||||
documentation, in Documentation/leds/leds-class.rst.
|
||||
|
||||
The LEDs are named (in LED ID order, from 0 to 12):
|
||||
"tpacpi::power", "tpacpi:orange:batt", "tpacpi:green:batt",
|
||||
|
25
Documentation/leds/index.rst
Normal file
25
Documentation/leds/index.rst
Normal file
@ -0,0 +1,25 @@
|
||||
:orphan:
|
||||
|
||||
====
|
||||
LEDs
|
||||
====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
leds-class
|
||||
leds-class-flash
|
||||
ledtrig-oneshot
|
||||
ledtrig-transient
|
||||
ledtrig-usbport
|
||||
|
||||
uleds
|
||||
|
||||
leds-blinkm
|
||||
leds-lm3556
|
||||
leds-lp3944
|
||||
leds-lp5521
|
||||
leds-lp5523
|
||||
leds-lp5562
|
||||
leds-lp55xx
|
||||
leds-mlxcpld
|
@ -1,3 +1,7 @@
|
||||
==================
|
||||
Leds BlinkM driver
|
||||
==================
|
||||
|
||||
The leds-blinkm driver supports the devices of the BlinkM family.
|
||||
|
||||
They are RGB-LED modules driven by a (AT)tiny microcontroller and
|
||||
@ -14,35 +18,36 @@ The interface this driver provides is 2-fold:
|
||||
a) LED class interface for use with triggers
|
||||
############################################
|
||||
|
||||
The registration follows the scheme:
|
||||
blinkm-<i2c-bus-nr>-<i2c-device-nr>-<color>
|
||||
The registration follows the scheme::
|
||||
|
||||
$ ls -h /sys/class/leds/blinkm-6-*
|
||||
/sys/class/leds/blinkm-6-9-blue:
|
||||
brightness device max_brightness power subsystem trigger uevent
|
||||
blinkm-<i2c-bus-nr>-<i2c-device-nr>-<color>
|
||||
|
||||
/sys/class/leds/blinkm-6-9-green:
|
||||
brightness device max_brightness power subsystem trigger uevent
|
||||
$ ls -h /sys/class/leds/blinkm-6-*
|
||||
/sys/class/leds/blinkm-6-9-blue:
|
||||
brightness device max_brightness power subsystem trigger uevent
|
||||
|
||||
/sys/class/leds/blinkm-6-9-red:
|
||||
brightness device max_brightness power subsystem trigger uevent
|
||||
/sys/class/leds/blinkm-6-9-green:
|
||||
brightness device max_brightness power subsystem trigger uevent
|
||||
|
||||
/sys/class/leds/blinkm-6-9-red:
|
||||
brightness device max_brightness power subsystem trigger uevent
|
||||
|
||||
(same is /sys/bus/i2c/devices/6-0009/leds)
|
||||
|
||||
We can control the colors separated into red, green and blue and
|
||||
assign triggers on each color.
|
||||
|
||||
E.g.:
|
||||
E.g.::
|
||||
|
||||
$ cat blinkm-6-9-blue/brightness
|
||||
05
|
||||
$ cat blinkm-6-9-blue/brightness
|
||||
05
|
||||
|
||||
$ echo 200 > blinkm-6-9-blue/brightness
|
||||
$
|
||||
$ echo 200 > blinkm-6-9-blue/brightness
|
||||
$
|
||||
|
||||
$ modprobe ledtrig-heartbeat
|
||||
$ echo heartbeat > blinkm-6-9-green/trigger
|
||||
$
|
||||
$ modprobe ledtrig-heartbeat
|
||||
$ echo heartbeat > blinkm-6-9-green/trigger
|
||||
$
|
||||
|
||||
|
||||
b) Sysfs group to control rgb, fade, hsb, scripts ...
|
||||
@ -52,29 +57,28 @@ This extended interface is available as folder blinkm
|
||||
in the sysfs folder of the I2C device.
|
||||
E.g. below /sys/bus/i2c/devices/6-0009/blinkm
|
||||
|
||||
$ ls -h /sys/bus/i2c/devices/6-0009/blinkm/
|
||||
blue green red test
|
||||
$ ls -h /sys/bus/i2c/devices/6-0009/blinkm/
|
||||
blue green red test
|
||||
|
||||
Currently supported is just setting red, green, blue
|
||||
and a test sequence.
|
||||
|
||||
E.g.:
|
||||
E.g.::
|
||||
|
||||
$ cat *
|
||||
00
|
||||
00
|
||||
00
|
||||
#Write into test to start test sequence!#
|
||||
$ cat *
|
||||
00
|
||||
00
|
||||
00
|
||||
#Write into test to start test sequence!#
|
||||
|
||||
$ echo 1 > test
|
||||
$
|
||||
$ echo 1 > test
|
||||
$
|
||||
|
||||
$ echo 255 > red
|
||||
$
|
||||
$ echo 255 > red
|
||||
$
|
||||
|
||||
|
||||
|
||||
as of 6/2012
|
||||
|
||||
dl9pf <at> gmx <dot> de
|
||||
|
@ -1,9 +1,9 @@
|
||||
|
||||
==============================
|
||||
Flash LED handling under Linux
|
||||
==============================
|
||||
|
||||
Some LED devices provide two modes - torch and flash. In the LED subsystem
|
||||
those modes are supported by LED class (see Documentation/leds/leds-class.txt)
|
||||
those modes are supported by LED class (see Documentation/leds/leds-class.rst)
|
||||
and LED Flash class respectively. The torch mode related features are enabled
|
||||
by default and the flash ones only if a driver declares it by setting
|
||||
LED_DEV_CAP_FLASH flag.
|
||||
@ -14,6 +14,7 @@ registered in the LED subsystem with led_classdev_flash_register function.
|
||||
|
||||
Following sysfs attributes are exposed for controlling flash LED devices:
|
||||
(see Documentation/ABI/testing/sysfs-class-led-flash)
|
||||
|
||||
- flash_brightness
|
||||
- max_flash_brightness
|
||||
- flash_timeout
|
||||
@ -31,30 +32,46 @@ be defined in the kernel config.
|
||||
|
||||
The driver must call the v4l2_flash_init function to get registered in the
|
||||
V4L2 subsystem. The function takes six arguments:
|
||||
- dev : flash device, e.g. an I2C device
|
||||
- of_node : of_node of the LED, may be NULL if the same as device's
|
||||
- fled_cdev : LED flash class device to wrap
|
||||
- iled_cdev : LED flash class device representing indicator LED associated with
|
||||
fled_cdev, may be NULL
|
||||
- ops : V4L2 specific ops
|
||||
* external_strobe_set - defines the source of the flash LED strobe -
|
||||
|
||||
- dev:
|
||||
flash device, e.g. an I2C device
|
||||
- of_node:
|
||||
of_node of the LED, may be NULL if the same as device's
|
||||
- fled_cdev:
|
||||
LED flash class device to wrap
|
||||
- iled_cdev:
|
||||
LED flash class device representing indicator LED associated with
|
||||
fled_cdev, may be NULL
|
||||
- ops:
|
||||
V4L2 specific ops
|
||||
|
||||
* external_strobe_set
|
||||
defines the source of the flash LED strobe -
|
||||
V4L2_CID_FLASH_STROBE control or external source, typically
|
||||
a sensor, which makes it possible to synchronise the flash
|
||||
strobe start with exposure start,
|
||||
* intensity_to_led_brightness and led_brightness_to_intensity - perform
|
||||
* intensity_to_led_brightness and led_brightness_to_intensity
|
||||
perform
|
||||
enum led_brightness <-> V4L2 intensity conversion in a device
|
||||
specific manner - they can be used for devices with non-linear
|
||||
LED current scale.
|
||||
- config : configuration for V4L2 Flash sub-device
|
||||
* dev_name - the name of the media entity, unique in the system,
|
||||
* flash_faults - bitmask of flash faults that the LED flash class
|
||||
- config:
|
||||
configuration for V4L2 Flash sub-device
|
||||
|
||||
* dev_name
|
||||
the name of the media entity, unique in the system,
|
||||
* flash_faults
|
||||
bitmask of flash faults that the LED flash class
|
||||
device can report; corresponding LED_FAULT* bit definitions are
|
||||
available in <linux/led-class-flash.h>,
|
||||
* torch_intensity - constraints for the LED in TORCH mode
|
||||
* torch_intensity
|
||||
constraints for the LED in TORCH mode
|
||||
in microamperes,
|
||||
* indicator_intensity - constraints for the indicator LED
|
||||
* indicator_intensity
|
||||
constraints for the indicator LED
|
||||
in microamperes,
|
||||
* has_external_strobe - determines whether the flash strobe source
|
||||
* has_external_strobe
|
||||
determines whether the flash strobe source
|
||||
can be switched to external,
|
||||
|
||||
On remove the v4l2_flash_release function has to be called, which takes one
|
@ -1,4 +1,4 @@
|
||||
|
||||
========================
|
||||
LED handling under Linux
|
||||
========================
|
||||
|
||||
@ -43,7 +43,7 @@ LED Device Naming
|
||||
|
||||
Is currently of the form:
|
||||
|
||||
"devicename:colour:function"
|
||||
"devicename:colour:function"
|
||||
|
||||
There have been calls for LED properties such as colour to be exported as
|
||||
individual led class attributes. As a solution which doesn't incur as much
|
||||
@ -57,9 +57,12 @@ Brightness setting API
|
||||
|
||||
LED subsystem core exposes following API for setting brightness:
|
||||
|
||||
- led_set_brightness : it is guaranteed not to sleep, passing LED_OFF stops
|
||||
- led_set_brightness:
|
||||
it is guaranteed not to sleep, passing LED_OFF stops
|
||||
blinking,
|
||||
- led_set_brightness_sync : for use cases when immediate effect is desired -
|
||||
|
||||
- led_set_brightness_sync:
|
||||
for use cases when immediate effect is desired -
|
||||
it can block the caller for the time required for accessing
|
||||
device registers and can sleep, passing LED_OFF stops hardware
|
||||
blinking, returns -EBUSY if software blink fallback is enabled.
|
||||
@ -70,7 +73,7 @@ LED registration API
|
||||
|
||||
A driver wanting to register a LED classdev for use by other drivers /
|
||||
userspace needs to allocate and fill a led_classdev struct and then call
|
||||
[devm_]led_classdev_register. If the non devm version is used the driver
|
||||
`[devm_]led_classdev_register`. If the non devm version is used the driver
|
||||
must call led_classdev_unregister from its remove function before
|
||||
free-ing the led_classdev struct.
|
||||
|
||||
@ -94,7 +97,7 @@ with brightness value LED_OFF, which should stop any software
|
||||
timers that may have been required for blinking.
|
||||
|
||||
The blink_set() function should choose a user friendly blinking value
|
||||
if it is called with *delay_on==0 && *delay_off==0 parameters. In this
|
||||
if it is called with `*delay_on==0` && `*delay_off==0` parameters. In this
|
||||
case the driver should give back the chosen value through delay_on and
|
||||
delay_off parameters to the leds subsystem.
|
||||
|
@ -1,68 +1,118 @@
|
||||
========================
|
||||
Kernel driver for lm3556
|
||||
========================
|
||||
|
||||
*Texas Instrument:
|
||||
1.5 A Synchronous Boost LED Flash Driver w/ High-Side Current Source
|
||||
* Texas Instrument:
|
||||
1.5 A Synchronous Boost LED Flash Driver w/ High-Side Current Source
|
||||
* Datasheet: http://www.national.com/ds/LM/LM3556.pdf
|
||||
|
||||
Authors:
|
||||
Daniel Jeong
|
||||
- Daniel Jeong
|
||||
|
||||
Contact:Daniel Jeong(daniel.jeong-at-ti.com, gshark.jeong-at-gmail.com)
|
||||
|
||||
Description
|
||||
-----------
|
||||
There are 3 functions in LM3556, Flash, Torch and Indicator.
|
||||
|
||||
FLASH MODE
|
||||
Flash Mode
|
||||
^^^^^^^^^^
|
||||
|
||||
In Flash Mode, the LED current source(LED) provides 16 target current levels
|
||||
from 93.75 mA to 1500 mA.The Flash currents are adjusted via the CURRENT
|
||||
CONTROL REGISTER(0x09).Flash mode is activated by the ENABLE REGISTER(0x0A),
|
||||
or by pulling the STROBE pin HIGH.
|
||||
|
||||
LM3556 Flash can be controlled through sys/class/leds/flash/brightness file
|
||||
|
||||
* if STROBE pin is enabled, below example control brightness only, and
|
||||
ON / OFF will be controlled by STROBE pin.
|
||||
ON / OFF will be controlled by STROBE pin.
|
||||
|
||||
Flash Example:
|
||||
OFF : #echo 0 > sys/class/leds/flash/brightness
|
||||
93.75 mA: #echo 1 > sys/class/leds/flash/brightness
|
||||
... .....
|
||||
1500 mA: #echo 16 > sys/class/leds/flash/brightness
|
||||
|
||||
TORCH MODE
|
||||
OFF::
|
||||
|
||||
#echo 0 > sys/class/leds/flash/brightness
|
||||
|
||||
93.75 mA::
|
||||
|
||||
#echo 1 > sys/class/leds/flash/brightness
|
||||
|
||||
...
|
||||
|
||||
1500 mA::
|
||||
|
||||
#echo 16 > sys/class/leds/flash/brightness
|
||||
|
||||
Torch Mode
|
||||
^^^^^^^^^^
|
||||
|
||||
In Torch Mode, the current source(LED) is programmed via the CURRENT CONTROL
|
||||
REGISTER(0x09).Torch Mode is activated by the ENABLE REGISTER(0x0A) or by the
|
||||
hardware TORCH input.
|
||||
|
||||
LM3556 torch can be controlled through sys/class/leds/torch/brightness file.
|
||||
* if TORCH pin is enabled, below example control brightness only,
|
||||
and ON / OFF will be controlled by TORCH pin.
|
||||
|
||||
Torch Example:
|
||||
OFF : #echo 0 > sys/class/leds/torch/brightness
|
||||
46.88 mA: #echo 1 > sys/class/leds/torch/brightness
|
||||
... .....
|
||||
375 mA : #echo 8 > sys/class/leds/torch/brightness
|
||||
|
||||
INDICATOR MODE
|
||||
OFF::
|
||||
|
||||
#echo 0 > sys/class/leds/torch/brightness
|
||||
|
||||
46.88 mA::
|
||||
|
||||
#echo 1 > sys/class/leds/torch/brightness
|
||||
|
||||
...
|
||||
|
||||
375 mA::
|
||||
|
||||
#echo 8 > sys/class/leds/torch/brightness
|
||||
|
||||
Indicator Mode
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Indicator pattern can be set through sys/class/leds/indicator/pattern file,
|
||||
and 4 patterns are pre-defined in indicator_pattern array.
|
||||
|
||||
According to N-lank, Pulse time and N Period values, different pattern wiill
|
||||
be generated.If you want new patterns for your own device, change
|
||||
indicator_pattern array with your own values and INDIC_PATTERN_SIZE.
|
||||
|
||||
Please refer datasheet for more detail about N-Blank, Pulse time and N Period.
|
||||
|
||||
Indicator pattern example:
|
||||
pattern 0: #echo 0 > sys/class/leds/indicator/pattern
|
||||
....
|
||||
pattern 3: #echo 3 > sys/class/leds/indicator/pattern
|
||||
|
||||
pattern 0::
|
||||
|
||||
#echo 0 > sys/class/leds/indicator/pattern
|
||||
|
||||
...
|
||||
|
||||
pattern 3::
|
||||
|
||||
#echo 3 > sys/class/leds/indicator/pattern
|
||||
|
||||
Indicator brightness can be controlled through
|
||||
sys/class/leds/indicator/brightness file.
|
||||
|
||||
Example:
|
||||
OFF : #echo 0 > sys/class/leds/indicator/brightness
|
||||
5.86 mA : #echo 1 > sys/class/leds/indicator/brightness
|
||||
........
|
||||
46.875mA : #echo 8 > sys/class/leds/indicator/brightness
|
||||
|
||||
OFF::
|
||||
|
||||
#echo 0 > sys/class/leds/indicator/brightness
|
||||
|
||||
5.86 mA::
|
||||
|
||||
#echo 1 > sys/class/leds/indicator/brightness
|
||||
|
||||
...
|
||||
|
||||
46.875mA::
|
||||
|
||||
#echo 8 > sys/class/leds/indicator/brightness
|
||||
|
||||
Notes
|
||||
-----
|
||||
@ -70,7 +120,8 @@ Driver expects it is registered using the i2c_board_info mechanism.
|
||||
To register the chip at address 0x63 on specific adapter, set the platform data
|
||||
according to include/linux/platform_data/leds-lm3556.h, set the i2c board info
|
||||
|
||||
Example:
|
||||
Example::
|
||||
|
||||
static struct i2c_board_info board_i2c_ch4[] __initdata = {
|
||||
{
|
||||
I2C_BOARD_INFO(LM3556_NAME, 0x63),
|
||||
@ -80,6 +131,7 @@ Example:
|
||||
|
||||
and register it in the platform init function
|
||||
|
||||
Example:
|
||||
Example::
|
||||
|
||||
board_register_i2c_bus(4, 400,
|
||||
board_i2c_ch4, ARRAY_SIZE(board_i2c_ch4));
|
@ -1,14 +1,20 @@
|
||||
====================
|
||||
Kernel driver lp3944
|
||||
====================
|
||||
|
||||
* National Semiconductor LP3944 Fun-light Chip
|
||||
|
||||
Prefix: 'lp3944'
|
||||
|
||||
Addresses scanned: None (see the Notes section below)
|
||||
Datasheet: Publicly available at the National Semiconductor website
|
||||
http://www.national.com/pf/LP/LP3944.html
|
||||
|
||||
Datasheet:
|
||||
|
||||
Publicly available at the National Semiconductor website
|
||||
http://www.national.com/pf/LP/LP3944.html
|
||||
|
||||
Authors:
|
||||
Antonio Ospite <ospite@studenti.unina.it>
|
||||
Antonio Ospite <ospite@studenti.unina.it>
|
||||
|
||||
|
||||
Description
|
||||
@ -19,8 +25,11 @@ is used as a led controller.
|
||||
|
||||
The DIM modes are used to set _blink_ patterns for leds, the pattern is
|
||||
specified supplying two parameters:
|
||||
- period: from 0s to 1.6s
|
||||
- duty cycle: percentage of the period the led is on, from 0 to 100
|
||||
|
||||
- period:
|
||||
from 0s to 1.6s
|
||||
- duty cycle:
|
||||
percentage of the period the led is on, from 0 to 100
|
||||
|
||||
Setting a led in DIM0 or DIM1 mode makes it blink according to the pattern.
|
||||
See the datasheet for details.
|
||||
@ -35,7 +44,7 @@ The chip is used mainly in embedded contexts, so this driver expects it is
|
||||
registered using the i2c_board_info mechanism.
|
||||
|
||||
To register the chip at address 0x60 on adapter 0, set the platform data
|
||||
according to include/linux/leds-lp3944.h, set the i2c board info:
|
||||
according to include/linux/leds-lp3944.h, set the i2c board info::
|
||||
|
||||
static struct i2c_board_info a910_i2c_board_info[] __initdata = {
|
||||
{
|
||||
@ -44,7 +53,7 @@ according to include/linux/leds-lp3944.h, set the i2c board info:
|
||||
},
|
||||
};
|
||||
|
||||
and register it in the platform init function
|
||||
and register it in the platform init function::
|
||||
|
||||
i2c_register_board_info(0, a910_i2c_board_info,
|
||||
ARRAY_SIZE(a910_i2c_board_info));
|
115
Documentation/leds/leds-lp5521.rst
Normal file
115
Documentation/leds/leds-lp5521.rst
Normal file
@ -0,0 +1,115 @@
|
||||
========================
|
||||
Kernel driver for lp5521
|
||||
========================
|
||||
|
||||
* National Semiconductor LP5521 led driver chip
|
||||
* Datasheet: http://www.national.com/pf/LP/LP5521.html
|
||||
|
||||
Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
|
||||
|
||||
Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
LP5521 can drive up to 3 channels. Leds can be controlled directly via
|
||||
the led class control interface. Channels have generic names:
|
||||
lp5521:channelx, where x is 0 .. 2
|
||||
|
||||
All three channels can be also controlled using the engine micro programs.
|
||||
More details of the instructions can be found from the public data sheet.
|
||||
|
||||
LP5521 has the internal program memory for running various LED patterns.
|
||||
There are two ways to run LED patterns.
|
||||
|
||||
1) Legacy interface - enginex_mode and enginex_load
|
||||
Control interface for the engines:
|
||||
|
||||
x is 1 .. 3
|
||||
|
||||
enginex_mode:
|
||||
disabled, load, run
|
||||
enginex_load:
|
||||
store program (visible only in engine load mode)
|
||||
|
||||
Example (start to blink the channel 2 led)::
|
||||
|
||||
cd /sys/class/leds/lp5521:channel2/device
|
||||
echo "load" > engine3_mode
|
||||
echo "037f4d0003ff6000" > engine3_load
|
||||
echo "run" > engine3_mode
|
||||
|
||||
To stop the engine::
|
||||
|
||||
echo "disabled" > engine3_mode
|
||||
|
||||
2) Firmware interface - LP55xx common interface
|
||||
|
||||
For the details, please refer to 'firmware' section in leds-lp55xx.txt
|
||||
|
||||
sysfs contains a selftest entry.
|
||||
|
||||
The test communicates with the chip and checks that
|
||||
the clock mode is automatically set to the requested one.
|
||||
|
||||
Each channel has its own led current settings.
|
||||
|
||||
- /sys/class/leds/lp5521:channel0/led_current - RW
|
||||
- /sys/class/leds/lp5521:channel0/max_current - RO
|
||||
|
||||
Format: 10x mA i.e 10 means 1.0 mA
|
||||
|
||||
example platform data::
|
||||
|
||||
static struct lp55xx_led_config lp5521_led_config[] = {
|
||||
{
|
||||
.name = "red",
|
||||
.chan_nr = 0,
|
||||
.led_current = 50,
|
||||
.max_current = 130,
|
||||
}, {
|
||||
.name = "green",
|
||||
.chan_nr = 1,
|
||||
.led_current = 0,
|
||||
.max_current = 130,
|
||||
}, {
|
||||
.name = "blue",
|
||||
.chan_nr = 2,
|
||||
.led_current = 0,
|
||||
.max_current = 130,
|
||||
}
|
||||
};
|
||||
|
||||
static int lp5521_setup(void)
|
||||
{
|
||||
/* setup HW resources */
|
||||
}
|
||||
|
||||
static void lp5521_release(void)
|
||||
{
|
||||
/* Release HW resources */
|
||||
}
|
||||
|
||||
static void lp5521_enable(bool state)
|
||||
{
|
||||
/* Control of chip enable signal */
|
||||
}
|
||||
|
||||
static struct lp55xx_platform_data lp5521_platform_data = {
|
||||
.led_config = lp5521_led_config,
|
||||
.num_channels = ARRAY_SIZE(lp5521_led_config),
|
||||
.clock_mode = LP55XX_CLOCK_EXT,
|
||||
.setup_resources = lp5521_setup,
|
||||
.release_resources = lp5521_release,
|
||||
.enable = lp5521_enable,
|
||||
};
|
||||
|
||||
Note:
|
||||
chan_nr can have values between 0 and 2.
|
||||
The name of each channel can be configurable.
|
||||
If the name field is not defined, the default name will be set to 'xxxx:channelN'
|
||||
(XXXX : pdata->label or i2c client name, N : channel number)
|
||||
|
||||
|
||||
If the current is set to 0 in the platform data, that channel is
|
||||
disabled and it is not visible in the sysfs.
|
@ -1,101 +0,0 @@
|
||||
Kernel driver for lp5521
|
||||
========================
|
||||
|
||||
* National Semiconductor LP5521 led driver chip
|
||||
* Datasheet: http://www.national.com/pf/LP/LP5521.html
|
||||
|
||||
Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
|
||||
Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
LP5521 can drive up to 3 channels. Leds can be controlled directly via
|
||||
the led class control interface. Channels have generic names:
|
||||
lp5521:channelx, where x is 0 .. 2
|
||||
|
||||
All three channels can be also controlled using the engine micro programs.
|
||||
More details of the instructions can be found from the public data sheet.
|
||||
|
||||
LP5521 has the internal program memory for running various LED patterns.
|
||||
There are two ways to run LED patterns.
|
||||
|
||||
1) Legacy interface - enginex_mode and enginex_load
|
||||
Control interface for the engines:
|
||||
x is 1 .. 3
|
||||
enginex_mode : disabled, load, run
|
||||
enginex_load : store program (visible only in engine load mode)
|
||||
|
||||
Example (start to blink the channel 2 led):
|
||||
cd /sys/class/leds/lp5521:channel2/device
|
||||
echo "load" > engine3_mode
|
||||
echo "037f4d0003ff6000" > engine3_load
|
||||
echo "run" > engine3_mode
|
||||
|
||||
To stop the engine:
|
||||
echo "disabled" > engine3_mode
|
||||
|
||||
2) Firmware interface - LP55xx common interface
|
||||
For the details, please refer to 'firmware' section in leds-lp55xx.txt
|
||||
|
||||
sysfs contains a selftest entry.
|
||||
The test communicates with the chip and checks that
|
||||
the clock mode is automatically set to the requested one.
|
||||
|
||||
Each channel has its own led current settings.
|
||||
/sys/class/leds/lp5521:channel0/led_current - RW
|
||||
/sys/class/leds/lp5521:channel0/max_current - RO
|
||||
Format: 10x mA i.e 10 means 1.0 mA
|
||||
|
||||
example platform data:
|
||||
|
||||
Note: chan_nr can have values between 0 and 2.
|
||||
The name of each channel can be configurable.
|
||||
If the name field is not defined, the default name will be set to 'xxxx:channelN'
|
||||
(XXXX : pdata->label or i2c client name, N : channel number)
|
||||
|
||||
static struct lp55xx_led_config lp5521_led_config[] = {
|
||||
{
|
||||
.name = "red",
|
||||
.chan_nr = 0,
|
||||
.led_current = 50,
|
||||
.max_current = 130,
|
||||
}, {
|
||||
.name = "green",
|
||||
.chan_nr = 1,
|
||||
.led_current = 0,
|
||||
.max_current = 130,
|
||||
}, {
|
||||
.name = "blue",
|
||||
.chan_nr = 2,
|
||||
.led_current = 0,
|
||||
.max_current = 130,
|
||||
}
|
||||
};
|
||||
|
||||
static int lp5521_setup(void)
|
||||
{
|
||||
/* setup HW resources */
|
||||
}
|
||||
|
||||
static void lp5521_release(void)
|
||||
{
|
||||
/* Release HW resources */
|
||||
}
|
||||
|
||||
static void lp5521_enable(bool state)
|
||||
{
|
||||
/* Control of chip enable signal */
|
||||
}
|
||||
|
||||
static struct lp55xx_platform_data lp5521_platform_data = {
|
||||
.led_config = lp5521_led_config,
|
||||
.num_channels = ARRAY_SIZE(lp5521_led_config),
|
||||
.clock_mode = LP55XX_CLOCK_EXT,
|
||||
.setup_resources = lp5521_setup,
|
||||
.release_resources = lp5521_release,
|
||||
.enable = lp5521_enable,
|
||||
};
|
||||
|
||||
If the current is set to 0 in the platform data, that channel is
|
||||
disabled and it is not visible in the sysfs.
|
147
Documentation/leds/leds-lp5523.rst
Normal file
147
Documentation/leds/leds-lp5523.rst
Normal file
@ -0,0 +1,147 @@
|
||||
========================
|
||||
Kernel driver for lp5523
|
||||
========================
|
||||
|
||||
* National Semiconductor LP5523 led driver chip
|
||||
* Datasheet: http://www.national.com/pf/LP/LP5523.html
|
||||
|
||||
Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
|
||||
Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
|
||||
|
||||
Description
|
||||
-----------
|
||||
LP5523 can drive up to 9 channels. Leds can be controlled directly via
|
||||
the led class control interface.
|
||||
The name of each channel is configurable in the platform data - name and label.
|
||||
There are three options to make the channel name.
|
||||
|
||||
a) Define the 'name' in the platform data
|
||||
|
||||
To make specific channel name, then use 'name' platform data.
|
||||
|
||||
- /sys/class/leds/R1 (name: 'R1')
|
||||
- /sys/class/leds/B1 (name: 'B1')
|
||||
|
||||
b) Use the 'label' with no 'name' field
|
||||
|
||||
For one device name with channel number, then use 'label'.
|
||||
- /sys/class/leds/RGB:channelN (label: 'RGB', N: 0 ~ 8)
|
||||
|
||||
c) Default
|
||||
|
||||
If both fields are NULL, 'lp5523' is used by default.
|
||||
- /sys/class/leds/lp5523:channelN (N: 0 ~ 8)
|
||||
|
||||
LP5523 has the internal program memory for running various LED patterns.
|
||||
There are two ways to run LED patterns.
|
||||
|
||||
1) Legacy interface - enginex_mode, enginex_load and enginex_leds
|
||||
|
||||
Control interface for the engines:
|
||||
|
||||
x is 1 .. 3
|
||||
|
||||
enginex_mode:
|
||||
disabled, load, run
|
||||
enginex_load:
|
||||
microcode load
|
||||
enginex_leds:
|
||||
led mux control
|
||||
|
||||
::
|
||||
|
||||
cd /sys/class/leds/lp5523:channel2/device
|
||||
echo "load" > engine3_mode
|
||||
echo "9d80400004ff05ff437f0000" > engine3_load
|
||||
echo "111111111" > engine3_leds
|
||||
echo "run" > engine3_mode
|
||||
|
||||
To stop the engine::
|
||||
|
||||
echo "disabled" > engine3_mode
|
||||
|
||||
2) Firmware interface - LP55xx common interface
|
||||
|
||||
For the details, please refer to 'firmware' section in leds-lp55xx.txt
|
||||
|
||||
LP5523 has three master faders. If a channel is mapped to one of
|
||||
the master faders, its output is dimmed based on the value of the master
|
||||
fader.
|
||||
|
||||
For example::
|
||||
|
||||
echo "123000123" > master_fader_leds
|
||||
|
||||
creates the following channel-fader mappings::
|
||||
|
||||
channel 0,6 to master_fader1
|
||||
channel 1,7 to master_fader2
|
||||
channel 2,8 to master_fader3
|
||||
|
||||
Then, to have 25% of the original output on channel 0,6::
|
||||
|
||||
echo 64 > master_fader1
|
||||
|
||||
To have 0% of the original output (i.e. no output) channel 1,7::
|
||||
|
||||
echo 0 > master_fader2
|
||||
|
||||
To have 100% of the original output (i.e. no dimming) on channel 2,8::
|
||||
|
||||
echo 255 > master_fader3
|
||||
|
||||
To clear all master fader controls::
|
||||
|
||||
echo "000000000" > master_fader_leds
|
||||
|
||||
Selftest uses always the current from the platform data.
|
||||
|
||||
Each channel contains led current settings.
|
||||
- /sys/class/leds/lp5523:channel2/led_current - RW
|
||||
- /sys/class/leds/lp5523:channel2/max_current - RO
|
||||
|
||||
Format: 10x mA i.e 10 means 1.0 mA
|
||||
|
||||
Example platform data::
|
||||
|
||||
static struct lp55xx_led_config lp5523_led_config[] = {
|
||||
{
|
||||
.name = "D1",
|
||||
.chan_nr = 0,
|
||||
.led_current = 50,
|
||||
.max_current = 130,
|
||||
},
|
||||
...
|
||||
{
|
||||
.chan_nr = 8,
|
||||
.led_current = 50,
|
||||
.max_current = 130,
|
||||
}
|
||||
};
|
||||
|
||||
static int lp5523_setup(void)
|
||||
{
|
||||
/* Setup HW resources */
|
||||
}
|
||||
|
||||
static void lp5523_release(void)
|
||||
{
|
||||
/* Release HW resources */
|
||||
}
|
||||
|
||||
static void lp5523_enable(bool state)
|
||||
{
|
||||
/* Control chip enable signal */
|
||||
}
|
||||
|
||||
static struct lp55xx_platform_data lp5523_platform_data = {
|
||||
.led_config = lp5523_led_config,
|
||||
.num_channels = ARRAY_SIZE(lp5523_led_config),
|
||||
.clock_mode = LP55XX_CLOCK_EXT,
|
||||
.setup_resources = lp5523_setup,
|
||||
.release_resources = lp5523_release,
|
||||
.enable = lp5523_enable,
|
||||
};
|
||||
|
||||
Note
|
||||
chan_nr can have values between 0 and 8.
|
@ -1,130 +0,0 @@
|
||||
Kernel driver for lp5523
|
||||
========================
|
||||
|
||||
* National Semiconductor LP5523 led driver chip
|
||||
* Datasheet: http://www.national.com/pf/LP/LP5523.html
|
||||
|
||||
Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
|
||||
Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
|
||||
|
||||
Description
|
||||
-----------
|
||||
LP5523 can drive up to 9 channels. Leds can be controlled directly via
|
||||
the led class control interface.
|
||||
The name of each channel is configurable in the platform data - name and label.
|
||||
There are three options to make the channel name.
|
||||
|
||||
a) Define the 'name' in the platform data
|
||||
To make specific channel name, then use 'name' platform data.
|
||||
/sys/class/leds/R1 (name: 'R1')
|
||||
/sys/class/leds/B1 (name: 'B1')
|
||||
|
||||
b) Use the 'label' with no 'name' field
|
||||
For one device name with channel number, then use 'label'.
|
||||
/sys/class/leds/RGB:channelN (label: 'RGB', N: 0 ~ 8)
|
||||
|
||||
c) Default
|
||||
If both fields are NULL, 'lp5523' is used by default.
|
||||
/sys/class/leds/lp5523:channelN (N: 0 ~ 8)
|
||||
|
||||
LP5523 has the internal program memory for running various LED patterns.
|
||||
There are two ways to run LED patterns.
|
||||
|
||||
1) Legacy interface - enginex_mode, enginex_load and enginex_leds
|
||||
Control interface for the engines:
|
||||
x is 1 .. 3
|
||||
enginex_mode : disabled, load, run
|
||||
enginex_load : microcode load
|
||||
enginex_leds : led mux control
|
||||
|
||||
cd /sys/class/leds/lp5523:channel2/device
|
||||
echo "load" > engine3_mode
|
||||
echo "9d80400004ff05ff437f0000" > engine3_load
|
||||
echo "111111111" > engine3_leds
|
||||
echo "run" > engine3_mode
|
||||
|
||||
To stop the engine:
|
||||
echo "disabled" > engine3_mode
|
||||
|
||||
2) Firmware interface - LP55xx common interface
|
||||
For the details, please refer to 'firmware' section in leds-lp55xx.txt
|
||||
|
||||
LP5523 has three master faders. If a channel is mapped to one of
|
||||
the master faders, its output is dimmed based on the value of the master
|
||||
fader.
|
||||
|
||||
For example,
|
||||
|
||||
echo "123000123" > master_fader_leds
|
||||
|
||||
creates the following channel-fader mappings:
|
||||
|
||||
channel 0,6 to master_fader1
|
||||
channel 1,7 to master_fader2
|
||||
channel 2,8 to master_fader3
|
||||
|
||||
Then, to have 25% of the original output on channel 0,6:
|
||||
|
||||
echo 64 > master_fader1
|
||||
|
||||
To have 0% of the original output (i.e. no output) channel 1,7:
|
||||
|
||||
echo 0 > master_fader2
|
||||
|
||||
To have 100% of the original output (i.e. no dimming) on channel 2,8:
|
||||
|
||||
echo 255 > master_fader3
|
||||
|
||||
To clear all master fader controls:
|
||||
|
||||
echo "000000000" > master_fader_leds
|
||||
|
||||
Selftest uses always the current from the platform data.
|
||||
|
||||
Each channel contains led current settings.
|
||||
/sys/class/leds/lp5523:channel2/led_current - RW
|
||||
/sys/class/leds/lp5523:channel2/max_current - RO
|
||||
Format: 10x mA i.e 10 means 1.0 mA
|
||||
|
||||
Example platform data:
|
||||
|
||||
Note - chan_nr can have values between 0 and 8.
|
||||
|
||||
static struct lp55xx_led_config lp5523_led_config[] = {
|
||||
{
|
||||
.name = "D1",
|
||||
.chan_nr = 0,
|
||||
.led_current = 50,
|
||||
.max_current = 130,
|
||||
},
|
||||
...
|
||||
{
|
||||
.chan_nr = 8,
|
||||
.led_current = 50,
|
||||
.max_current = 130,
|
||||
}
|
||||
};
|
||||
|
||||
static int lp5523_setup(void)
|
||||
{
|
||||
/* Setup HW resources */
|
||||
}
|
||||
|
||||
static void lp5523_release(void)
|
||||
{
|
||||
/* Release HW resources */
|
||||
}
|
||||
|
||||
static void lp5523_enable(bool state)
|
||||
{
|
||||
/* Control chip enable signal */
|
||||
}
|
||||
|
||||
static struct lp55xx_platform_data lp5523_platform_data = {
|
||||
.led_config = lp5523_led_config,
|
||||
.num_channels = ARRAY_SIZE(lp5523_led_config),
|
||||
.clock_mode = LP55XX_CLOCK_EXT,
|
||||
.setup_resources = lp5523_setup,
|
||||
.release_resources = lp5523_release,
|
||||
.enable = lp5523_enable,
|
||||
};
|
137
Documentation/leds/leds-lp5562.rst
Normal file
137
Documentation/leds/leds-lp5562.rst
Normal file
@ -0,0 +1,137 @@
|
||||
========================
|
||||
Kernel driver for lp5562
|
||||
========================
|
||||
|
||||
* TI LP5562 LED Driver
|
||||
|
||||
Author: Milo(Woogyom) Kim <milo.kim@ti.com>
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
LP5562 can drive up to 4 channels. R/G/B and White.
|
||||
LEDs can be controlled directly via the led class control interface.
|
||||
|
||||
All four channels can be also controlled using the engine micro programs.
|
||||
LP5562 has the internal program memory for running various LED patterns.
|
||||
For the details, please refer to 'firmware' section in leds-lp55xx.txt
|
||||
|
||||
Device attribute
|
||||
================
|
||||
|
||||
engine_mux
|
||||
3 Engines are allocated in LP5562, but the number of channel is 4.
|
||||
Therefore each channel should be mapped to the engine number.
|
||||
|
||||
Value: RGB or W
|
||||
|
||||
This attribute is used for programming LED data with the firmware interface.
|
||||
Unlike the LP5521/LP5523/55231, LP5562 has unique feature for the engine mux,
|
||||
so additional sysfs is required
|
||||
|
||||
LED Map
|
||||
|
||||
===== === ===============================
|
||||
Red ... Engine 1 (fixed)
|
||||
Green ... Engine 2 (fixed)
|
||||
Blue ... Engine 3 (fixed)
|
||||
White ... Engine 1 or 2 or 3 (selective)
|
||||
===== === ===============================
|
||||
|
||||
How to load the program data using engine_mux
|
||||
=============================================
|
||||
|
||||
Before loading the LP5562 program data, engine_mux should be written between
|
||||
the engine selection and loading the firmware.
|
||||
Engine mux has two different mode, RGB and W.
|
||||
RGB is used for loading RGB program data, W is used for W program data.
|
||||
|
||||
For example, run blinking green channel pattern::
|
||||
|
||||
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine # 2 is for green channel
|
||||
echo "RGB" > /sys/bus/i2c/devices/xxxx/engine_mux # engine mux for RGB
|
||||
echo 1 > /sys/class/firmware/lp5562/loading
|
||||
echo "4000600040FF6000" > /sys/class/firmware/lp5562/data
|
||||
echo 0 > /sys/class/firmware/lp5562/loading
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
To run a blinking white pattern::
|
||||
|
||||
echo 1 or 2 or 3 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo "W" > /sys/bus/i2c/devices/xxxx/engine_mux
|
||||
echo 1 > /sys/class/firmware/lp5562/loading
|
||||
echo "4000600040FF6000" > /sys/class/firmware/lp5562/data
|
||||
echo 0 > /sys/class/firmware/lp5562/loading
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
How to load the predefined patterns
|
||||
===================================
|
||||
|
||||
Please refer to 'leds-lp55xx.txt"
|
||||
|
||||
Setting Current of Each Channel
|
||||
===============================
|
||||
|
||||
Like LP5521 and LP5523/55231, LP5562 provides LED current settings.
|
||||
The 'led_current' and 'max_current' are used.
|
||||
|
||||
Example of Platform data
|
||||
========================
|
||||
|
||||
::
|
||||
|
||||
static struct lp55xx_led_config lp5562_led_config[] = {
|
||||
{
|
||||
.name = "R",
|
||||
.chan_nr = 0,
|
||||
.led_current = 20,
|
||||
.max_current = 40,
|
||||
},
|
||||
{
|
||||
.name = "G",
|
||||
.chan_nr = 1,
|
||||
.led_current = 20,
|
||||
.max_current = 40,
|
||||
},
|
||||
{
|
||||
.name = "B",
|
||||
.chan_nr = 2,
|
||||
.led_current = 20,
|
||||
.max_current = 40,
|
||||
},
|
||||
{
|
||||
.name = "W",
|
||||
.chan_nr = 3,
|
||||
.led_current = 20,
|
||||
.max_current = 40,
|
||||
},
|
||||
};
|
||||
|
||||
static int lp5562_setup(void)
|
||||
{
|
||||
/* setup HW resources */
|
||||
}
|
||||
|
||||
static void lp5562_release(void)
|
||||
{
|
||||
/* Release HW resources */
|
||||
}
|
||||
|
||||
static void lp5562_enable(bool state)
|
||||
{
|
||||
/* Control of chip enable signal */
|
||||
}
|
||||
|
||||
static struct lp55xx_platform_data lp5562_platform_data = {
|
||||
.led_config = lp5562_led_config,
|
||||
.num_channels = ARRAY_SIZE(lp5562_led_config),
|
||||
.setup_resources = lp5562_setup,
|
||||
.release_resources = lp5562_release,
|
||||
.enable = lp5562_enable,
|
||||
};
|
||||
|
||||
To configure the platform specific data, lp55xx_platform_data structure is used
|
||||
|
||||
|
||||
If the current is set to 0 in the platform data, that channel is
|
||||
disabled and it is not visible in the sysfs.
|
@ -1,120 +0,0 @@
|
||||
Kernel driver for LP5562
|
||||
========================
|
||||
|
||||
* TI LP5562 LED Driver
|
||||
|
||||
Author: Milo(Woogyom) Kim <milo.kim@ti.com>
|
||||
|
||||
Description
|
||||
|
||||
LP5562 can drive up to 4 channels. R/G/B and White.
|
||||
LEDs can be controlled directly via the led class control interface.
|
||||
|
||||
All four channels can be also controlled using the engine micro programs.
|
||||
LP5562 has the internal program memory for running various LED patterns.
|
||||
For the details, please refer to 'firmware' section in leds-lp55xx.txt
|
||||
|
||||
Device attribute: engine_mux
|
||||
|
||||
3 Engines are allocated in LP5562, but the number of channel is 4.
|
||||
Therefore each channel should be mapped to the engine number.
|
||||
Value : RGB or W
|
||||
|
||||
This attribute is used for programming LED data with the firmware interface.
|
||||
Unlike the LP5521/LP5523/55231, LP5562 has unique feature for the engine mux,
|
||||
so additional sysfs is required.
|
||||
|
||||
LED Map
|
||||
Red ... Engine 1 (fixed)
|
||||
Green ... Engine 2 (fixed)
|
||||
Blue ... Engine 3 (fixed)
|
||||
White ... Engine 1 or 2 or 3 (selective)
|
||||
|
||||
How to load the program data using engine_mux
|
||||
|
||||
Before loading the LP5562 program data, engine_mux should be written between
|
||||
the engine selection and loading the firmware.
|
||||
Engine mux has two different mode, RGB and W.
|
||||
RGB is used for loading RGB program data, W is used for W program data.
|
||||
|
||||
For example, run blinking green channel pattern,
|
||||
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine # 2 is for green channel
|
||||
echo "RGB" > /sys/bus/i2c/devices/xxxx/engine_mux # engine mux for RGB
|
||||
echo 1 > /sys/class/firmware/lp5562/loading
|
||||
echo "4000600040FF6000" > /sys/class/firmware/lp5562/data
|
||||
echo 0 > /sys/class/firmware/lp5562/loading
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
To run a blinking white pattern,
|
||||
echo 1 or 2 or 3 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo "W" > /sys/bus/i2c/devices/xxxx/engine_mux
|
||||
echo 1 > /sys/class/firmware/lp5562/loading
|
||||
echo "4000600040FF6000" > /sys/class/firmware/lp5562/data
|
||||
echo 0 > /sys/class/firmware/lp5562/loading
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
How to load the predefined patterns
|
||||
|
||||
Please refer to 'leds-lp55xx.txt"
|
||||
|
||||
Setting Current of Each Channel
|
||||
|
||||
Like LP5521 and LP5523/55231, LP5562 provides LED current settings.
|
||||
The 'led_current' and 'max_current' are used.
|
||||
|
||||
(Example of Platform data)
|
||||
|
||||
To configure the platform specific data, lp55xx_platform_data structure is used.
|
||||
|
||||
static struct lp55xx_led_config lp5562_led_config[] = {
|
||||
{
|
||||
.name = "R",
|
||||
.chan_nr = 0,
|
||||
.led_current = 20,
|
||||
.max_current = 40,
|
||||
},
|
||||
{
|
||||
.name = "G",
|
||||
.chan_nr = 1,
|
||||
.led_current = 20,
|
||||
.max_current = 40,
|
||||
},
|
||||
{
|
||||
.name = "B",
|
||||
.chan_nr = 2,
|
||||
.led_current = 20,
|
||||
.max_current = 40,
|
||||
},
|
||||
{
|
||||
.name = "W",
|
||||
.chan_nr = 3,
|
||||
.led_current = 20,
|
||||
.max_current = 40,
|
||||
},
|
||||
};
|
||||
|
||||
static int lp5562_setup(void)
|
||||
{
|
||||
/* setup HW resources */
|
||||
}
|
||||
|
||||
static void lp5562_release(void)
|
||||
{
|
||||
/* Release HW resources */
|
||||
}
|
||||
|
||||
static void lp5562_enable(bool state)
|
||||
{
|
||||
/* Control of chip enable signal */
|
||||
}
|
||||
|
||||
static struct lp55xx_platform_data lp5562_platform_data = {
|
||||
.led_config = lp5562_led_config,
|
||||
.num_channels = ARRAY_SIZE(lp5562_led_config),
|
||||
.setup_resources = lp5562_setup,
|
||||
.release_resources = lp5562_release,
|
||||
.enable = lp5562_enable,
|
||||
};
|
||||
|
||||
If the current is set to 0 in the platform data, that channel is
|
||||
disabled and it is not visible in the sysfs.
|
224
Documentation/leds/leds-lp55xx.rst
Normal file
224
Documentation/leds/leds-lp55xx.rst
Normal file
@ -0,0 +1,224 @@
|
||||
=================================================
|
||||
LP5521/LP5523/LP55231/LP5562/LP8501 Common Driver
|
||||
=================================================
|
||||
|
||||
Authors: Milo(Woogyom) Kim <milo.kim@ti.com>
|
||||
|
||||
Description
|
||||
-----------
|
||||
LP5521, LP5523/55231, LP5562 and LP8501 have common features as below.
|
||||
|
||||
Register access via the I2C
|
||||
Device initialization/deinitialization
|
||||
Create LED class devices for multiple output channels
|
||||
Device attributes for user-space interface
|
||||
Program memory for running LED patterns
|
||||
|
||||
The LP55xx common driver provides these features using exported functions.
|
||||
|
||||
lp55xx_init_device() / lp55xx_deinit_device()
|
||||
lp55xx_register_leds() / lp55xx_unregister_leds()
|
||||
lp55xx_regsister_sysfs() / lp55xx_unregister_sysfs()
|
||||
|
||||
( Driver Structure Data )
|
||||
|
||||
In lp55xx common driver, two different data structure is used.
|
||||
|
||||
* lp55xx_led
|
||||
control multi output LED channels such as led current, channel index.
|
||||
* lp55xx_chip
|
||||
general chip control such like the I2C and platform data.
|
||||
|
||||
For example, LP5521 has maximum 3 LED channels.
|
||||
LP5523/55231 has 9 output channels::
|
||||
|
||||
lp55xx_chip for LP5521 ... lp55xx_led #1
|
||||
lp55xx_led #2
|
||||
lp55xx_led #3
|
||||
|
||||
lp55xx_chip for LP5523 ... lp55xx_led #1
|
||||
lp55xx_led #2
|
||||
.
|
||||
.
|
||||
lp55xx_led #9
|
||||
|
||||
( Chip Dependent Code )
|
||||
|
||||
To support device specific configurations, special structure
|
||||
'lpxx_device_config' is used.
|
||||
|
||||
- Maximum number of channels
|
||||
- Reset command, chip enable command
|
||||
- Chip specific initialization
|
||||
- Brightness control register access
|
||||
- Setting LED output current
|
||||
- Program memory address access for running patterns
|
||||
- Additional device specific attributes
|
||||
|
||||
( Firmware Interface )
|
||||
|
||||
LP55xx family devices have the internal program memory for running
|
||||
various LED patterns.
|
||||
|
||||
This pattern data is saved as a file in the user-land or
|
||||
hex byte string is written into the memory through the I2C.
|
||||
|
||||
LP55xx common driver supports the firmware interface.
|
||||
|
||||
LP55xx chips have three program engines.
|
||||
|
||||
To load and run the pattern, the programming sequence is following.
|
||||
|
||||
(1) Select an engine number (1/2/3)
|
||||
(2) Mode change to load
|
||||
(3) Write pattern data into selected area
|
||||
(4) Mode change to run
|
||||
|
||||
The LP55xx common driver provides simple interfaces as below.
|
||||
|
||||
select_engine:
|
||||
Select which engine is used for running program
|
||||
run_engine:
|
||||
Start program which is loaded via the firmware interface
|
||||
firmware:
|
||||
Load program data
|
||||
|
||||
In case of LP5523, one more command is required, 'enginex_leds'.
|
||||
It is used for selecting LED output(s) at each engine number.
|
||||
In more details, please refer to 'leds-lp5523.txt'.
|
||||
|
||||
For example, run blinking pattern in engine #1 of LP5521::
|
||||
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo 1 > /sys/class/firmware/lp5521/loading
|
||||
echo "4000600040FF6000" > /sys/class/firmware/lp5521/data
|
||||
echo 0 > /sys/class/firmware/lp5521/loading
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
For example, run blinking pattern in engine #3 of LP55231
|
||||
|
||||
Two LEDs are configured as pattern output channels::
|
||||
|
||||
echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo 1 > /sys/class/firmware/lp55231/loading
|
||||
echo "9d0740ff7e0040007e00a0010000" > /sys/class/firmware/lp55231/data
|
||||
echo 0 > /sys/class/firmware/lp55231/loading
|
||||
echo "000001100" > /sys/bus/i2c/devices/xxxx/engine3_leds
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
To start blinking patterns in engine #2 and #3 simultaneously::
|
||||
|
||||
for idx in 2 3
|
||||
do
|
||||
echo $idx > /sys/class/leds/red/device/select_engine
|
||||
sleep 0.1
|
||||
echo 1 > /sys/class/firmware/lp5521/loading
|
||||
echo "4000600040FF6000" > /sys/class/firmware/lp5521/data
|
||||
echo 0 > /sys/class/firmware/lp5521/loading
|
||||
done
|
||||
echo 1 > /sys/class/leds/red/device/run_engine
|
||||
|
||||
Here is another example for LP5523.
|
||||
|
||||
Full LED strings are selected by 'engine2_leds'::
|
||||
|
||||
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo 1 > /sys/class/firmware/lp5523/loading
|
||||
echo "9d80400004ff05ff437f0000" > /sys/class/firmware/lp5523/data
|
||||
echo 0 > /sys/class/firmware/lp5523/loading
|
||||
echo "111111111" > /sys/bus/i2c/devices/xxxx/engine2_leds
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
As soon as 'loading' is set to 0, registered callback is called.
|
||||
Inside the callback, the selected engine is loaded and memory is updated.
|
||||
To run programmed pattern, 'run_engine' attribute should be enabled.
|
||||
|
||||
The pattern sequence of LP8501 is similar to LP5523.
|
||||
|
||||
However pattern data is specific.
|
||||
|
||||
Ex 1) Engine 1 is used::
|
||||
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo 1 > /sys/class/firmware/lp8501/loading
|
||||
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
|
||||
echo 0 > /sys/class/firmware/lp8501/loading
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
Ex 2) Engine 2 and 3 are used at the same time::
|
||||
|
||||
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
sleep 1
|
||||
echo 1 > /sys/class/firmware/lp8501/loading
|
||||
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
|
||||
echo 0 > /sys/class/firmware/lp8501/loading
|
||||
sleep 1
|
||||
echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
sleep 1
|
||||
echo 1 > /sys/class/firmware/lp8501/loading
|
||||
echo "9d0340ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
|
||||
echo 0 > /sys/class/firmware/lp8501/loading
|
||||
sleep 1
|
||||
echo 1 > /sys/class/leds/d1/device/run_engine
|
||||
|
||||
( 'run_engine' and 'firmware_cb' )
|
||||
|
||||
The sequence of running the program data is common.
|
||||
|
||||
But each device has own specific register addresses for commands.
|
||||
|
||||
To support this, 'run_engine' and 'firmware_cb' are configurable in each driver.
|
||||
|
||||
run_engine:
|
||||
Control the selected engine
|
||||
firmware_cb:
|
||||
The callback function after loading the firmware is done.
|
||||
|
||||
Chip specific commands for loading and updating program memory.
|
||||
|
||||
( Predefined pattern data )
|
||||
|
||||
Without the firmware interface, LP55xx driver provides another method for
|
||||
loading a LED pattern. That is 'predefined' pattern.
|
||||
|
||||
A predefined pattern is defined in the platform data and load it(or them)
|
||||
via the sysfs if needed.
|
||||
|
||||
To use the predefined pattern concept, 'patterns' and 'num_patterns' should be
|
||||
configured.
|
||||
|
||||
Example of predefined pattern data::
|
||||
|
||||
/* mode_1: blinking data */
|
||||
static const u8 mode_1[] = {
|
||||
0x40, 0x00, 0x60, 0x00, 0x40, 0xFF, 0x60, 0x00,
|
||||
};
|
||||
|
||||
/* mode_2: always on */
|
||||
static const u8 mode_2[] = { 0x40, 0xFF, };
|
||||
|
||||
struct lp55xx_predef_pattern board_led_patterns[] = {
|
||||
{
|
||||
.r = mode_1,
|
||||
.size_r = ARRAY_SIZE(mode_1),
|
||||
},
|
||||
{
|
||||
.b = mode_2,
|
||||
.size_b = ARRAY_SIZE(mode_2),
|
||||
},
|
||||
}
|
||||
|
||||
struct lp55xx_platform_data lp5562_pdata = {
|
||||
...
|
||||
.patterns = board_led_patterns,
|
||||
.num_patterns = ARRAY_SIZE(board_led_patterns),
|
||||
};
|
||||
|
||||
Then, mode_1 and mode_2 can be run via through the sysfs::
|
||||
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern # red blinking LED pattern
|
||||
echo 2 > /sys/bus/i2c/devices/xxxx/led_pattern # blue LED always on
|
||||
|
||||
To stop running pattern::
|
||||
|
||||
echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern
|
@ -1,194 +0,0 @@
|
||||
LP5521/LP5523/LP55231/LP5562/LP8501 Common Driver
|
||||
=================================================
|
||||
|
||||
Authors: Milo(Woogyom) Kim <milo.kim@ti.com>
|
||||
|
||||
Description
|
||||
-----------
|
||||
LP5521, LP5523/55231, LP5562 and LP8501 have common features as below.
|
||||
|
||||
Register access via the I2C
|
||||
Device initialization/deinitialization
|
||||
Create LED class devices for multiple output channels
|
||||
Device attributes for user-space interface
|
||||
Program memory for running LED patterns
|
||||
|
||||
The LP55xx common driver provides these features using exported functions.
|
||||
lp55xx_init_device() / lp55xx_deinit_device()
|
||||
lp55xx_register_leds() / lp55xx_unregister_leds()
|
||||
lp55xx_regsister_sysfs() / lp55xx_unregister_sysfs()
|
||||
|
||||
( Driver Structure Data )
|
||||
|
||||
In lp55xx common driver, two different data structure is used.
|
||||
|
||||
o lp55xx_led
|
||||
control multi output LED channels such as led current, channel index.
|
||||
o lp55xx_chip
|
||||
general chip control such like the I2C and platform data.
|
||||
|
||||
For example, LP5521 has maximum 3 LED channels.
|
||||
LP5523/55231 has 9 output channels.
|
||||
|
||||
lp55xx_chip for LP5521 ... lp55xx_led #1
|
||||
lp55xx_led #2
|
||||
lp55xx_led #3
|
||||
|
||||
lp55xx_chip for LP5523 ... lp55xx_led #1
|
||||
lp55xx_led #2
|
||||
.
|
||||
.
|
||||
lp55xx_led #9
|
||||
|
||||
( Chip Dependent Code )
|
||||
|
||||
To support device specific configurations, special structure
|
||||
'lpxx_device_config' is used.
|
||||
|
||||
Maximum number of channels
|
||||
Reset command, chip enable command
|
||||
Chip specific initialization
|
||||
Brightness control register access
|
||||
Setting LED output current
|
||||
Program memory address access for running patterns
|
||||
Additional device specific attributes
|
||||
|
||||
( Firmware Interface )
|
||||
|
||||
LP55xx family devices have the internal program memory for running
|
||||
various LED patterns.
|
||||
This pattern data is saved as a file in the user-land or
|
||||
hex byte string is written into the memory through the I2C.
|
||||
LP55xx common driver supports the firmware interface.
|
||||
|
||||
LP55xx chips have three program engines.
|
||||
To load and run the pattern, the programming sequence is following.
|
||||
(1) Select an engine number (1/2/3)
|
||||
(2) Mode change to load
|
||||
(3) Write pattern data into selected area
|
||||
(4) Mode change to run
|
||||
|
||||
The LP55xx common driver provides simple interfaces as below.
|
||||
select_engine : Select which engine is used for running program
|
||||
run_engine : Start program which is loaded via the firmware interface
|
||||
firmware : Load program data
|
||||
|
||||
In case of LP5523, one more command is required, 'enginex_leds'.
|
||||
It is used for selecting LED output(s) at each engine number.
|
||||
In more details, please refer to 'leds-lp5523.txt'.
|
||||
|
||||
For example, run blinking pattern in engine #1 of LP5521
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo 1 > /sys/class/firmware/lp5521/loading
|
||||
echo "4000600040FF6000" > /sys/class/firmware/lp5521/data
|
||||
echo 0 > /sys/class/firmware/lp5521/loading
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
For example, run blinking pattern in engine #3 of LP55231
|
||||
Two LEDs are configured as pattern output channels.
|
||||
echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo 1 > /sys/class/firmware/lp55231/loading
|
||||
echo "9d0740ff7e0040007e00a0010000" > /sys/class/firmware/lp55231/data
|
||||
echo 0 > /sys/class/firmware/lp55231/loading
|
||||
echo "000001100" > /sys/bus/i2c/devices/xxxx/engine3_leds
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
To start blinking patterns in engine #2 and #3 simultaneously,
|
||||
for idx in 2 3
|
||||
do
|
||||
echo $idx > /sys/class/leds/red/device/select_engine
|
||||
sleep 0.1
|
||||
echo 1 > /sys/class/firmware/lp5521/loading
|
||||
echo "4000600040FF6000" > /sys/class/firmware/lp5521/data
|
||||
echo 0 > /sys/class/firmware/lp5521/loading
|
||||
done
|
||||
echo 1 > /sys/class/leds/red/device/run_engine
|
||||
|
||||
Here is another example for LP5523.
|
||||
Full LED strings are selected by 'engine2_leds'.
|
||||
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo 1 > /sys/class/firmware/lp5523/loading
|
||||
echo "9d80400004ff05ff437f0000" > /sys/class/firmware/lp5523/data
|
||||
echo 0 > /sys/class/firmware/lp5523/loading
|
||||
echo "111111111" > /sys/bus/i2c/devices/xxxx/engine2_leds
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
As soon as 'loading' is set to 0, registered callback is called.
|
||||
Inside the callback, the selected engine is loaded and memory is updated.
|
||||
To run programmed pattern, 'run_engine' attribute should be enabled.
|
||||
|
||||
The pattern sequence of LP8501 is similar to LP5523.
|
||||
However pattern data is specific.
|
||||
Ex 1) Engine 1 is used
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
echo 1 > /sys/class/firmware/lp8501/loading
|
||||
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
|
||||
echo 0 > /sys/class/firmware/lp8501/loading
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
|
||||
|
||||
Ex 2) Engine 2 and 3 are used at the same time
|
||||
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
sleep 1
|
||||
echo 1 > /sys/class/firmware/lp8501/loading
|
||||
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
|
||||
echo 0 > /sys/class/firmware/lp8501/loading
|
||||
sleep 1
|
||||
echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
|
||||
sleep 1
|
||||
echo 1 > /sys/class/firmware/lp8501/loading
|
||||
echo "9d0340ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
|
||||
echo 0 > /sys/class/firmware/lp8501/loading
|
||||
sleep 1
|
||||
echo 1 > /sys/class/leds/d1/device/run_engine
|
||||
|
||||
( 'run_engine' and 'firmware_cb' )
|
||||
The sequence of running the program data is common.
|
||||
But each device has own specific register addresses for commands.
|
||||
To support this, 'run_engine' and 'firmware_cb' are configurable in each driver.
|
||||
run_engine : Control the selected engine
|
||||
firmware_cb : The callback function after loading the firmware is done.
|
||||
Chip specific commands for loading and updating program memory.
|
||||
|
||||
( Predefined pattern data )
|
||||
|
||||
Without the firmware interface, LP55xx driver provides another method for
|
||||
loading a LED pattern. That is 'predefined' pattern.
|
||||
A predefined pattern is defined in the platform data and load it(or them)
|
||||
via the sysfs if needed.
|
||||
To use the predefined pattern concept, 'patterns' and 'num_patterns' should be
|
||||
configured.
|
||||
|
||||
Example of predefined pattern data:
|
||||
|
||||
/* mode_1: blinking data */
|
||||
static const u8 mode_1[] = {
|
||||
0x40, 0x00, 0x60, 0x00, 0x40, 0xFF, 0x60, 0x00,
|
||||
};
|
||||
|
||||
/* mode_2: always on */
|
||||
static const u8 mode_2[] = { 0x40, 0xFF, };
|
||||
|
||||
struct lp55xx_predef_pattern board_led_patterns[] = {
|
||||
{
|
||||
.r = mode_1,
|
||||
.size_r = ARRAY_SIZE(mode_1),
|
||||
},
|
||||
{
|
||||
.b = mode_2,
|
||||
.size_b = ARRAY_SIZE(mode_2),
|
||||
},
|
||||
}
|
||||
|
||||
struct lp55xx_platform_data lp5562_pdata = {
|
||||
...
|
||||
.patterns = board_led_patterns,
|
||||
.num_patterns = ARRAY_SIZE(board_led_patterns),
|
||||
};
|
||||
|
||||
Then, mode_1 and mode_2 can be run via through the sysfs.
|
||||
|
||||
echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern # red blinking LED pattern
|
||||
echo 2 > /sys/bus/i2c/devices/xxxx/led_pattern # blue LED always on
|
||||
|
||||
To stop running pattern,
|
||||
echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern
|
118
Documentation/leds/leds-mlxcpld.rst
Normal file
118
Documentation/leds/leds-mlxcpld.rst
Normal file
@ -0,0 +1,118 @@
|
||||
=======================================
|
||||
Kernel driver for Mellanox systems LEDs
|
||||
=======================================
|
||||
|
||||
Provide system LED support for the nex Mellanox systems:
|
||||
"msx6710", "msx6720", "msb7700", "msn2700", "msx1410",
|
||||
"msn2410", "msb7800", "msn2740", "msn2100".
|
||||
|
||||
Description
|
||||
-----------
|
||||
Driver provides the following LEDs for the systems "msx6710", "msx6720",
|
||||
"msb7700", "msn2700", "msx1410", "msn2410", "msb7800", "msn2740":
|
||||
|
||||
- mlxcpld:fan1:green
|
||||
- mlxcpld:fan1:red
|
||||
- mlxcpld:fan2:green
|
||||
- mlxcpld:fan2:red
|
||||
- mlxcpld:fan3:green
|
||||
- mlxcpld:fan3:red
|
||||
- mlxcpld:fan4:green
|
||||
- mlxcpld:fan4:red
|
||||
- mlxcpld:psu:green
|
||||
- mlxcpld:psu:red
|
||||
- mlxcpld:status:green
|
||||
- mlxcpld:status:red
|
||||
|
||||
"status"
|
||||
- CPLD reg offset: 0x20
|
||||
- Bits [3:0]
|
||||
|
||||
"psu"
|
||||
- CPLD reg offset: 0x20
|
||||
- Bits [7:4]
|
||||
|
||||
"fan1"
|
||||
- CPLD reg offset: 0x21
|
||||
- Bits [3:0]
|
||||
|
||||
"fan2"
|
||||
- CPLD reg offset: 0x21
|
||||
- Bits [7:4]
|
||||
|
||||
"fan3"
|
||||
- CPLD reg offset: 0x22
|
||||
- Bits [3:0]
|
||||
|
||||
"fan4"
|
||||
- CPLD reg offset: 0x22
|
||||
- Bits [7:4]
|
||||
|
||||
Color mask for all the above LEDs:
|
||||
|
||||
[bit3,bit2,bit1,bit0] or
|
||||
[bit7,bit6,bit5,bit4]:
|
||||
|
||||
- [0,0,0,0] = LED OFF
|
||||
- [0,1,0,1] = Red static ON
|
||||
- [1,1,0,1] = Green static ON
|
||||
- [0,1,1,0] = Red blink 3Hz
|
||||
- [1,1,1,0] = Green blink 3Hz
|
||||
- [0,1,1,1] = Red blink 6Hz
|
||||
- [1,1,1,1] = Green blink 6Hz
|
||||
|
||||
Driver provides the following LEDs for the system "msn2100":
|
||||
|
||||
- mlxcpld:fan:green
|
||||
- mlxcpld:fan:red
|
||||
- mlxcpld:psu1:green
|
||||
- mlxcpld:psu1:red
|
||||
- mlxcpld:psu2:green
|
||||
- mlxcpld:psu2:red
|
||||
- mlxcpld:status:green
|
||||
- mlxcpld:status:red
|
||||
- mlxcpld:uid:blue
|
||||
|
||||
"status"
|
||||
- CPLD reg offset: 0x20
|
||||
- Bits [3:0]
|
||||
|
||||
"fan"
|
||||
- CPLD reg offset: 0x21
|
||||
- Bits [3:0]
|
||||
|
||||
"psu1"
|
||||
- CPLD reg offset: 0x23
|
||||
- Bits [3:0]
|
||||
|
||||
"psu2"
|
||||
- CPLD reg offset: 0x23
|
||||
- Bits [7:4]
|
||||
|
||||
"uid"
|
||||
- CPLD reg offset: 0x24
|
||||
- Bits [3:0]
|
||||
|
||||
Color mask for all the above LEDs, excepted uid:
|
||||
|
||||
[bit3,bit2,bit1,bit0] or
|
||||
[bit7,bit6,bit5,bit4]:
|
||||
|
||||
- [0,0,0,0] = LED OFF
|
||||
- [0,1,0,1] = Red static ON
|
||||
- [1,1,0,1] = Green static ON
|
||||
- [0,1,1,0] = Red blink 3Hz
|
||||
- [1,1,1,0] = Green blink 3Hz
|
||||
- [0,1,1,1] = Red blink 6Hz
|
||||
- [1,1,1,1] = Green blink 6Hz
|
||||
|
||||
Color mask for uid LED:
|
||||
[bit3,bit2,bit1,bit0]:
|
||||
|
||||
- [0,0,0,0] = LED OFF
|
||||
- [1,1,0,1] = Blue static ON
|
||||
- [1,1,1,0] = Blue blink 3Hz
|
||||
- [1,1,1,1] = Blue blink 6Hz
|
||||
|
||||
Driver supports HW blinking at 3Hz and 6Hz frequency (50% duty cycle).
|
||||
For 3Hz duty cylce is about 167 msec, for 6Hz is about 83 msec.
|
@ -1,110 +0,0 @@
|
||||
Kernel driver for Mellanox systems LEDs
|
||||
=======================================
|
||||
|
||||
Provide system LED support for the nex Mellanox systems:
|
||||
"msx6710", "msx6720", "msb7700", "msn2700", "msx1410",
|
||||
"msn2410", "msb7800", "msn2740", "msn2100".
|
||||
|
||||
Description
|
||||
-----------
|
||||
Driver provides the following LEDs for the systems "msx6710", "msx6720",
|
||||
"msb7700", "msn2700", "msx1410", "msn2410", "msb7800", "msn2740":
|
||||
mlxcpld:fan1:green
|
||||
mlxcpld:fan1:red
|
||||
mlxcpld:fan2:green
|
||||
mlxcpld:fan2:red
|
||||
mlxcpld:fan3:green
|
||||
mlxcpld:fan3:red
|
||||
mlxcpld:fan4:green
|
||||
mlxcpld:fan4:red
|
||||
mlxcpld:psu:green
|
||||
mlxcpld:psu:red
|
||||
mlxcpld:status:green
|
||||
mlxcpld:status:red
|
||||
|
||||
"status"
|
||||
CPLD reg offset: 0x20
|
||||
Bits [3:0]
|
||||
|
||||
"psu"
|
||||
CPLD reg offset: 0x20
|
||||
Bits [7:4]
|
||||
|
||||
"fan1"
|
||||
CPLD reg offset: 0x21
|
||||
Bits [3:0]
|
||||
|
||||
"fan2"
|
||||
CPLD reg offset: 0x21
|
||||
Bits [7:4]
|
||||
|
||||
"fan3"
|
||||
CPLD reg offset: 0x22
|
||||
Bits [3:0]
|
||||
|
||||
"fan4"
|
||||
CPLD reg offset: 0x22
|
||||
Bits [7:4]
|
||||
|
||||
Color mask for all the above LEDs:
|
||||
[bit3,bit2,bit1,bit0] or
|
||||
[bit7,bit6,bit5,bit4]:
|
||||
[0,0,0,0] = LED OFF
|
||||
[0,1,0,1] = Red static ON
|
||||
[1,1,0,1] = Green static ON
|
||||
[0,1,1,0] = Red blink 3Hz
|
||||
[1,1,1,0] = Green blink 3Hz
|
||||
[0,1,1,1] = Red blink 6Hz
|
||||
[1,1,1,1] = Green blink 6Hz
|
||||
|
||||
Driver provides the following LEDs for the system "msn2100":
|
||||
mlxcpld:fan:green
|
||||
mlxcpld:fan:red
|
||||
mlxcpld:psu1:green
|
||||
mlxcpld:psu1:red
|
||||
mlxcpld:psu2:green
|
||||
mlxcpld:psu2:red
|
||||
mlxcpld:status:green
|
||||
mlxcpld:status:red
|
||||
mlxcpld:uid:blue
|
||||
|
||||
"status"
|
||||
CPLD reg offset: 0x20
|
||||
Bits [3:0]
|
||||
|
||||
"fan"
|
||||
CPLD reg offset: 0x21
|
||||
Bits [3:0]
|
||||
|
||||
"psu1"
|
||||
CPLD reg offset: 0x23
|
||||
Bits [3:0]
|
||||
|
||||
"psu2"
|
||||
CPLD reg offset: 0x23
|
||||
Bits [7:4]
|
||||
|
||||
"uid"
|
||||
CPLD reg offset: 0x24
|
||||
Bits [3:0]
|
||||
|
||||
Color mask for all the above LEDs, excepted uid:
|
||||
[bit3,bit2,bit1,bit0] or
|
||||
[bit7,bit6,bit5,bit4]:
|
||||
[0,0,0,0] = LED OFF
|
||||
[0,1,0,1] = Red static ON
|
||||
[1,1,0,1] = Green static ON
|
||||
[0,1,1,0] = Red blink 3Hz
|
||||
[1,1,1,0] = Green blink 3Hz
|
||||
[0,1,1,1] = Red blink 6Hz
|
||||
[1,1,1,1] = Green blink 6Hz
|
||||
|
||||
Color mask for uid LED:
|
||||
[bit3,bit2,bit1,bit0]:
|
||||
[0,0,0,0] = LED OFF
|
||||
[1,1,0,1] = Blue static ON
|
||||
[1,1,1,0] = Blue blink 3Hz
|
||||
[1,1,1,1] = Blue blink 6Hz
|
||||
|
||||
Driver supports HW blinking at 3Hz and 6Hz frequency (50% duty cycle).
|
||||
For 3Hz duty cylce is about 167 msec, for 6Hz is about 83 msec.
|
@ -1,3 +1,4 @@
|
||||
====================
|
||||
One-shot LED Trigger
|
||||
====================
|
||||
|
||||
@ -17,27 +18,27 @@ additional "invert" property specifies if the LED has to stay off (normal) or
|
||||
on (inverted) when not rearmed.
|
||||
|
||||
The trigger can be activated from user space on led class devices as shown
|
||||
below:
|
||||
below::
|
||||
|
||||
echo oneshot > trigger
|
||||
|
||||
This adds sysfs attributes to the LED that are documented in:
|
||||
Documentation/ABI/testing/sysfs-class-led-trigger-oneshot
|
||||
|
||||
Example use-case: network devices, initialization:
|
||||
Example use-case: network devices, initialization::
|
||||
|
||||
echo oneshot > trigger # set trigger for this led
|
||||
echo 33 > delay_on # blink at 1 / (33 + 33) Hz on continuous traffic
|
||||
echo 33 > delay_off
|
||||
|
||||
interface goes up:
|
||||
interface goes up::
|
||||
|
||||
echo 1 > invert # set led as normally-on, turn the led on
|
||||
|
||||
packet received/transmitted:
|
||||
packet received/transmitted::
|
||||
|
||||
echo 1 > shot # led starts blinking, ignored if already blinking
|
||||
|
||||
interface goes down
|
||||
interface goes down::
|
||||
|
||||
echo 0 > invert # set led as normally-off, turn the led off
|
@ -1,3 +1,4 @@
|
||||
=====================
|
||||
LED Transient Trigger
|
||||
=====================
|
||||
|
||||
@ -62,12 +63,13 @@ non-transient state. When driver gets suspended, irrespective of the transient
|
||||
state, the LED state changes to LED_OFF.
|
||||
|
||||
Transient trigger can be enabled and disabled from user space on led class
|
||||
devices, that support this trigger as shown below:
|
||||
devices, that support this trigger as shown below::
|
||||
|
||||
echo transient > trigger
|
||||
echo none > trigger
|
||||
echo transient > trigger
|
||||
echo none > trigger
|
||||
|
||||
NOTE: Add a new property trigger state to control the state.
|
||||
NOTE:
|
||||
Add a new property trigger state to control the state.
|
||||
|
||||
This trigger exports three properties, activate, state, and duration. When
|
||||
transient trigger is activated these properties are set to default values.
|
||||
@ -79,7 +81,8 @@ transient trigger is activated these properties are set to default values.
|
||||
- state allows user to specify a transient state to be held for the specified
|
||||
duration.
|
||||
|
||||
activate - one shot timer activate mechanism.
|
||||
activate
|
||||
- one shot timer activate mechanism.
|
||||
1 when activated, 0 when deactivated.
|
||||
default value is zero when transient trigger is enabled,
|
||||
to allow duration to be set.
|
||||
@ -89,12 +92,14 @@ transient trigger is activated these properties are set to default values.
|
||||
deactivated state indicates that there is no active timer
|
||||
running.
|
||||
|
||||
duration - one shot timer value. When activate is set, duration value
|
||||
duration
|
||||
- one shot timer value. When activate is set, duration value
|
||||
is used to start a timer that runs once. This value doesn't
|
||||
get changed by the trigger unless user does a set via
|
||||
echo new_value > duration
|
||||
|
||||
state - transient state to be held. It has two values 0 or 1. 0 maps
|
||||
state
|
||||
- transient state to be held. It has two values 0 or 1. 0 maps
|
||||
to LED_OFF and 1 maps to LED_FULL. The specified state is
|
||||
held for the duration of the one shot timer and then the
|
||||
state gets changed to the non-transient state which is the
|
||||
@ -114,39 +119,49 @@ When timer expires activate goes back to deactivated state, duration is left
|
||||
at the set value to be used when activate is set at a future time. This will
|
||||
allow user app to set the time once and activate it to run it once for the
|
||||
specified value as needed. When timer expires, state is restored to the
|
||||
non-transient state which is the inverse of the transient state.
|
||||
non-transient state which is the inverse of the transient state:
|
||||
|
||||
echo 1 > activate - starts timer = duration when duration is not 0.
|
||||
echo 0 > activate - cancels currently running timer.
|
||||
echo n > duration - stores timer value to be used upon next
|
||||
activate. Currently active timer if
|
||||
any, continues to run for the specified time.
|
||||
echo 0 > duration - stores timer value to be used upon next
|
||||
activate. Currently active timer if any,
|
||||
continues to run for the specified time.
|
||||
echo 1 > state - stores desired transient state LED_FULL to be
|
||||
================= ===============================================
|
||||
echo 1 > activate starts timer = duration when duration is not 0.
|
||||
echo 0 > activate cancels currently running timer.
|
||||
echo n > duration stores timer value to be used upon next
|
||||
activate. Currently active timer if
|
||||
any, continues to run for the specified time.
|
||||
echo 0 > duration stores timer value to be used upon next
|
||||
activate. Currently active timer if any,
|
||||
continues to run for the specified time.
|
||||
echo 1 > state stores desired transient state LED_FULL to be
|
||||
held for the specified duration.
|
||||
echo 0 > state - stores desired transient state LED_OFF to be
|
||||
echo 0 > state stores desired transient state LED_OFF to be
|
||||
held for the specified duration.
|
||||
================= ===============================================
|
||||
|
||||
What is not supported
|
||||
=====================
|
||||
|
||||
What is not supported:
|
||||
======================
|
||||
- Timer activation is one shot and extending and/or shortening the timer
|
||||
is not supported.
|
||||
|
||||
Example use-case 1:
|
||||
Examples
|
||||
========
|
||||
|
||||
use-case 1::
|
||||
|
||||
echo transient > trigger
|
||||
echo n > duration
|
||||
echo 1 > state
|
||||
repeat the following step as needed:
|
||||
|
||||
repeat the following step as needed::
|
||||
|
||||
echo 1 > activate - start timer = duration to run once
|
||||
echo 1 > activate - start timer = duration to run once
|
||||
echo none > trigger
|
||||
|
||||
This trigger is intended to be used for for the following example use cases:
|
||||
|
||||
- Control of vibrate (phones, tablets etc.) hardware by user space app.
|
||||
- Use of LED by user space app as activity indicator.
|
||||
- Use of LED by user space app as a kind of watchdog indicator -- as
|
||||
long as the app is alive, it can keep the LED illuminated, if it dies
|
||||
the LED will be extinguished automatically.
|
||||
long as the app is alive, it can keep the LED illuminated, if it dies
|
||||
the LED will be extinguished automatically.
|
||||
- Use by any user space app that needs a transient GPIO output.
|
@ -1,3 +1,4 @@
|
||||
====================
|
||||
USB port LED trigger
|
||||
====================
|
||||
|
||||
@ -10,14 +11,18 @@ listed as separated entries in a "ports" subdirectory. Selecting is handled by
|
||||
echoing "1" to a chosen port.
|
||||
|
||||
Please note that this trigger allows selecting multiple USB ports for a single
|
||||
LED. This can be useful in two cases:
|
||||
LED.
|
||||
|
||||
This can be useful in two cases:
|
||||
|
||||
1) Device with single USB LED and few physical ports
|
||||
====================================================
|
||||
|
||||
In such a case LED will be turned on as long as there is at least one connected
|
||||
USB device.
|
||||
|
||||
2) Device with a physical port handled by few controllers
|
||||
=========================================================
|
||||
|
||||
Some devices may have one controller per PHY standard. E.g. USB 3.0 physical
|
||||
port may be handled by ohci-platform, ehci-platform and xhci-hcd. If there is
|
||||
@ -25,14 +30,14 @@ only one LED user will most likely want to assign ports from all 3 hubs.
|
||||
|
||||
|
||||
This trigger can be activated from user space on led class devices as shown
|
||||
below:
|
||||
below::
|
||||
|
||||
echo usbport > trigger
|
||||
|
||||
This adds sysfs attributes to the LED that are documented in:
|
||||
Documentation/ABI/testing/sysfs-class-led-trigger-usbport
|
||||
|
||||
Example use-case:
|
||||
Example use-case::
|
||||
|
||||
echo usbport > trigger
|
||||
echo 1 > ports/usb1-port1
|
@ -1,3 +1,4 @@
|
||||
==============
|
||||
Userspace LEDs
|
||||
==============
|
||||
|
||||
@ -10,12 +11,12 @@ Usage
|
||||
|
||||
When the driver is loaded, a character device is created at /dev/uleds. To
|
||||
create a new LED class device, open /dev/uleds and write a uleds_user_dev
|
||||
structure to it (found in kernel public header file linux/uleds.h).
|
||||
structure to it (found in kernel public header file linux/uleds.h)::
|
||||
|
||||
#define LED_MAX_NAME_SIZE 64
|
||||
|
||||
struct uleds_user_dev {
|
||||
char name[LED_MAX_NAME_SIZE];
|
||||
char name[LED_MAX_NAME_SIZE];
|
||||
};
|
||||
|
||||
A new LED class device will be created with the name given. The name can be
|
@ -10165,7 +10165,7 @@ L: linux-leds@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/leds/leds-mlxcpld.c
|
||||
F: drivers/leds/leds-mlxreg.c
|
||||
F: Documentation/leds/leds-mlxcpld.txt
|
||||
F: Documentation/leds/leds-mlxcpld.rst
|
||||
|
||||
MELLANOX PLATFORM DRIVER
|
||||
M: Vadim Pasternak <vadimp@mellanox.com>
|
||||
|
@ -784,6 +784,41 @@ config LEDS_NIC78BX
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called leds-nic78bx.
|
||||
|
||||
config LEDS_SPI_BYTE
|
||||
tristate "LED support for SPI LED controller with a single byte"
|
||||
depends on LEDS_CLASS
|
||||
depends on SPI
|
||||
depends on OF
|
||||
help
|
||||
This option enables support for LED controller which use a single byte
|
||||
for controlling the brightness. Currently the following controller is
|
||||
supported: Ubiquiti airCube ISP microcontroller based LED controller.
|
||||
|
||||
config LEDS_TI_LMU_COMMON
|
||||
tristate "LED driver for TI LMU"
|
||||
depends on LEDS_CLASS
|
||||
depends on REGMAP
|
||||
help
|
||||
Say Y to enable the LED driver for TI LMU devices.
|
||||
This supports common features between the TI LM3532, LM3631, LM3632,
|
||||
LM3633, LM3695 and LM3697.
|
||||
|
||||
config LEDS_LM3697
|
||||
tristate "LED driver for LM3697"
|
||||
depends on LEDS_TI_LMU_COMMON
|
||||
depends on I2C && OF
|
||||
help
|
||||
Say Y to enable the LM3697 LED driver for TI LMU devices.
|
||||
This supports the LED device LM3697.
|
||||
|
||||
config LEDS_LM36274
|
||||
tristate "LED driver for LM36274"
|
||||
depends on LEDS_TI_LMU_COMMON
|
||||
depends on MFD_TI_LMU
|
||||
help
|
||||
Say Y to enable the LM36274 LED driver for TI LMU devices.
|
||||
This supports the LED device LM36274.
|
||||
|
||||
comment "LED Triggers"
|
||||
source "drivers/leds/trigger/Kconfig"
|
||||
|
||||
|
@ -77,10 +77,14 @@ obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o
|
||||
obj-$(CONFIG_LEDS_MLXCPLD) += leds-mlxcpld.o
|
||||
obj-$(CONFIG_LEDS_MLXREG) += leds-mlxreg.o
|
||||
obj-$(CONFIG_LEDS_NIC78BX) += leds-nic78bx.o
|
||||
obj-$(CONFIG_LEDS_SPI_BYTE) += leds-spi-byte.o
|
||||
obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o
|
||||
obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o
|
||||
obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o
|
||||
obj-$(CONFIG_LEDS_LM3601X) += leds-lm3601x.o
|
||||
obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o
|
||||
obj-$(CONFIG_LEDS_LM3697) += leds-lm3697.o
|
||||
obj-$(CONFIG_LEDS_LM36274) += leds-lm36274.o
|
||||
|
||||
# LED SPI Drivers
|
||||
obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o
|
||||
|
172
drivers/leds/leds-lm36274.c
Normal file
172
drivers/leds/leds-lm36274.c
Normal file
@ -0,0 +1,172 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// TI LM36274 LED chip family driver
|
||||
// Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/leds-ti-lmu-common.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/mfd/ti-lmu.h>
|
||||
#include <linux/mfd/ti-lmu-register.h>
|
||||
|
||||
#include <uapi/linux/uleds.h>
|
||||
|
||||
#define LM36274_MAX_STRINGS 4
|
||||
#define LM36274_BL_EN BIT(4)
|
||||
|
||||
/**
|
||||
* struct lm36274
|
||||
* @pdev: platform device
|
||||
* @led_dev: led class device
|
||||
* @lmu_data: Register and setting values for common code
|
||||
* @regmap: Devices register map
|
||||
* @dev: Pointer to the devices device struct
|
||||
* @led_sources - The LED strings supported in this array
|
||||
* @num_leds - Number of LED strings are supported in this array
|
||||
*/
|
||||
struct lm36274 {
|
||||
struct platform_device *pdev;
|
||||
struct led_classdev led_dev;
|
||||
struct ti_lmu_bank lmu_data;
|
||||
struct regmap *regmap;
|
||||
struct device *dev;
|
||||
|
||||
u32 led_sources[LM36274_MAX_STRINGS];
|
||||
int num_leds;
|
||||
};
|
||||
|
||||
static int lm36274_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brt_val)
|
||||
{
|
||||
struct lm36274 *led = container_of(led_cdev, struct lm36274, led_dev);
|
||||
|
||||
return ti_lmu_common_set_brightness(&led->lmu_data, brt_val);
|
||||
}
|
||||
|
||||
static int lm36274_init(struct lm36274 *lm36274_data)
|
||||
{
|
||||
int enable_val = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lm36274_data->num_leds; i++)
|
||||
enable_val |= (1 << lm36274_data->led_sources[i]);
|
||||
|
||||
if (!enable_val) {
|
||||
dev_err(lm36274_data->dev, "No LEDs were enabled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
enable_val |= LM36274_BL_EN;
|
||||
|
||||
return regmap_write(lm36274_data->regmap, LM36274_REG_BL_EN,
|
||||
enable_val);
|
||||
}
|
||||
|
||||
static int lm36274_parse_dt(struct lm36274 *lm36274_data)
|
||||
{
|
||||
struct fwnode_handle *child = NULL;
|
||||
char label[LED_MAX_NAME_SIZE];
|
||||
struct device *dev = &lm36274_data->pdev->dev;
|
||||
const char *name;
|
||||
int child_cnt;
|
||||
int ret = -EINVAL;
|
||||
|
||||
/* There should only be 1 node */
|
||||
child_cnt = device_get_child_node_count(dev);
|
||||
if (child_cnt != 1)
|
||||
return -EINVAL;
|
||||
|
||||
device_for_each_child_node(dev, child) {
|
||||
ret = fwnode_property_read_string(child, "label", &name);
|
||||
if (ret)
|
||||
snprintf(label, sizeof(label),
|
||||
"%s::", lm36274_data->pdev->name);
|
||||
else
|
||||
snprintf(label, sizeof(label),
|
||||
"%s:%s", lm36274_data->pdev->name, name);
|
||||
|
||||
lm36274_data->num_leds = fwnode_property_read_u32_array(child,
|
||||
"led-sources",
|
||||
NULL, 0);
|
||||
if (lm36274_data->num_leds <= 0)
|
||||
return -ENODEV;
|
||||
|
||||
ret = fwnode_property_read_u32_array(child, "led-sources",
|
||||
lm36274_data->led_sources,
|
||||
lm36274_data->num_leds);
|
||||
if (ret) {
|
||||
dev_err(dev, "led-sources property missing\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
fwnode_property_read_string(child, "linux,default-trigger",
|
||||
&lm36274_data->led_dev.default_trigger);
|
||||
|
||||
}
|
||||
|
||||
lm36274_data->lmu_data.regmap = lm36274_data->regmap;
|
||||
lm36274_data->lmu_data.max_brightness = MAX_BRIGHTNESS_11BIT;
|
||||
lm36274_data->lmu_data.msb_brightness_reg = LM36274_REG_BRT_MSB;
|
||||
lm36274_data->lmu_data.lsb_brightness_reg = LM36274_REG_BRT_LSB;
|
||||
|
||||
lm36274_data->led_dev.name = label;
|
||||
lm36274_data->led_dev.max_brightness = MAX_BRIGHTNESS_11BIT;
|
||||
lm36274_data->led_dev.brightness_set_blocking = lm36274_brightness_set;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm36274_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent);
|
||||
struct lm36274 *lm36274_data;
|
||||
int ret;
|
||||
|
||||
lm36274_data = devm_kzalloc(&pdev->dev, sizeof(*lm36274_data),
|
||||
GFP_KERNEL);
|
||||
if (!lm36274_data)
|
||||
return -ENOMEM;
|
||||
|
||||
lm36274_data->pdev = pdev;
|
||||
lm36274_data->dev = lmu->dev;
|
||||
lm36274_data->regmap = lmu->regmap;
|
||||
dev_set_drvdata(&pdev->dev, lm36274_data);
|
||||
|
||||
ret = lm36274_parse_dt(lm36274_data);
|
||||
if (ret) {
|
||||
dev_err(lm36274_data->dev, "Failed to parse DT node\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = lm36274_init(lm36274_data);
|
||||
if (ret) {
|
||||
dev_err(lm36274_data->dev, "Failed to init the device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_led_classdev_register(lm36274_data->dev,
|
||||
&lm36274_data->led_dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id of_lm36274_leds_match[] = {
|
||||
{ .compatible = "ti,lm36274-backlight", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_lm36274_leds_match);
|
||||
|
||||
static struct platform_driver lm36274_driver = {
|
||||
.probe = lm36274_probe,
|
||||
.driver = {
|
||||
.name = "lm36274-leds",
|
||||
},
|
||||
};
|
||||
module_platform_driver(lm36274_driver)
|
||||
|
||||
MODULE_DESCRIPTION("Texas Instruments LM36274 LED driver");
|
||||
MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
395
drivers/leds/leds-lm3697.c
Normal file
395
drivers/leds/leds-lm3697.c
Normal file
@ -0,0 +1,395 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// TI LM3697 LED chip family driver
|
||||
// Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
|
||||
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/leds-ti-lmu-common.h>
|
||||
|
||||
#define LM3697_REV 0x0
|
||||
#define LM3697_RESET 0x1
|
||||
#define LM3697_OUTPUT_CONFIG 0x10
|
||||
#define LM3697_CTRL_A_RAMP 0x11
|
||||
#define LM3697_CTRL_B_RAMP 0x12
|
||||
#define LM3697_CTRL_A_B_RT_RAMP 0x13
|
||||
#define LM3697_CTRL_A_B_RAMP_CFG 0x14
|
||||
#define LM3697_CTRL_A_B_BRT_CFG 0x16
|
||||
#define LM3697_CTRL_A_FS_CURR_CFG 0x17
|
||||
#define LM3697_CTRL_B_FS_CURR_CFG 0x18
|
||||
#define LM3697_PWM_CFG 0x1c
|
||||
#define LM3697_CTRL_A_BRT_LSB 0x20
|
||||
#define LM3697_CTRL_A_BRT_MSB 0x21
|
||||
#define LM3697_CTRL_B_BRT_LSB 0x22
|
||||
#define LM3697_CTRL_B_BRT_MSB 0x23
|
||||
#define LM3697_CTRL_ENABLE 0x24
|
||||
|
||||
#define LM3697_SW_RESET BIT(0)
|
||||
|
||||
#define LM3697_CTRL_A_EN BIT(0)
|
||||
#define LM3697_CTRL_B_EN BIT(1)
|
||||
#define LM3697_CTRL_A_B_EN (LM3697_CTRL_A_EN | LM3697_CTRL_B_EN)
|
||||
|
||||
#define LM3697_MAX_LED_STRINGS 3
|
||||
|
||||
#define LM3697_CONTROL_A 0
|
||||
#define LM3697_CONTROL_B 1
|
||||
#define LM3697_MAX_CONTROL_BANKS 2
|
||||
|
||||
/**
|
||||
* struct lm3697_led -
|
||||
* @hvled_strings: Array of LED strings associated with a control bank
|
||||
* @label: LED label
|
||||
* @led_dev: LED class device
|
||||
* @priv: Pointer to the device struct
|
||||
* @lmu_data: Register and setting values for common code
|
||||
* @control_bank: Control bank the LED is associated to. 0 is control bank A
|
||||
* 1 is control bank B
|
||||
*/
|
||||
struct lm3697_led {
|
||||
u32 hvled_strings[LM3697_MAX_LED_STRINGS];
|
||||
char label[LED_MAX_NAME_SIZE];
|
||||
struct led_classdev led_dev;
|
||||
struct lm3697 *priv;
|
||||
struct ti_lmu_bank lmu_data;
|
||||
int control_bank;
|
||||
int enabled;
|
||||
int num_leds;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct lm3697 -
|
||||
* @enable_gpio: Hardware enable gpio
|
||||
* @regulator: LED supply regulator pointer
|
||||
* @client: Pointer to the I2C client
|
||||
* @regmap: Devices register map
|
||||
* @dev: Pointer to the devices device struct
|
||||
* @lock: Lock for reading/writing the device
|
||||
* @leds: Array of LED strings
|
||||
*/
|
||||
struct lm3697 {
|
||||
struct gpio_desc *enable_gpio;
|
||||
struct regulator *regulator;
|
||||
struct i2c_client *client;
|
||||
struct regmap *regmap;
|
||||
struct device *dev;
|
||||
struct mutex lock;
|
||||
|
||||
int bank_cfg;
|
||||
|
||||
struct lm3697_led leds[];
|
||||
};
|
||||
|
||||
static const struct reg_default lm3697_reg_defs[] = {
|
||||
{LM3697_OUTPUT_CONFIG, 0x6},
|
||||
{LM3697_CTRL_A_RAMP, 0x0},
|
||||
{LM3697_CTRL_B_RAMP, 0x0},
|
||||
{LM3697_CTRL_A_B_RT_RAMP, 0x0},
|
||||
{LM3697_CTRL_A_B_RAMP_CFG, 0x0},
|
||||
{LM3697_CTRL_A_B_BRT_CFG, 0x0},
|
||||
{LM3697_CTRL_A_FS_CURR_CFG, 0x13},
|
||||
{LM3697_CTRL_B_FS_CURR_CFG, 0x13},
|
||||
{LM3697_PWM_CFG, 0xc},
|
||||
{LM3697_CTRL_A_BRT_LSB, 0x0},
|
||||
{LM3697_CTRL_A_BRT_MSB, 0x0},
|
||||
{LM3697_CTRL_B_BRT_LSB, 0x0},
|
||||
{LM3697_CTRL_B_BRT_MSB, 0x0},
|
||||
{LM3697_CTRL_ENABLE, 0x0},
|
||||
};
|
||||
|
||||
static const struct regmap_config lm3697_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = LM3697_CTRL_ENABLE,
|
||||
.reg_defaults = lm3697_reg_defs,
|
||||
.num_reg_defaults = ARRAY_SIZE(lm3697_reg_defs),
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static int lm3697_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brt_val)
|
||||
{
|
||||
struct lm3697_led *led = container_of(led_cdev, struct lm3697_led,
|
||||
led_dev);
|
||||
int ctrl_en_val = (1 << led->control_bank);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&led->priv->lock);
|
||||
|
||||
if (brt_val == LED_OFF) {
|
||||
ret = regmap_update_bits(led->priv->regmap, LM3697_CTRL_ENABLE,
|
||||
ctrl_en_val, ~ctrl_en_val);
|
||||
if (ret) {
|
||||
dev_err(&led->priv->client->dev, "Cannot write ctrl register\n");
|
||||
goto brightness_out;
|
||||
}
|
||||
|
||||
led->enabled = LED_OFF;
|
||||
} else {
|
||||
ret = ti_lmu_common_set_brightness(&led->lmu_data, brt_val);
|
||||
if (ret) {
|
||||
dev_err(&led->priv->client->dev,
|
||||
"Cannot write brightness\n");
|
||||
goto brightness_out;
|
||||
}
|
||||
|
||||
if (!led->enabled) {
|
||||
ret = regmap_update_bits(led->priv->regmap,
|
||||
LM3697_CTRL_ENABLE,
|
||||
ctrl_en_val, ctrl_en_val);
|
||||
if (ret) {
|
||||
dev_err(&led->priv->client->dev,
|
||||
"Cannot enable the device\n");
|
||||
goto brightness_out;
|
||||
}
|
||||
|
||||
led->enabled = brt_val;
|
||||
}
|
||||
}
|
||||
|
||||
brightness_out:
|
||||
mutex_unlock(&led->priv->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lm3697_init(struct lm3697 *priv)
|
||||
{
|
||||
struct lm3697_led *led;
|
||||
int i, ret;
|
||||
|
||||
if (priv->enable_gpio) {
|
||||
gpiod_direction_output(priv->enable_gpio, 1);
|
||||
} else {
|
||||
ret = regmap_write(priv->regmap, LM3697_RESET, LM3697_SW_RESET);
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev, "Cannot reset the device\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_write(priv->regmap, LM3697_CTRL_ENABLE, 0x0);
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev, "Cannot write ctrl enable\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = regmap_write(priv->regmap, LM3697_OUTPUT_CONFIG, priv->bank_cfg);
|
||||
if (ret)
|
||||
dev_err(&priv->client->dev, "Cannot write OUTPUT config\n");
|
||||
|
||||
for (i = 0; i < LM3697_MAX_CONTROL_BANKS; i++) {
|
||||
led = &priv->leds[i];
|
||||
ret = ti_lmu_common_set_ramp(&led->lmu_data);
|
||||
if (ret)
|
||||
dev_err(&priv->client->dev, "Setting the ramp rate failed\n");
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lm3697_probe_dt(struct lm3697 *priv)
|
||||
{
|
||||
struct fwnode_handle *child = NULL;
|
||||
struct lm3697_led *led;
|
||||
const char *name;
|
||||
int control_bank;
|
||||
size_t i = 0;
|
||||
int ret = -EINVAL;
|
||||
int j;
|
||||
|
||||
priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
|
||||
"enable", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(priv->enable_gpio)) {
|
||||
ret = PTR_ERR(priv->enable_gpio);
|
||||
dev_err(&priv->client->dev, "Failed to get enable gpio: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->regulator = devm_regulator_get(&priv->client->dev, "vled");
|
||||
if (IS_ERR(priv->regulator))
|
||||
priv->regulator = NULL;
|
||||
|
||||
device_for_each_child_node(priv->dev, child) {
|
||||
ret = fwnode_property_read_u32(child, "reg", &control_bank);
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev, "reg property missing\n");
|
||||
fwnode_handle_put(child);
|
||||
goto child_out;
|
||||
}
|
||||
|
||||
if (control_bank > LM3697_CONTROL_B) {
|
||||
dev_err(&priv->client->dev, "reg property is invalid\n");
|
||||
ret = -EINVAL;
|
||||
fwnode_handle_put(child);
|
||||
goto child_out;
|
||||
}
|
||||
|
||||
led = &priv->leds[i];
|
||||
|
||||
ret = ti_lmu_common_get_brt_res(&priv->client->dev,
|
||||
child, &led->lmu_data);
|
||||
if (ret)
|
||||
dev_warn(&priv->client->dev, "brightness resolution property missing\n");
|
||||
|
||||
led->control_bank = control_bank;
|
||||
led->lmu_data.regmap = priv->regmap;
|
||||
led->lmu_data.runtime_ramp_reg = LM3697_CTRL_A_RAMP +
|
||||
control_bank;
|
||||
led->lmu_data.msb_brightness_reg = LM3697_CTRL_A_BRT_MSB +
|
||||
led->control_bank * 2;
|
||||
led->lmu_data.lsb_brightness_reg = LM3697_CTRL_A_BRT_LSB +
|
||||
led->control_bank * 2;
|
||||
|
||||
led->num_leds = fwnode_property_read_u32_array(child,
|
||||
"led-sources",
|
||||
NULL, 0);
|
||||
|
||||
if (led->num_leds > LM3697_MAX_LED_STRINGS) {
|
||||
dev_err(&priv->client->dev, "To many LED strings defined\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = fwnode_property_read_u32_array(child, "led-sources",
|
||||
led->hvled_strings,
|
||||
led->num_leds);
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev, "led-sources property missing\n");
|
||||
fwnode_handle_put(child);
|
||||
goto child_out;
|
||||
}
|
||||
|
||||
for (j = 0; j < led->num_leds; j++)
|
||||
priv->bank_cfg |=
|
||||
(led->control_bank << led->hvled_strings[j]);
|
||||
|
||||
ret = ti_lmu_common_get_ramp_params(&priv->client->dev,
|
||||
child, &led->lmu_data);
|
||||
if (ret)
|
||||
dev_warn(&priv->client->dev, "runtime-ramp properties missing\n");
|
||||
|
||||
fwnode_property_read_string(child, "linux,default-trigger",
|
||||
&led->led_dev.default_trigger);
|
||||
|
||||
ret = fwnode_property_read_string(child, "label", &name);
|
||||
if (ret)
|
||||
snprintf(led->label, sizeof(led->label),
|
||||
"%s::", priv->client->name);
|
||||
else
|
||||
snprintf(led->label, sizeof(led->label),
|
||||
"%s:%s", priv->client->name, name);
|
||||
|
||||
led->priv = priv;
|
||||
led->led_dev.name = led->label;
|
||||
led->led_dev.max_brightness = led->lmu_data.max_brightness;
|
||||
led->led_dev.brightness_set_blocking = lm3697_brightness_set;
|
||||
|
||||
ret = devm_led_classdev_register(priv->dev, &led->led_dev);
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev, "led register err: %d\n",
|
||||
ret);
|
||||
fwnode_handle_put(child);
|
||||
goto child_out;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
child_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lm3697_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct lm3697 *led;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
count = device_get_child_node_count(&client->dev);
|
||||
if (!count) {
|
||||
dev_err(&client->dev, "LEDs are not defined in device tree!");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
led = devm_kzalloc(&client->dev, struct_size(led, leds, count),
|
||||
GFP_KERNEL);
|
||||
if (!led)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&led->lock);
|
||||
i2c_set_clientdata(client, led);
|
||||
|
||||
led->client = client;
|
||||
led->dev = &client->dev;
|
||||
led->regmap = devm_regmap_init_i2c(client, &lm3697_regmap_config);
|
||||
if (IS_ERR(led->regmap)) {
|
||||
ret = PTR_ERR(led->regmap);
|
||||
dev_err(&client->dev, "Failed to allocate register map: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = lm3697_probe_dt(led);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return lm3697_init(led);
|
||||
}
|
||||
|
||||
static int lm3697_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lm3697 *led = i2c_get_clientdata(client);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(led->regmap, LM3697_CTRL_ENABLE,
|
||||
LM3697_CTRL_A_B_EN, 0);
|
||||
if (ret) {
|
||||
dev_err(&led->client->dev, "Failed to disable the device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (led->enable_gpio)
|
||||
gpiod_direction_output(led->enable_gpio, 0);
|
||||
|
||||
if (led->regulator) {
|
||||
ret = regulator_disable(led->regulator);
|
||||
if (ret)
|
||||
dev_err(&led->client->dev,
|
||||
"Failed to disable regulator\n");
|
||||
}
|
||||
|
||||
mutex_destroy(&led->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id lm3697_id[] = {
|
||||
{ "lm3697", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, lm3697_id);
|
||||
|
||||
static const struct of_device_id of_lm3697_leds_match[] = {
|
||||
{ .compatible = "ti,lm3697", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_lm3697_leds_match);
|
||||
|
||||
static struct i2c_driver lm3697_driver = {
|
||||
.driver = {
|
||||
.name = "lm3697",
|
||||
.of_match_table = of_lm3697_leds_match,
|
||||
},
|
||||
.probe = lm3697_probe,
|
||||
.remove = lm3697_remove,
|
||||
.id_table = lm3697_id,
|
||||
};
|
||||
module_i2c_driver(lm3697_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Texas Instruments LM3697 LED driver");
|
||||
MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -64,7 +64,6 @@ static int max77650_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *of_node, *child;
|
||||
struct max77650_led *leds, *led;
|
||||
struct device *parent;
|
||||
struct device *dev;
|
||||
struct regmap *map;
|
||||
const char *label;
|
||||
@ -72,7 +71,6 @@ static int max77650_led_probe(struct platform_device *pdev)
|
||||
u32 reg;
|
||||
|
||||
dev = &pdev->dev;
|
||||
parent = dev->parent;
|
||||
of_node = dev->of_node;
|
||||
|
||||
if (!of_node)
|
||||
|
@ -429,7 +429,7 @@ static int pca955x_probe(struct i2c_client *client,
|
||||
int ngpios = 0;
|
||||
|
||||
chip = &pca955x_chipdefs[id->driver_data];
|
||||
adapter = to_i2c_adapter(client->dev.parent);
|
||||
adapter = client->adapter;
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
if (!pdata) {
|
||||
pdata = pca955x_get_pdata(client, chip);
|
||||
|
161
drivers/leds/leds-spi-byte.c
Normal file
161
drivers/leds/leds-spi-byte.c
Normal file
@ -0,0 +1,161 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2019 Christian Mauderer <oss@c-mauderer.de>
|
||||
|
||||
/*
|
||||
* The driver supports controllers with a very simple SPI protocol:
|
||||
* - one LED is controlled by a single byte on MOSI
|
||||
* - the value of the byte gives the brightness between two values (lowest to
|
||||
* highest)
|
||||
* - no return value is necessary (no MISO signal)
|
||||
*
|
||||
* The value for minimum and maximum brightness depends on the device
|
||||
* (compatible string).
|
||||
*
|
||||
* Supported devices:
|
||||
* - "ubnt,acb-spi-led": Microcontroller (SONiX 8F26E611LA) based device used
|
||||
* for example in Ubiquiti airCube ISP. Reverse engineered protocol for this
|
||||
* controller:
|
||||
* * Higher two bits set a mode. Lower six bits are a parameter.
|
||||
* * Mode: 00 -> set brightness between 0x00 (min) and 0x3F (max)
|
||||
* * Mode: 01 -> pulsing pattern (min -> max -> min) with an interval. From
|
||||
* some tests, the period is about (50ms + 102ms * parameter). There is a
|
||||
* slightly different pattern starting from 0x10 (longer gap between the
|
||||
* pulses) but the time still follows that calculation.
|
||||
* * Mode: 10 -> same as 01 but with only a ramp from min to max. Again a
|
||||
* slight jump in the pattern at 0x10.
|
||||
* * Mode: 11 -> blinking (off -> 25% -> off -> 25% -> ...) with a period of
|
||||
* (105ms * parameter)
|
||||
* NOTE: This driver currently only supports mode 00.
|
||||
*/
|
||||
|
||||
#include <linux/leds.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <uapi/linux/uleds.h>
|
||||
|
||||
struct spi_byte_chipdef {
|
||||
/* SPI byte that will be send to switch the LED off */
|
||||
u8 off_value;
|
||||
/* SPI byte that will be send to switch the LED to maximum brightness */
|
||||
u8 max_value;
|
||||
};
|
||||
|
||||
struct spi_byte_led {
|
||||
struct led_classdev ldev;
|
||||
struct spi_device *spi;
|
||||
char name[LED_MAX_NAME_SIZE];
|
||||
struct mutex mutex;
|
||||
const struct spi_byte_chipdef *cdef;
|
||||
};
|
||||
|
||||
static const struct spi_byte_chipdef ubnt_acb_spi_led_cdef = {
|
||||
.off_value = 0x0,
|
||||
.max_value = 0x3F,
|
||||
};
|
||||
|
||||
static const struct of_device_id spi_byte_dt_ids[] = {
|
||||
{ .compatible = "ubnt,acb-spi-led", .data = &ubnt_acb_spi_led_cdef },
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, spi_byte_dt_ids);
|
||||
|
||||
static int spi_byte_brightness_set_blocking(struct led_classdev *dev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct spi_byte_led *led = container_of(dev, struct spi_byte_led, ldev);
|
||||
u8 value;
|
||||
int ret;
|
||||
|
||||
value = (u8) brightness + led->cdef->off_value;
|
||||
|
||||
mutex_lock(&led->mutex);
|
||||
ret = spi_write(led->spi, &value, sizeof(value));
|
||||
mutex_unlock(&led->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spi_byte_probe(struct spi_device *spi)
|
||||
{
|
||||
const struct of_device_id *of_dev_id;
|
||||
struct device_node *child;
|
||||
struct device *dev = &spi->dev;
|
||||
struct spi_byte_led *led;
|
||||
const char *name = "leds-spi-byte::";
|
||||
const char *state;
|
||||
int ret;
|
||||
|
||||
of_dev_id = of_match_device(spi_byte_dt_ids, dev);
|
||||
if (!of_dev_id)
|
||||
return -EINVAL;
|
||||
|
||||
if (of_get_child_count(dev->of_node) != 1) {
|
||||
dev_err(dev, "Device must have exactly one LED sub-node.");
|
||||
return -EINVAL;
|
||||
}
|
||||
child = of_get_next_child(dev->of_node, NULL);
|
||||
|
||||
led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
|
||||
if (!led)
|
||||
return -ENOMEM;
|
||||
|
||||
of_property_read_string(child, "label", &name);
|
||||
strlcpy(led->name, name, sizeof(led->name));
|
||||
led->spi = spi;
|
||||
mutex_init(&led->mutex);
|
||||
led->cdef = of_dev_id->data;
|
||||
led->ldev.name = led->name;
|
||||
led->ldev.brightness = LED_OFF;
|
||||
led->ldev.max_brightness = led->cdef->max_value - led->cdef->off_value;
|
||||
led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
|
||||
|
||||
state = of_get_property(child, "default-state", NULL);
|
||||
if (state) {
|
||||
if (!strcmp(state, "on")) {
|
||||
led->ldev.brightness = led->ldev.max_brightness;
|
||||
} else if (strcmp(state, "off")) {
|
||||
/* all other cases except "off" */
|
||||
dev_err(dev, "default-state can only be 'on' or 'off'");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
spi_byte_brightness_set_blocking(&led->ldev,
|
||||
led->ldev.brightness);
|
||||
|
||||
ret = devm_led_classdev_register(&spi->dev, &led->ldev);
|
||||
if (ret) {
|
||||
mutex_destroy(&led->mutex);
|
||||
return ret;
|
||||
}
|
||||
spi_set_drvdata(spi, led);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_byte_remove(struct spi_device *spi)
|
||||
{
|
||||
struct spi_byte_led *led = spi_get_drvdata(spi);
|
||||
|
||||
mutex_destroy(&led->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver spi_byte_driver = {
|
||||
.probe = spi_byte_probe,
|
||||
.remove = spi_byte_remove,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.of_match_table = spi_byte_dt_ids,
|
||||
},
|
||||
};
|
||||
|
||||
module_spi_driver(spi_byte_driver);
|
||||
|
||||
MODULE_AUTHOR("Christian Mauderer <oss@c-mauderer.de>");
|
||||
MODULE_DESCRIPTION("single byte SPI LED driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("spi:leds-spi-byte");
|
@ -758,7 +758,7 @@ static int tca6507_probe(struct i2c_client *client,
|
||||
int err;
|
||||
int i = 0;
|
||||
|
||||
adapter = to_i2c_adapter(client->dev.parent);
|
||||
adapter = client->adapter;
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
|
||||
|
156
drivers/leds/leds-ti-lmu-common.c
Normal file
156
drivers/leds/leds-ti-lmu-common.c
Normal file
@ -0,0 +1,156 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright 2015 Texas Instruments
|
||||
// Copyright 2018 Sebastian Reichel
|
||||
// Copyright 2018 Pavel Machek <pavel@ucw.cz>
|
||||
// TI LMU LED common framework, based on previous work from
|
||||
// Milo Kim <milo.kim@ti.com>
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <linux/leds-ti-lmu-common.h>
|
||||
|
||||
const static int ramp_table[16] = {2048, 262000, 524000, 1049000, 2090000,
|
||||
4194000, 8389000, 16780000, 33550000, 41940000,
|
||||
50330000, 58720000, 67110000, 83880000,
|
||||
100660000, 117440000};
|
||||
|
||||
static int ti_lmu_common_update_brightness(struct ti_lmu_bank *lmu_bank,
|
||||
int brightness)
|
||||
{
|
||||
struct regmap *regmap = lmu_bank->regmap;
|
||||
u8 reg, val;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Brightness register update
|
||||
*
|
||||
* 11 bit dimming: update LSB bits and write MSB byte.
|
||||
* MSB brightness should be shifted.
|
||||
* 8 bit dimming: write MSB byte.
|
||||
*/
|
||||
if (lmu_bank->max_brightness == MAX_BRIGHTNESS_11BIT) {
|
||||
reg = lmu_bank->lsb_brightness_reg;
|
||||
ret = regmap_update_bits(regmap, reg,
|
||||
LMU_11BIT_LSB_MASK,
|
||||
brightness);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val = brightness >> LMU_11BIT_MSB_SHIFT;
|
||||
} else {
|
||||
val = brightness;
|
||||
}
|
||||
|
||||
reg = lmu_bank->msb_brightness_reg;
|
||||
|
||||
return regmap_write(regmap, reg, val);
|
||||
}
|
||||
|
||||
int ti_lmu_common_set_brightness(struct ti_lmu_bank *lmu_bank, int brightness)
|
||||
{
|
||||
return ti_lmu_common_update_brightness(lmu_bank, brightness);
|
||||
}
|
||||
EXPORT_SYMBOL(ti_lmu_common_set_brightness);
|
||||
|
||||
static int ti_lmu_common_convert_ramp_to_index(unsigned int usec)
|
||||
{
|
||||
int size = ARRAY_SIZE(ramp_table);
|
||||
int i;
|
||||
|
||||
if (usec <= ramp_table[0])
|
||||
return 0;
|
||||
|
||||
if (usec > ramp_table[size - 1])
|
||||
return size - 1;
|
||||
|
||||
for (i = 1; i < size; i++) {
|
||||
if (usec == ramp_table[i])
|
||||
return i;
|
||||
|
||||
/* Find an approximate index by looking up the table */
|
||||
if (usec > ramp_table[i - 1] && usec < ramp_table[i]) {
|
||||
if (usec - ramp_table[i - 1] < ramp_table[i] - usec)
|
||||
return i - 1;
|
||||
else
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int ti_lmu_common_set_ramp(struct ti_lmu_bank *lmu_bank)
|
||||
{
|
||||
struct regmap *regmap = lmu_bank->regmap;
|
||||
u8 ramp, ramp_up, ramp_down;
|
||||
|
||||
if (lmu_bank->ramp_up_usec == 0 && lmu_bank->ramp_down_usec == 0) {
|
||||
ramp_up = 0;
|
||||
ramp_down = 0;
|
||||
} else {
|
||||
ramp_up = ti_lmu_common_convert_ramp_to_index(lmu_bank->ramp_up_usec);
|
||||
ramp_down = ti_lmu_common_convert_ramp_to_index(lmu_bank->ramp_down_usec);
|
||||
}
|
||||
|
||||
if (ramp_up < 0 || ramp_down < 0)
|
||||
return -EINVAL;
|
||||
|
||||
ramp = (ramp_up << 4) | ramp_down;
|
||||
|
||||
return regmap_write(regmap, lmu_bank->runtime_ramp_reg, ramp);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(ti_lmu_common_set_ramp);
|
||||
|
||||
int ti_lmu_common_get_ramp_params(struct device *dev,
|
||||
struct fwnode_handle *child,
|
||||
struct ti_lmu_bank *lmu_data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = fwnode_property_read_u32(child, "ramp-up-us",
|
||||
&lmu_data->ramp_up_usec);
|
||||
if (ret)
|
||||
dev_warn(dev, "ramp-up-us property missing\n");
|
||||
|
||||
|
||||
ret = fwnode_property_read_u32(child, "ramp-down-us",
|
||||
&lmu_data->ramp_down_usec);
|
||||
if (ret)
|
||||
dev_warn(dev, "ramp-down-us property missing\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ti_lmu_common_get_ramp_params);
|
||||
|
||||
int ti_lmu_common_get_brt_res(struct device *dev, struct fwnode_handle *child,
|
||||
struct ti_lmu_bank *lmu_data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = device_property_read_u32(dev, "ti,brightness-resolution",
|
||||
&lmu_data->max_brightness);
|
||||
if (ret)
|
||||
ret = fwnode_property_read_u32(child,
|
||||
"ti,brightness-resolution",
|
||||
&lmu_data->max_brightness);
|
||||
if (lmu_data->max_brightness <= 0) {
|
||||
lmu_data->max_brightness = MAX_BRIGHTNESS_8BIT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (lmu_data->max_brightness > MAX_BRIGHTNESS_11BIT)
|
||||
lmu_data->max_brightness = MAX_BRIGHTNESS_11BIT;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ti_lmu_common_get_brt_res);
|
||||
|
||||
MODULE_DESCRIPTION("TI LMU common LED framework");
|
||||
MODULE_AUTHOR("Sebastian Reichel");
|
||||
MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("ti-lmu-led-common");
|
@ -15,7 +15,7 @@ config LEDS_TRIGGER_TIMER
|
||||
This allows LEDs to be controlled by a programmable timer
|
||||
via sysfs. Some LED hardware can be programmed to start
|
||||
blinking the LED without any further software interaction.
|
||||
For more details read Documentation/leds/leds-class.txt.
|
||||
For more details read Documentation/leds/leds-class.rst.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// LED Kernel Transient Trigger
|
||||
//
|
||||
// Transient trigger allows one shot timer activation. Please refer to
|
||||
// Documentation/leds/ledtrig-transient.txt for details
|
||||
// Documentation/leds/ledtrig-transient.rst for details
|
||||
// Copyright (C) 2012 Shuah Khan <shuahkhan@gmail.com>
|
||||
//
|
||||
// Based on Richard Purdie's ledtrig-timer.c and Atsushi Nemoto's
|
||||
|
@ -1336,9 +1336,8 @@ config MFD_TI_LMU
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say yes here to enable support for TI LMU chips.
|
||||
|
||||
TI LMU MFD supports LM3532, LM3631, LM3632, LM3633, LM3695 and LM3697.
|
||||
It consists of backlight, LED and regulator driver.
|
||||
TI LMU MFD supports LM3532, LM3631, LM3632, LM3633, LM3695 and
|
||||
LM36274. It consists of backlight, LED and regulator driver.
|
||||
It provides consistent device controls for lighting functions.
|
||||
|
||||
config MFD_OMAP_USB_HOST
|
||||
|
@ -108,17 +108,14 @@ static const struct mfd_cell lm3695_devices[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell lm3697_devices[] = {
|
||||
static const struct mfd_cell lm36274_devices[] = {
|
||||
LM363X_REGULATOR(LM36274_BOOST),
|
||||
LM363X_REGULATOR(LM36274_LDO_POS),
|
||||
LM363X_REGULATOR(LM36274_LDO_NEG),
|
||||
{
|
||||
.name = "ti-lmu-backlight",
|
||||
.id = LM3697,
|
||||
.of_compatible = "ti,lm3697-backlight",
|
||||
},
|
||||
/* Monitoring driver for open/short circuit detection */
|
||||
{
|
||||
.name = "ti-lmu-fault-monitor",
|
||||
.id = LM3697,
|
||||
.of_compatible = "ti,lm3697-fault-monitor",
|
||||
.name = "lm36274-leds",
|
||||
.id = LM36274,
|
||||
.of_compatible = "ti,lm36274-backlight",
|
||||
},
|
||||
};
|
||||
|
||||
@ -134,7 +131,7 @@ TI_LMU_DATA(lm3631, LM3631_MAX_REG);
|
||||
TI_LMU_DATA(lm3632, LM3632_MAX_REG);
|
||||
TI_LMU_DATA(lm3633, LM3633_MAX_REG);
|
||||
TI_LMU_DATA(lm3695, LM3695_MAX_REG);
|
||||
TI_LMU_DATA(lm3697, LM3697_MAX_REG);
|
||||
TI_LMU_DATA(lm36274, LM36274_MAX_REG);
|
||||
|
||||
static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
||||
{
|
||||
@ -203,7 +200,7 @@ static const struct of_device_id ti_lmu_of_match[] = {
|
||||
{ .compatible = "ti,lm3632", .data = &lm3632_data },
|
||||
{ .compatible = "ti,lm3633", .data = &lm3633_data },
|
||||
{ .compatible = "ti,lm3695", .data = &lm3695_data },
|
||||
{ .compatible = "ti,lm3697", .data = &lm3697_data },
|
||||
{ .compatible = "ti,lm36274", .data = &lm36274_data },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ti_lmu_of_match);
|
||||
@ -213,7 +210,7 @@ static const struct i2c_device_id ti_lmu_ids[] = {
|
||||
{ "lm3632", LM3632 },
|
||||
{ "lm3633", LM3633 },
|
||||
{ "lm3695", LM3695 },
|
||||
{ "lm3697", LM3697 },
|
||||
{ "lm36274", LM36274 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ti_lmu_ids);
|
||||
|
@ -364,7 +364,7 @@ config REGULATOR_LM363X
|
||||
tristate "TI LM363X voltage regulators"
|
||||
depends on MFD_TI_LMU
|
||||
help
|
||||
This driver supports LM3631 and LM3632 voltage regulators for
|
||||
This driver supports LM3631, LM3632 and LM36274 voltage regulators for
|
||||
the LCD bias.
|
||||
One boost output voltage is configurable and always on.
|
||||
Other LDOs are used for the display module.
|
||||
|
@ -34,6 +34,11 @@
|
||||
#define LM3632_VBOOST_MIN 4500000
|
||||
#define LM3632_VLDO_MIN 4000000
|
||||
|
||||
/* LM36274 */
|
||||
#define LM36274_BOOST_VSEL_MAX 0x3f
|
||||
#define LM36274_LDO_VSEL_MAX 0x34
|
||||
#define LM36274_VOLTAGE_MIN 4000000
|
||||
|
||||
/* Common */
|
||||
#define LM363X_STEP_50mV 50000
|
||||
#define LM363X_STEP_500mV 500000
|
||||
@ -214,6 +219,51 @@ static const struct regulator_desc lm363x_regulator_desc[] = {
|
||||
.enable_reg = LM3632_REG_BIAS_CONFIG,
|
||||
.enable_mask = LM3632_EN_VNEG_MASK,
|
||||
},
|
||||
|
||||
/* LM36274 */
|
||||
{
|
||||
.name = "vboost",
|
||||
.of_match = "vboost",
|
||||
.id = LM36274_BOOST,
|
||||
.ops = &lm363x_boost_voltage_table_ops,
|
||||
.n_voltages = LM36274_BOOST_VSEL_MAX,
|
||||
.min_uV = LM36274_VOLTAGE_MIN,
|
||||
.uV_step = LM363X_STEP_50mV,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.vsel_reg = LM36274_REG_VOUT_BOOST,
|
||||
.vsel_mask = LM36274_VOUT_MASK,
|
||||
},
|
||||
{
|
||||
.name = "ldo_vpos",
|
||||
.of_match = "vpos",
|
||||
.id = LM36274_LDO_POS,
|
||||
.ops = &lm363x_regulator_voltage_table_ops,
|
||||
.n_voltages = LM36274_LDO_VSEL_MAX,
|
||||
.min_uV = LM36274_VOLTAGE_MIN,
|
||||
.uV_step = LM363X_STEP_50mV,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.vsel_reg = LM36274_REG_VOUT_POS,
|
||||
.vsel_mask = LM36274_VOUT_MASK,
|
||||
.enable_reg = LM36274_REG_BIAS_CONFIG_1,
|
||||
.enable_mask = LM36274_EN_VPOS_MASK,
|
||||
},
|
||||
{
|
||||
.name = "ldo_vneg",
|
||||
.of_match = "vneg",
|
||||
.id = LM36274_LDO_NEG,
|
||||
.ops = &lm363x_regulator_voltage_table_ops,
|
||||
.n_voltages = LM36274_LDO_VSEL_MAX,
|
||||
.min_uV = LM36274_VOLTAGE_MIN,
|
||||
.uV_step = LM363X_STEP_50mV,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.vsel_reg = LM36274_REG_VOUT_NEG,
|
||||
.vsel_mask = LM36274_VOUT_MASK,
|
||||
.enable_reg = LM36274_REG_BIAS_CONFIG_1,
|
||||
.enable_mask = LM36274_EN_VNEG_MASK,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_desc *lm363x_regulator_of_get_enable_gpio(struct device *dev, int id)
|
||||
@ -226,9 +276,11 @@ static struct gpio_desc *lm363x_regulator_of_get_enable_gpio(struct device *dev,
|
||||
*/
|
||||
switch (id) {
|
||||
case LM3632_LDO_POS:
|
||||
case LM36274_LDO_POS:
|
||||
return gpiod_get_index_optional(dev, "enable", 0,
|
||||
GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
|
||||
case LM3632_LDO_NEG:
|
||||
case LM36274_LDO_NEG:
|
||||
return gpiod_get_index_optional(dev, "enable", 1,
|
||||
GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
|
||||
default:
|
||||
@ -236,6 +288,27 @@ static struct gpio_desc *lm363x_regulator_of_get_enable_gpio(struct device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
static int lm363x_regulator_set_ext_en(struct regmap *regmap, int id)
|
||||
{
|
||||
int ext_en_mask = 0;
|
||||
|
||||
switch (id) {
|
||||
case LM3632_LDO_POS:
|
||||
case LM3632_LDO_NEG:
|
||||
ext_en_mask = LM3632_EXT_EN_MASK;
|
||||
break;
|
||||
case LM36274_LDO_POS:
|
||||
case LM36274_LDO_NEG:
|
||||
ext_en_mask = LM36274_EXT_EN_MASK;
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return regmap_update_bits(regmap, lm363x_regulator_desc[id].enable_reg,
|
||||
ext_en_mask, ext_en_mask);
|
||||
}
|
||||
|
||||
static int lm363x_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent);
|
||||
@ -260,10 +333,7 @@ static int lm363x_regulator_probe(struct platform_device *pdev)
|
||||
|
||||
if (gpiod) {
|
||||
cfg.ena_gpiod = gpiod;
|
||||
|
||||
ret = regmap_update_bits(regmap, LM3632_REG_BIAS_CONFIG,
|
||||
LM3632_EXT_EN_MASK,
|
||||
LM3632_EXT_EN_MASK);
|
||||
ret = lm363x_regulator_set_ext_en(regmap, id);
|
||||
if (ret) {
|
||||
gpiod_put(gpiod);
|
||||
dev_err(dev, "External pin err: %d\n", ret);
|
||||
|
47
include/linux/leds-ti-lmu-common.h
Normal file
47
include/linux/leds-ti-lmu-common.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
// TI LMU Common Core
|
||||
// Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
|
||||
|
||||
#ifndef _TI_LMU_COMMON_H_
|
||||
#define _TI_LMU_COMMON_H_
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <uapi/linux/uleds.h>
|
||||
|
||||
#define LMU_11BIT_LSB_MASK (BIT(0) | BIT(1) | BIT(2))
|
||||
#define LMU_11BIT_MSB_SHIFT 3
|
||||
|
||||
#define MAX_BRIGHTNESS_8BIT 255
|
||||
#define MAX_BRIGHTNESS_11BIT 2047
|
||||
|
||||
struct ti_lmu_bank {
|
||||
struct regmap *regmap;
|
||||
|
||||
int max_brightness;
|
||||
|
||||
u8 lsb_brightness_reg;
|
||||
u8 msb_brightness_reg;
|
||||
|
||||
u8 runtime_ramp_reg;
|
||||
u32 ramp_up_usec;
|
||||
u32 ramp_down_usec;
|
||||
};
|
||||
|
||||
int ti_lmu_common_set_brightness(struct ti_lmu_bank *lmu_bank, int brightness);
|
||||
|
||||
int ti_lmu_common_set_ramp(struct ti_lmu_bank *lmu_bank);
|
||||
|
||||
int ti_lmu_common_get_ramp_params(struct device *dev,
|
||||
struct fwnode_handle *child,
|
||||
struct ti_lmu_bank *lmu_data);
|
||||
|
||||
int ti_lmu_common_get_brt_res(struct device *dev, struct fwnode_handle *child,
|
||||
struct ti_lmu_bank *lmu_data);
|
||||
|
||||
#endif /* _TI_LMU_COMMON_H_ */
|
@ -187,47 +187,26 @@
|
||||
|
||||
#define LM3695_MAX_REG 0x14
|
||||
|
||||
/* LM3697 */
|
||||
#define LM3697_REG_HVLED_OUTPUT_CFG 0x10
|
||||
#define LM3697_HVLED1_CFG_MASK BIT(0)
|
||||
#define LM3697_HVLED2_CFG_MASK BIT(1)
|
||||
#define LM3697_HVLED3_CFG_MASK BIT(2)
|
||||
#define LM3697_HVLED1_CFG_SHIFT 0
|
||||
#define LM3697_HVLED2_CFG_SHIFT 1
|
||||
#define LM3697_HVLED3_CFG_SHIFT 2
|
||||
/* LM36274 */
|
||||
#define LM36274_REG_REV 0x01
|
||||
#define LM36274_REG_BL_CFG_1 0x02
|
||||
#define LM36274_REG_BL_CFG_2 0x03
|
||||
#define LM36274_REG_BRT_LSB 0x04
|
||||
#define LM36274_REG_BRT_MSB 0x05
|
||||
#define LM36274_REG_BL_EN 0x08
|
||||
|
||||
#define LM3697_REG_BL0_RAMP 0x11
|
||||
#define LM3697_REG_BL1_RAMP 0x12
|
||||
#define LM3697_RAMPUP_MASK 0xF0
|
||||
#define LM3697_RAMPUP_SHIFT 4
|
||||
#define LM3697_RAMPDN_MASK 0x0F
|
||||
#define LM3697_RAMPDN_SHIFT 0
|
||||
#define LM36274_REG_BIAS_CONFIG_1 0x09
|
||||
#define LM36274_EXT_EN_MASK BIT(0)
|
||||
#define LM36274_EN_VNEG_MASK BIT(1)
|
||||
#define LM36274_EN_VPOS_MASK BIT(2)
|
||||
|
||||
#define LM3697_REG_RAMP_CONF 0x14
|
||||
#define LM3697_RAMP_MASK 0x0F
|
||||
#define LM3697_RAMP_EACH 0x05
|
||||
#define LM36274_REG_BIAS_CONFIG_2 0x0a
|
||||
#define LM36274_REG_BIAS_CONFIG_3 0x0b
|
||||
#define LM36274_REG_VOUT_BOOST 0x0c
|
||||
#define LM36274_REG_VOUT_POS 0x0d
|
||||
#define LM36274_REG_VOUT_NEG 0x0e
|
||||
#define LM36274_VOUT_MASK 0x3F
|
||||
|
||||
#define LM3697_REG_PWM_CFG 0x1C
|
||||
#define LM3697_PWM_A_MASK BIT(0)
|
||||
#define LM3697_PWM_B_MASK BIT(1)
|
||||
#define LM36274_MAX_REG 0x13
|
||||
|
||||
#define LM3697_REG_IMAX_A 0x17
|
||||
#define LM3697_REG_IMAX_B 0x18
|
||||
|
||||
#define LM3697_REG_FEEDBACK_ENABLE 0x19
|
||||
|
||||
#define LM3697_REG_BRT_A_LSB 0x20
|
||||
#define LM3697_REG_BRT_A_MSB 0x21
|
||||
#define LM3697_REG_BRT_B_LSB 0x22
|
||||
#define LM3697_REG_BRT_B_MSB 0x23
|
||||
|
||||
#define LM3697_REG_ENABLE 0x24
|
||||
|
||||
#define LM3697_REG_OPEN_FAULT_STATUS 0xB0
|
||||
|
||||
#define LM3697_REG_SHORT_FAULT_STATUS 0xB2
|
||||
|
||||
#define LM3697_REG_MONITOR_ENABLE 0xB4
|
||||
|
||||
#define LM3697_MAX_REG 0xB4
|
||||
#endif
|
||||
|
@ -23,7 +23,7 @@ enum ti_lmu_id {
|
||||
LM3632,
|
||||
LM3633,
|
||||
LM3695,
|
||||
LM3697,
|
||||
LM36274,
|
||||
LMU_MAX_ID,
|
||||
};
|
||||
|
||||
@ -65,6 +65,9 @@ enum lm363x_regulator_id {
|
||||
LM3632_BOOST, /* Boost output */
|
||||
LM3632_LDO_POS, /* Positive display bias output */
|
||||
LM3632_LDO_NEG, /* Negative display bias output */
|
||||
LM36274_BOOST, /* Boost output */
|
||||
LM36274_LDO_POS, /* Positive display bias output */
|
||||
LM36274_LDO_NEG, /* Negative display bias output */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -906,7 +906,7 @@ config NETFILTER_XT_TARGET_LED
|
||||
echo netfilter-ssh > /sys/class/leds/<ledname>/trigger
|
||||
|
||||
For more information on the LEDs available on your system, see
|
||||
Documentation/leds/leds-class.txt
|
||||
Documentation/leds/leds-class.rst
|
||||
|
||||
config NETFILTER_XT_TARGET_LOG
|
||||
tristate "LOG target support"
|
||||
|
Loading…
Reference in New Issue
Block a user