- Move the out-of-LED-tree led-sead3 driver to the LED subsystem.
- Add 'invert' sysfs attribute to the heartbeat trigger. - Add Device Tree support to the leds-netxbig driver and add related DT nodes to the kirkwood-netxbig.dtsi and kirkwood-net5big.dts files. Remove static LED setup from the related board files. - Remove redundant brightness conversion operation from leds-netxbig. - Improve leds-bcm6328 driver: improve default-state handling, add more init configuration options, print invalid LED instead of warning only about maximum LED value. - Add a shutdown function for setting gpio-leds into off state when shutting down. - Fix DT flash timeout property naming in leds-aat1290.txt. - Switch to using devm prefixed version of led_classdev_register() (leds-cobalt-qube, leds-hp6xx, leds-ot200, leds-ipaq-micro, leds-netxbig, leds-locomo, leds-menf21bmc, leds-net48xx, leds-wrap). - Add missing of_node_put (leds-powernv, leds-bcm6358, leds-bcm6328, leds-88pm860x). - Coding style fixes and cleanups: led-class/led-core, leds-ipaq-micro. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.17 (GNU/Linux) iQIcBAABAgAGBQJWOGwiAAoJEL1qUBy3i3wm72QQANGvr2lx7YgpLx0BjtkvKlBN CVVHE3u4DhZoiMusJ0qcMO2mGyjd6yJe9rfv3UchA2H7+OooJl401m9niZBrsJGW 2WIOTI1IpJOPD+WaKdxX/Fg3s76UU4hOcsDPxEyKjdJY9pmk6rUkpkDPAS7GoyCH fhjCByhMT0JHN1Md5+vSx8heMWPcn/3b0RHSMJg9ZZZNi+vCLRiCRMOVYqtZxh6R P4HLHXfU45dVtBeikD1Thlq7BvaRyOpWASJwCF2Jar/xKZYPrlXeTn3xaMgVa4ls 3fZFcerib3JBR0B1Y9oguhGepd/N7YXacSuxg3TJu4xSd1GzdT9id19hYftHwj7T NYxImgXLV92stQInCn1L18OUFtvdgO0xJSszCZwUvup4BtJKU1kyFBQ8fouRUimr 8FTYCgwO8F7/zpFeJcKIgwTKZ8XFjzyehM5lXZBxK+mQh69IT2qqY0klqc4xKynr CFSG/PUWQt3iYXM/D/q7vRphykMqicjwHSgaDDGGDDov+VmUdvRxxVveH74oWFre 2LvOAeVo42Abl5h+An7KHXZGzxWUs3XpDXOthd77NISNnK3sw43hBAw782GjwM95 0/tdXGvOsMMPUSjR9StHSkn6rQipW0q606nqmXr0VnSuJA1yLr3GNL0j4A75ULxM Qoj/sW7Gzb+ZmN78Pg4y =X8+e -----END PGP SIGNATURE----- Merge tag 'leds_for_4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds Pull LED updates from Jacek Anaszewski: - Move the out-of-LED-tree led-sead3 driver to the LED subsystem. - Add 'invert' sysfs attribute to the heartbeat trigger. - Add Device Tree support to the leds-netxbig driver and add related DT nodes to the kirkwood-netxbig.dtsi and kirkwood-net5big.dts files. Remove static LED setup from the related board files. - Remove redundant brightness conversion operation from leds-netxbig. - Improve leds-bcm6328 driver: improve default-state handling, add more init configuration options, print invalid LED instead of warning only about maximum LED value. - Add a shutdown function for setting gpio-leds into off state when shutting down. - Fix DT flash timeout property naming in leds-aat1290.txt. - Switch to using devm prefixed version of led_classdev_register() (leds-cobalt-qube, leds-hp6xx, leds-ot200, leds-ipaq-micro, leds-netxbig, leds-locomo, leds-menf21bmc, leds-net48xx, leds-wrap). - Add missing of_node_put (leds-powernv, leds-bcm6358, leds-bcm6328, leds-88pm860x). - Coding style fixes and cleanups: led-class/led-core, leds-ipaq-micro. * tag 'leds_for_4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds: (27 commits) leds: 88pm860x: add missing of_node_put leds: bcm6328: add missing of_node_put leds: bcm6358: add missing of_node_put powerpc/powernv: add missing of_node_put leds: leds-wrap.c: Use devm_led_classdev_register leds: aat1290: Fix property naming of flash-timeout-us leds: leds-net48xx: Use devm_led_classdev_register leds: leds-menf21bmc.c: Use devm_led_class_register leds: leds-locomo.c: Use devm_led_classdev_register leds: leds-gpio: add shutdown function Documentation: leds: update DT bindings for leds-bcm6328 leds-bcm6328: add more init configuration options leds-bcm6328: simplify and improve default-state handling leds-bcm6328: print invalid LED leds: netxbig: set led_classdev max_brightness leds: netxbig: convert to use the devm_ functions ARM: mvebu: remove static LED setup for netxbig boards ARM: Kirkwood: add LED DT entries for netxbig boards leds: netxbig: add device tree binding leds: triggers: add invert to heartbeat ...
This commit is contained in:
commit
e8a2a176dd
35 changed files with 766 additions and 538 deletions
22
Documentation/devicetree/bindings/gpio/netxbig-gpio-ext.txt
Normal file
22
Documentation/devicetree/bindings/gpio/netxbig-gpio-ext.txt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Binding for the GPIO extension bus found on some LaCie/Seagate boards
|
||||||
|
(Example: 2Big/5Big Network v2, 2Big NAS).
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: "lacie,netxbig-gpio-ext".
|
||||||
|
- addr-gpios: GPIOs representing the address register (LSB -> MSB).
|
||||||
|
- data-gpios: GPIOs representing the data register (LSB -> MSB).
|
||||||
|
- enable-gpio: latches the new configuration (address, data) on raising edge.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
netxbig_gpio_ext: netxbig-gpio-ext {
|
||||||
|
compatible = "lacie,netxbig-gpio-ext";
|
||||||
|
|
||||||
|
addr-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH
|
||||||
|
&gpio1 16 GPIO_ACTIVE_HIGH
|
||||||
|
&gpio1 17 GPIO_ACTIVE_HIGH>;
|
||||||
|
data-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH
|
||||||
|
&gpio1 13 GPIO_ACTIVE_HIGH
|
||||||
|
&gpio1 14 GPIO_ACTIVE_HIGH>;
|
||||||
|
enable-gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
|
@ -27,9 +27,9 @@ Required properties of the LED child node:
|
||||||
- flash-max-microamp : see Documentation/devicetree/bindings/leds/common.txt
|
- flash-max-microamp : see Documentation/devicetree/bindings/leds/common.txt
|
||||||
Maximum flash LED supply current can be calculated using
|
Maximum flash LED supply current can be calculated using
|
||||||
following formula: I = 1A * 162kohm / Rset.
|
following formula: I = 1A * 162kohm / Rset.
|
||||||
- flash-timeout-us : see Documentation/devicetree/bindings/leds/common.txt
|
- flash-max-timeout-us : see Documentation/devicetree/bindings/leds/common.txt
|
||||||
Maximum flash timeout can be calculated using following
|
Maximum flash timeout can be calculated using following
|
||||||
formula: T = 8.82 * 10^9 * Ct.
|
formula: T = 8.82 * 10^9 * Ct.
|
||||||
|
|
||||||
Optional properties of the LED child node:
|
Optional properties of the LED child node:
|
||||||
- label : see Documentation/devicetree/bindings/leds/common.txt
|
- label : see Documentation/devicetree/bindings/leds/common.txt
|
||||||
|
@ -54,7 +54,7 @@ aat1290 {
|
||||||
label = "aat1290-flash";
|
label = "aat1290-flash";
|
||||||
led-max-microamp = <520833>;
|
led-max-microamp = <520833>;
|
||||||
flash-max-microamp = <1012500>;
|
flash-max-microamp = <1012500>;
|
||||||
flash-timeout-us = <1940000>;
|
flash-max-timeout-us = <1940000>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,14 @@ Required properties:
|
||||||
Optional properties:
|
Optional properties:
|
||||||
- brcm,serial-leds : Boolean, enables Serial LEDs.
|
- brcm,serial-leds : Boolean, enables Serial LEDs.
|
||||||
Default : false
|
Default : false
|
||||||
|
- brcm,serial-mux : Boolean, enables Serial LEDs multiplexing.
|
||||||
|
Default : false
|
||||||
|
- brcm,serial-clk-low : Boolean, makes clock signal active low.
|
||||||
|
Default : false
|
||||||
|
- brcm,serial-dat-low : Boolean, makes data signal active low.
|
||||||
|
Default : false
|
||||||
|
- brcm,serial-shift-inv : Boolean, inverts Serial LEDs shift direction.
|
||||||
|
Default : false
|
||||||
|
|
||||||
Each LED is represented as a sub-node of the brcm,bcm6328-leds device.
|
Each LED is represented as a sub-node of the brcm,bcm6328-leds device.
|
||||||
|
|
||||||
|
@ -110,6 +118,8 @@ Scenario 2 : BCM63268 with Serial/GPHY0 LEDs
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
reg = <0x10001900 0x24>;
|
reg = <0x10001900 0x24>;
|
||||||
brcm,serial-leds;
|
brcm,serial-leds;
|
||||||
|
brcm,serial-dat-low;
|
||||||
|
brcm,serial-shift-inv;
|
||||||
|
|
||||||
gphy0_spd0@0 {
|
gphy0_spd0@0 {
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
|
|
92
Documentation/devicetree/bindings/leds/leds-netxbig.txt
Normal file
92
Documentation/devicetree/bindings/leds/leds-netxbig.txt
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
Binding for the CPLD LEDs (GPIO extension bus) found on some LaCie/Seagate
|
||||||
|
boards (Example: 2Big/5Big Network v2, 2Big NAS).
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: "lacie,netxbig-leds".
|
||||||
|
- gpio-ext: Phandle for the gpio-ext bus.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- timers: Timer array. Each timer entry is represented by three integers:
|
||||||
|
Mode (gpio-ext bus), delay_on and delay_off.
|
||||||
|
|
||||||
|
Each LED is represented as a sub-node of the netxbig-leds device.
|
||||||
|
|
||||||
|
Required sub-node properties:
|
||||||
|
- mode-addr: Mode register address on gpio-ext bus.
|
||||||
|
- mode-val: Mode to value mapping. Each entry is represented by two integers:
|
||||||
|
A mode and the corresponding value on the gpio-ext bus.
|
||||||
|
- bright-addr: Brightness register address on gpio-ext bus.
|
||||||
|
- max-brightness: Maximum brightness value.
|
||||||
|
|
||||||
|
Optional sub-node properties:
|
||||||
|
- label: Name for this LED. If omitted, the label is taken from the node name.
|
||||||
|
- linux,default-trigger: Trigger assigned to the LED.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
netxbig-leds {
|
||||||
|
compatible = "lacie,netxbig-leds";
|
||||||
|
|
||||||
|
gpio-ext = &gpio_ext;
|
||||||
|
|
||||||
|
timers = <NETXBIG_LED_TIMER1 500 500
|
||||||
|
NETXBIG_LED_TIMER2 500 1000>;
|
||||||
|
|
||||||
|
blue-power {
|
||||||
|
label = "netxbig:blue:power";
|
||||||
|
mode-addr = <0>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 1
|
||||||
|
NETXBIG_LED_TIMER1 3
|
||||||
|
NETXBIG_LED_TIMER2 7>;
|
||||||
|
bright-addr = <1>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
red-power {
|
||||||
|
label = "netxbig:red:power";
|
||||||
|
mode-addr = <0>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 2
|
||||||
|
NETXBIG_LED_TIMER1 4>;
|
||||||
|
bright-addr = <1>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
blue-sata0 {
|
||||||
|
label = "netxbig:blue:sata0";
|
||||||
|
mode-addr = <3>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 7
|
||||||
|
NETXBIG_LED_SATA 1
|
||||||
|
NETXBIG_LED_TIMER1 3>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
red-sata0 {
|
||||||
|
label = "netxbig:red:sata0";
|
||||||
|
mode-addr = <3>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 2
|
||||||
|
NETXBIG_LED_TIMER1 4>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
blue-sata1 {
|
||||||
|
label = "netxbig:blue:sata1";
|
||||||
|
mode-addr = <4>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 7
|
||||||
|
NETXBIG_LED_SATA 1
|
||||||
|
NETXBIG_LED_TIMER1 3>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
red-sata1 {
|
||||||
|
label = "netxbig:red:sata1";
|
||||||
|
mode-addr = <4>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 2
|
||||||
|
NETXBIG_LED_TIMER1 4>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -86,6 +86,66 @@
|
||||||
clock-frequency = <32768>;
|
clock-frequency = <32768>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
netxbig-leds {
|
||||||
|
blue-sata2 {
|
||||||
|
label = "netxbig:blue:sata2";
|
||||||
|
mode-addr = <5>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 7
|
||||||
|
NETXBIG_LED_SATA 1
|
||||||
|
NETXBIG_LED_TIMER1 3>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
red-sata2 {
|
||||||
|
label = "netxbig:red:sata2";
|
||||||
|
mode-addr = <5>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 2
|
||||||
|
NETXBIG_LED_TIMER1 4>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
blue-sata3 {
|
||||||
|
label = "netxbig:blue:sata3";
|
||||||
|
mode-addr = <6>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 7
|
||||||
|
NETXBIG_LED_SATA 1
|
||||||
|
NETXBIG_LED_TIMER1 3>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
red-sata3 {
|
||||||
|
label = "netxbig:red:sata3";
|
||||||
|
mode-addr = <6>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 2
|
||||||
|
NETXBIG_LED_TIMER1 4>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
blue-sata4 {
|
||||||
|
label = "netxbig:blue:sata4";
|
||||||
|
mode-addr = <7>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 7
|
||||||
|
NETXBIG_LED_SATA 1
|
||||||
|
NETXBIG_LED_TIMER1 3>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
red-sata4 {
|
||||||
|
label = "netxbig:red:sata4";
|
||||||
|
mode-addr = <7>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 2
|
||||||
|
NETXBIG_LED_TIMER1 4>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&mdio {
|
&mdio {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* warranty of any kind, whether express or implied.
|
* warranty of any kind, whether express or implied.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <dt-bindings/leds/leds-netxbig.h>
|
||||||
#include "kirkwood.dtsi"
|
#include "kirkwood.dtsi"
|
||||||
#include "kirkwood-6281.dtsi"
|
#include "kirkwood-6281.dtsi"
|
||||||
|
|
||||||
|
@ -105,6 +106,85 @@
|
||||||
gpio = <&gpio0 16 GPIO_ACTIVE_HIGH>;
|
gpio = <&gpio0 16 GPIO_ACTIVE_HIGH>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
netxbig_gpio_ext: netxbig-gpio-ext {
|
||||||
|
compatible = "lacie,netxbig-gpio-ext";
|
||||||
|
|
||||||
|
addr-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH
|
||||||
|
&gpio1 16 GPIO_ACTIVE_HIGH
|
||||||
|
&gpio1 17 GPIO_ACTIVE_HIGH>;
|
||||||
|
data-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH
|
||||||
|
&gpio1 13 GPIO_ACTIVE_HIGH
|
||||||
|
&gpio1 14 GPIO_ACTIVE_HIGH>;
|
||||||
|
enable-gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
|
netxbig-leds {
|
||||||
|
compatible = "lacie,netxbig-leds";
|
||||||
|
|
||||||
|
gpio-ext = <&netxbig_gpio_ext>;
|
||||||
|
|
||||||
|
timers = <NETXBIG_LED_TIMER1 500 500
|
||||||
|
NETXBIG_LED_TIMER2 500 1000>;
|
||||||
|
|
||||||
|
blue-power {
|
||||||
|
label = "netxbig:blue:power";
|
||||||
|
mode-addr = <0>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 1
|
||||||
|
NETXBIG_LED_TIMER1 3
|
||||||
|
NETXBIG_LED_TIMER2 7>;
|
||||||
|
bright-addr = <1>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
red-power {
|
||||||
|
label = "netxbig:red:power";
|
||||||
|
mode-addr = <0>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 2
|
||||||
|
NETXBIG_LED_TIMER1 4>;
|
||||||
|
bright-addr = <1>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
blue-sata0 {
|
||||||
|
label = "netxbig:blue:sata0";
|
||||||
|
mode-addr = <3>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 7
|
||||||
|
NETXBIG_LED_SATA 1
|
||||||
|
NETXBIG_LED_TIMER1 3>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
red-sata0 {
|
||||||
|
label = "netxbig:red:sata0";
|
||||||
|
mode-addr = <3>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 2
|
||||||
|
NETXBIG_LED_TIMER1 4>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
blue-sata1 {
|
||||||
|
label = "netxbig:blue:sata1";
|
||||||
|
mode-addr = <4>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 7
|
||||||
|
NETXBIG_LED_SATA 1
|
||||||
|
NETXBIG_LED_TIMER1 3>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
red-sata1 {
|
||||||
|
label = "netxbig:red:sata1";
|
||||||
|
mode-addr = <4>;
|
||||||
|
mode-val = <NETXBIG_LED_OFF 0
|
||||||
|
NETXBIG_LED_ON 2
|
||||||
|
NETXBIG_LED_TIMER1 4>;
|
||||||
|
bright-addr = <2>;
|
||||||
|
max-brightness = <7>;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&mdio {
|
&mdio {
|
||||||
|
|
|
@ -117,11 +117,4 @@ config MACH_KIRKWOOD
|
||||||
Say 'Y' here if you want your kernel to support boards based
|
Say 'Y' here if you want your kernel to support boards based
|
||||||
on the Marvell Kirkwood device tree.
|
on the Marvell Kirkwood device tree.
|
||||||
|
|
||||||
config MACH_NETXBIG
|
|
||||||
bool "LaCie 2Big and 5Big Network v2"
|
|
||||||
depends on MACH_KIRKWOOD
|
|
||||||
help
|
|
||||||
Say 'Y' here if you want your kernel to support the
|
|
||||||
LaCie 2Big and 5Big Network v2
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -13,4 +13,3 @@ endif
|
||||||
|
|
||||||
obj-$(CONFIG_MACH_DOVE) += dove.o
|
obj-$(CONFIG_MACH_DOVE) += dove.o
|
||||||
obj-$(CONFIG_MACH_KIRKWOOD) += kirkwood.o kirkwood-pm.o
|
obj-$(CONFIG_MACH_KIRKWOOD) += kirkwood.o kirkwood-pm.o
|
||||||
obj-$(CONFIG_MACH_NETXBIG) += netxbig.o
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
* Board functions for Marvell System On Chip
|
|
||||||
*
|
|
||||||
* Copyright (C) 2014
|
|
||||||
*
|
|
||||||
* Andrew Lunn <andrew@lunn.ch>
|
|
||||||
*
|
|
||||||
* This file is licensed under the terms of the GNU General Public
|
|
||||||
* License version 2. This program is licensed "as is" without any
|
|
||||||
* warranty of any kind, whether express or implied.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __ARCH_MVEBU_BOARD_H
|
|
||||||
#define __ARCH_MVEBU_BOARD_H
|
|
||||||
|
|
||||||
#ifdef CONFIG_MACH_NETXBIG
|
|
||||||
void netxbig_init(void);
|
|
||||||
#else
|
|
||||||
static inline void netxbig_init(void) {};
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "kirkwood.h"
|
#include "kirkwood.h"
|
||||||
#include "kirkwood-pm.h"
|
#include "kirkwood-pm.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "board.h"
|
|
||||||
|
|
||||||
static struct resource kirkwood_cpufreq_resources[] = {
|
static struct resource kirkwood_cpufreq_resources[] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
|
@ -180,9 +179,6 @@ static void __init kirkwood_dt_init(void)
|
||||||
kirkwood_pm_init();
|
kirkwood_pm_init();
|
||||||
kirkwood_dt_eth_fixup();
|
kirkwood_dt_eth_fixup();
|
||||||
|
|
||||||
if (of_machine_is_compatible("lacie,netxbig"))
|
|
||||||
netxbig_init();
|
|
||||||
|
|
||||||
of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL);
|
of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,191 +0,0 @@
|
||||||
/*
|
|
||||||
* arch/arm/mach-mvbu/board-netxbig.c
|
|
||||||
*
|
|
||||||
* LaCie 2Big and 5Big Network v2 board setup
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/of.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/platform_data/leds-kirkwood-netxbig.h>
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* GPIO extension LEDs
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The LEDs are controlled by a CPLD and can be configured through a GPIO
|
|
||||||
* extension bus:
|
|
||||||
*
|
|
||||||
* - address register : bit [0-2] -> GPIO [47-49]
|
|
||||||
* - data register : bit [0-2] -> GPIO [44-46]
|
|
||||||
* - enable register : GPIO 29
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 };
|
|
||||||
static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 };
|
|
||||||
|
|
||||||
static struct netxbig_gpio_ext netxbig_v2_gpio_ext = {
|
|
||||||
.addr = netxbig_v2_gpio_ext_addr,
|
|
||||||
.num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr),
|
|
||||||
.data = netxbig_v2_gpio_ext_data,
|
|
||||||
.num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data),
|
|
||||||
.enable = 29,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Address register selection:
|
|
||||||
*
|
|
||||||
* addr | register
|
|
||||||
* ----------------------------
|
|
||||||
* 0 | front LED
|
|
||||||
* 1 | front LED brightness
|
|
||||||
* 2 | SATA LED brightness
|
|
||||||
* 3 | SATA0 LED
|
|
||||||
* 4 | SATA1 LED
|
|
||||||
* 5 | SATA2 LED
|
|
||||||
* 6 | SATA3 LED
|
|
||||||
* 7 | SATA4 LED
|
|
||||||
*
|
|
||||||
* Data register configuration:
|
|
||||||
*
|
|
||||||
* data | LED brightness
|
|
||||||
* -------------------------------------------------
|
|
||||||
* 0 | min (off)
|
|
||||||
* - | -
|
|
||||||
* 7 | max
|
|
||||||
*
|
|
||||||
* data | front LED mode
|
|
||||||
* -------------------------------------------------
|
|
||||||
* 0 | fix off
|
|
||||||
* 1 | fix blue on
|
|
||||||
* 2 | fix red on
|
|
||||||
* 3 | blink blue on=1 sec and blue off=1 sec
|
|
||||||
* 4 | blink red on=1 sec and red off=1 sec
|
|
||||||
* 5 | blink blue on=2.5 sec and red on=0.5 sec
|
|
||||||
* 6 | blink blue on=1 sec and red on=1 sec
|
|
||||||
* 7 | blink blue on=0.5 sec and blue off=2.5 sec
|
|
||||||
*
|
|
||||||
* data | SATA LED mode
|
|
||||||
* -------------------------------------------------
|
|
||||||
* 0 | fix off
|
|
||||||
* 1 | SATA activity blink
|
|
||||||
* 2 | fix red on
|
|
||||||
* 3 | blink blue on=1 sec and blue off=1 sec
|
|
||||||
* 4 | blink red on=1 sec and red off=1 sec
|
|
||||||
* 5 | blink blue on=2.5 sec and red on=0.5 sec
|
|
||||||
* 6 | blink blue on=1 sec and red on=1 sec
|
|
||||||
* 7 | fix blue on
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = {
|
|
||||||
[NETXBIG_LED_OFF] = 0,
|
|
||||||
[NETXBIG_LED_ON] = 2,
|
|
||||||
[NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
|
|
||||||
[NETXBIG_LED_TIMER1] = 4,
|
|
||||||
[NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = {
|
|
||||||
[NETXBIG_LED_OFF] = 0,
|
|
||||||
[NETXBIG_LED_ON] = 1,
|
|
||||||
[NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
|
|
||||||
[NETXBIG_LED_TIMER1] = 3,
|
|
||||||
[NETXBIG_LED_TIMER2] = 7,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = {
|
|
||||||
[NETXBIG_LED_OFF] = 0,
|
|
||||||
[NETXBIG_LED_ON] = 7,
|
|
||||||
[NETXBIG_LED_SATA] = 1,
|
|
||||||
[NETXBIG_LED_TIMER1] = 3,
|
|
||||||
[NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct netxbig_led_timer netxbig_v2_led_timer[] = {
|
|
||||||
[0] = {
|
|
||||||
.delay_on = 500,
|
|
||||||
.delay_off = 500,
|
|
||||||
.mode = NETXBIG_LED_TIMER1,
|
|
||||||
},
|
|
||||||
[1] = {
|
|
||||||
.delay_on = 500,
|
|
||||||
.delay_off = 1000,
|
|
||||||
.mode = NETXBIG_LED_TIMER2,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NETXBIG_LED(_name, maddr, mval, baddr) \
|
|
||||||
{ .name = _name, \
|
|
||||||
.mode_addr = maddr, \
|
|
||||||
.mode_val = mval, \
|
|
||||||
.bright_addr = baddr }
|
|
||||||
|
|
||||||
static struct netxbig_led net2big_v2_leds_ctrl[] = {
|
|
||||||
NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
|
|
||||||
NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1),
|
|
||||||
NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
|
|
||||||
NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
|
|
||||||
NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
|
|
||||||
NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct netxbig_led_platform_data net2big_v2_leds_data = {
|
|
||||||
.gpio_ext = &netxbig_v2_gpio_ext,
|
|
||||||
.timer = netxbig_v2_led_timer,
|
|
||||||
.num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
|
|
||||||
.leds = net2big_v2_leds_ctrl,
|
|
||||||
.num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct netxbig_led net5big_v2_leds_ctrl[] = {
|
|
||||||
NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
|
|
||||||
NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1),
|
|
||||||
NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
|
|
||||||
NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
|
|
||||||
NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
|
|
||||||
NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
|
|
||||||
NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2),
|
|
||||||
NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2),
|
|
||||||
NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2),
|
|
||||||
NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2),
|
|
||||||
NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2),
|
|
||||||
NETXBIG_LED("net5big-v2:red:sata4", 7, netxbig_v2_red_mled, 2),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct netxbig_led_platform_data net5big_v2_leds_data = {
|
|
||||||
.gpio_ext = &netxbig_v2_gpio_ext,
|
|
||||||
.timer = netxbig_v2_led_timer,
|
|
||||||
.num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
|
|
||||||
.leds = net5big_v2_leds_ctrl,
|
|
||||||
.num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device netxbig_v2_leds = {
|
|
||||||
.name = "leds-netxbig",
|
|
||||||
.id = -1,
|
|
||||||
.dev = {
|
|
||||||
.platform_data = &net2big_v2_leds_data,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
void __init netxbig_init(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (of_machine_is_compatible("lacie,net5big_v2"))
|
|
||||||
netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
|
|
||||||
platform_device_register(&netxbig_v2_leds);
|
|
||||||
}
|
|
|
@ -12,6 +12,4 @@ obj-y := sead3-lcd.o sead3-display.o sead3-init.o \
|
||||||
sead3-int.o sead3-platform.o sead3-reset.o \
|
sead3-int.o sead3-platform.o sead3-reset.o \
|
||||||
sead3-setup.o sead3-time.o
|
sead3-setup.o sead3-time.o
|
||||||
|
|
||||||
obj-y += leds-sead3.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o
|
obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o
|
||||||
|
|
|
@ -556,6 +556,16 @@ config LEDS_KTD2692
|
||||||
|
|
||||||
Say Y to enable this driver.
|
Say Y to enable this driver.
|
||||||
|
|
||||||
|
config LEDS_SEAD3
|
||||||
|
tristate "LED support for the MIPS SEAD 3 board"
|
||||||
|
depends on LEDS_CLASS && MIPS_SEAD3
|
||||||
|
help
|
||||||
|
Say Y here to include support for the FLED and PLED LEDs on SEAD3 eval
|
||||||
|
boards.
|
||||||
|
|
||||||
|
This driver can also be built as a module. If so the module
|
||||||
|
will be called leds-sead3.
|
||||||
|
|
||||||
comment "LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)"
|
comment "LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)"
|
||||||
|
|
||||||
config LEDS_BLINKM
|
config LEDS_BLINKM
|
||||||
|
|
|
@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o
|
||||||
obj-$(CONFIG_LEDS_MENF21BMC) += leds-menf21bmc.o
|
obj-$(CONFIG_LEDS_MENF21BMC) += leds-menf21bmc.o
|
||||||
obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o
|
obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o
|
||||||
obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
|
obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
|
||||||
|
obj-$(CONFIG_LEDS_SEAD3) += leds-sead3.o
|
||||||
|
|
||||||
# LED SPI Drivers
|
# LED SPI Drivers
|
||||||
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
|
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
|
||||||
|
|
|
@ -102,70 +102,6 @@ static const struct attribute_group *led_groups[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void led_timer_function(unsigned long data)
|
|
||||||
{
|
|
||||||
struct led_classdev *led_cdev = (void *)data;
|
|
||||||
unsigned long brightness;
|
|
||||||
unsigned long delay;
|
|
||||||
|
|
||||||
if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) {
|
|
||||||
led_set_brightness_async(led_cdev, LED_OFF);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (led_cdev->flags & LED_BLINK_ONESHOT_STOP) {
|
|
||||||
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
brightness = led_get_brightness(led_cdev);
|
|
||||||
if (!brightness) {
|
|
||||||
/* Time to switch the LED on. */
|
|
||||||
if (led_cdev->delayed_set_value) {
|
|
||||||
led_cdev->blink_brightness =
|
|
||||||
led_cdev->delayed_set_value;
|
|
||||||
led_cdev->delayed_set_value = 0;
|
|
||||||
}
|
|
||||||
brightness = led_cdev->blink_brightness;
|
|
||||||
delay = led_cdev->blink_delay_on;
|
|
||||||
} else {
|
|
||||||
/* Store the current brightness value to be able
|
|
||||||
* to restore it when the delay_off period is over.
|
|
||||||
*/
|
|
||||||
led_cdev->blink_brightness = brightness;
|
|
||||||
brightness = LED_OFF;
|
|
||||||
delay = led_cdev->blink_delay_off;
|
|
||||||
}
|
|
||||||
|
|
||||||
led_set_brightness_async(led_cdev, brightness);
|
|
||||||
|
|
||||||
/* Return in next iteration if led is in one-shot mode and we are in
|
|
||||||
* the final blink state so that the led is toggled each delay_on +
|
|
||||||
* delay_off milliseconds in worst case.
|
|
||||||
*/
|
|
||||||
if (led_cdev->flags & LED_BLINK_ONESHOT) {
|
|
||||||
if (led_cdev->flags & LED_BLINK_INVERT) {
|
|
||||||
if (brightness)
|
|
||||||
led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
|
|
||||||
} else {
|
|
||||||
if (!brightness)
|
|
||||||
led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_brightness_delayed(struct work_struct *ws)
|
|
||||||
{
|
|
||||||
struct led_classdev *led_cdev =
|
|
||||||
container_of(ws, struct led_classdev, set_brightness_work);
|
|
||||||
|
|
||||||
led_stop_software_blink(led_cdev);
|
|
||||||
|
|
||||||
led_set_brightness_async(led_cdev, led_cdev->delayed_set_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* led_classdev_suspend - suspend an led_classdev.
|
* led_classdev_suspend - suspend an led_classdev.
|
||||||
* @led_cdev: the led_classdev to suspend.
|
* @led_cdev: the led_classdev to suspend.
|
||||||
|
@ -283,10 +219,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
|
||||||
|
|
||||||
led_update_brightness(led_cdev);
|
led_update_brightness(led_cdev);
|
||||||
|
|
||||||
INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
|
led_init_core(led_cdev);
|
||||||
|
|
||||||
setup_timer(&led_cdev->blink_timer, led_timer_function,
|
|
||||||
(unsigned long)led_cdev);
|
|
||||||
|
|
||||||
#ifdef CONFIG_LEDS_TRIGGERS
|
#ifdef CONFIG_LEDS_TRIGGERS
|
||||||
led_trigger_set_default(led_cdev);
|
led_trigger_set_default(led_cdev);
|
||||||
|
|
|
@ -25,6 +25,70 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
|
||||||
LIST_HEAD(leds_list);
|
LIST_HEAD(leds_list);
|
||||||
EXPORT_SYMBOL_GPL(leds_list);
|
EXPORT_SYMBOL_GPL(leds_list);
|
||||||
|
|
||||||
|
static void led_timer_function(unsigned long data)
|
||||||
|
{
|
||||||
|
struct led_classdev *led_cdev = (void *)data;
|
||||||
|
unsigned long brightness;
|
||||||
|
unsigned long delay;
|
||||||
|
|
||||||
|
if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) {
|
||||||
|
led_set_brightness_async(led_cdev, LED_OFF);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (led_cdev->flags & LED_BLINK_ONESHOT_STOP) {
|
||||||
|
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
brightness = led_get_brightness(led_cdev);
|
||||||
|
if (!brightness) {
|
||||||
|
/* Time to switch the LED on. */
|
||||||
|
if (led_cdev->delayed_set_value) {
|
||||||
|
led_cdev->blink_brightness =
|
||||||
|
led_cdev->delayed_set_value;
|
||||||
|
led_cdev->delayed_set_value = 0;
|
||||||
|
}
|
||||||
|
brightness = led_cdev->blink_brightness;
|
||||||
|
delay = led_cdev->blink_delay_on;
|
||||||
|
} else {
|
||||||
|
/* Store the current brightness value to be able
|
||||||
|
* to restore it when the delay_off period is over.
|
||||||
|
*/
|
||||||
|
led_cdev->blink_brightness = brightness;
|
||||||
|
brightness = LED_OFF;
|
||||||
|
delay = led_cdev->blink_delay_off;
|
||||||
|
}
|
||||||
|
|
||||||
|
led_set_brightness_async(led_cdev, brightness);
|
||||||
|
|
||||||
|
/* Return in next iteration if led is in one-shot mode and we are in
|
||||||
|
* the final blink state so that the led is toggled each delay_on +
|
||||||
|
* delay_off milliseconds in worst case.
|
||||||
|
*/
|
||||||
|
if (led_cdev->flags & LED_BLINK_ONESHOT) {
|
||||||
|
if (led_cdev->flags & LED_BLINK_INVERT) {
|
||||||
|
if (brightness)
|
||||||
|
led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
|
||||||
|
} else {
|
||||||
|
if (!brightness)
|
||||||
|
led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_brightness_delayed(struct work_struct *ws)
|
||||||
|
{
|
||||||
|
struct led_classdev *led_cdev =
|
||||||
|
container_of(ws, struct led_classdev, set_brightness_work);
|
||||||
|
|
||||||
|
led_stop_software_blink(led_cdev);
|
||||||
|
|
||||||
|
led_set_brightness_async(led_cdev, led_cdev->delayed_set_value);
|
||||||
|
}
|
||||||
|
|
||||||
static void led_set_software_blink(struct led_classdev *led_cdev,
|
static void led_set_software_blink(struct led_classdev *led_cdev,
|
||||||
unsigned long delay_on,
|
unsigned long delay_on,
|
||||||
unsigned long delay_off)
|
unsigned long delay_off)
|
||||||
|
@ -72,6 +136,15 @@ static void led_blink_setup(struct led_classdev *led_cdev,
|
||||||
led_set_software_blink(led_cdev, *delay_on, *delay_off);
|
led_set_software_blink(led_cdev, *delay_on, *delay_off);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void led_init_core(struct led_classdev *led_cdev)
|
||||||
|
{
|
||||||
|
INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
|
||||||
|
|
||||||
|
setup_timer(&led_cdev->blink_timer, led_timer_function,
|
||||||
|
(unsigned long)led_cdev);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(led_init_core);
|
||||||
|
|
||||||
void led_blink_set(struct led_classdev *led_cdev,
|
void led_blink_set(struct led_classdev *led_cdev,
|
||||||
unsigned long *delay_on,
|
unsigned long *delay_on,
|
||||||
unsigned long *delay_off)
|
unsigned long *delay_off)
|
||||||
|
|
|
@ -142,6 +142,7 @@ static int pm860x_led_dt_init(struct platform_device *pdev,
|
||||||
of_property_read_u32(np, "marvell,88pm860x-iset",
|
of_property_read_u32(np, "marvell,88pm860x-iset",
|
||||||
&iset);
|
&iset);
|
||||||
data->iset = PM8606_LED_CURRENT(iset);
|
data->iset = PM8606_LED_CURRENT(iset);
|
||||||
|
of_node_put(np);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,11 @@
|
||||||
#define BCM6328_SERIAL_LED_SHIFT_DIR BIT(16)
|
#define BCM6328_SERIAL_LED_SHIFT_DIR BIT(16)
|
||||||
#define BCM6328_LED_SHIFT_TEST BIT(30)
|
#define BCM6328_LED_SHIFT_TEST BIT(30)
|
||||||
#define BCM6328_LED_TEST BIT(31)
|
#define BCM6328_LED_TEST BIT(31)
|
||||||
|
#define BCM6328_INIT_MASK (BCM6328_SERIAL_LED_EN | \
|
||||||
|
BCM6328_SERIAL_LED_MUX | \
|
||||||
|
BCM6328_SERIAL_LED_CLK_NPOL | \
|
||||||
|
BCM6328_SERIAL_LED_DATA_PPOL | \
|
||||||
|
BCM6328_SERIAL_LED_SHIFT_DIR)
|
||||||
|
|
||||||
#define BCM6328_LED_MODE_MASK 3
|
#define BCM6328_LED_MODE_MASK 3
|
||||||
#define BCM6328_LED_MODE_OFF 0
|
#define BCM6328_LED_MODE_OFF 0
|
||||||
|
@ -281,11 +286,10 @@ static int bcm6328_led(struct device *dev, struct device_node *nc, u32 reg,
|
||||||
"linux,default-trigger",
|
"linux,default-trigger",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
spin_lock_irqsave(lock, flags);
|
||||||
if (!of_property_read_string(nc, "default-state", &state)) {
|
if (!of_property_read_string(nc, "default-state", &state)) {
|
||||||
spin_lock_irqsave(lock, flags);
|
|
||||||
if (!strcmp(state, "on")) {
|
if (!strcmp(state, "on")) {
|
||||||
led->cdev.brightness = LED_FULL;
|
led->cdev.brightness = LED_FULL;
|
||||||
bcm6328_led_mode(led, BCM6328_LED_MODE_ON);
|
|
||||||
} else if (!strcmp(state, "keep")) {
|
} else if (!strcmp(state, "keep")) {
|
||||||
void __iomem *mode;
|
void __iomem *mode;
|
||||||
unsigned long val, shift;
|
unsigned long val, shift;
|
||||||
|
@ -296,21 +300,28 @@ static int bcm6328_led(struct device *dev, struct device_node *nc, u32 reg,
|
||||||
else
|
else
|
||||||
mode = mem + BCM6328_REG_MODE_LO;
|
mode = mem + BCM6328_REG_MODE_LO;
|
||||||
|
|
||||||
val = bcm6328_led_read(mode) >> (shift % 16);
|
val = bcm6328_led_read(mode) >>
|
||||||
|
BCM6328_LED_SHIFT(shift % 16);
|
||||||
val &= BCM6328_LED_MODE_MASK;
|
val &= BCM6328_LED_MODE_MASK;
|
||||||
if (val == BCM6328_LED_MODE_ON)
|
if ((led->active_low && val == BCM6328_LED_MODE_ON) ||
|
||||||
|
(!led->active_low && val == BCM6328_LED_MODE_OFF))
|
||||||
led->cdev.brightness = LED_FULL;
|
led->cdev.brightness = LED_FULL;
|
||||||
else {
|
else
|
||||||
led->cdev.brightness = LED_OFF;
|
led->cdev.brightness = LED_OFF;
|
||||||
bcm6328_led_mode(led, BCM6328_LED_MODE_OFF);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
led->cdev.brightness = LED_OFF;
|
led->cdev.brightness = LED_OFF;
|
||||||
bcm6328_led_mode(led, BCM6328_LED_MODE_OFF);
|
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(lock, flags);
|
} else {
|
||||||
|
led->cdev.brightness = LED_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((led->active_low && led->cdev.brightness == LED_FULL) ||
|
||||||
|
(!led->active_low && led->cdev.brightness == LED_OFF))
|
||||||
|
bcm6328_led_mode(led, BCM6328_LED_MODE_ON);
|
||||||
|
else
|
||||||
|
bcm6328_led_mode(led, BCM6328_LED_MODE_OFF);
|
||||||
|
spin_unlock_irqrestore(lock, flags);
|
||||||
|
|
||||||
led->cdev.brightness_set = bcm6328_led_set;
|
led->cdev.brightness_set = bcm6328_led_set;
|
||||||
led->cdev.blink_set = bcm6328_blink_set;
|
led->cdev.blink_set = bcm6328_blink_set;
|
||||||
|
|
||||||
|
@ -360,9 +371,17 @@ static int bcm6328_leds_probe(struct platform_device *pdev)
|
||||||
bcm6328_led_write(mem + BCM6328_REG_LNKACTSEL_LO, 0);
|
bcm6328_led_write(mem + BCM6328_REG_LNKACTSEL_LO, 0);
|
||||||
|
|
||||||
val = bcm6328_led_read(mem + BCM6328_REG_INIT);
|
val = bcm6328_led_read(mem + BCM6328_REG_INIT);
|
||||||
val &= ~BCM6328_SERIAL_LED_EN;
|
val &= ~(BCM6328_INIT_MASK);
|
||||||
if (of_property_read_bool(np, "brcm,serial-leds"))
|
if (of_property_read_bool(np, "brcm,serial-leds"))
|
||||||
val |= BCM6328_SERIAL_LED_EN;
|
val |= BCM6328_SERIAL_LED_EN;
|
||||||
|
if (of_property_read_bool(np, "brcm,serial-mux"))
|
||||||
|
val |= BCM6328_SERIAL_LED_MUX;
|
||||||
|
if (of_property_read_bool(np, "brcm,serial-clk-low"))
|
||||||
|
val |= BCM6328_SERIAL_LED_CLK_NPOL;
|
||||||
|
if (!of_property_read_bool(np, "brcm,serial-dat-low"))
|
||||||
|
val |= BCM6328_SERIAL_LED_DATA_PPOL;
|
||||||
|
if (!of_property_read_bool(np, "brcm,serial-shift-inv"))
|
||||||
|
val |= BCM6328_SERIAL_LED_SHIFT_DIR;
|
||||||
bcm6328_led_write(mem + BCM6328_REG_INIT, val);
|
bcm6328_led_write(mem + BCM6328_REG_INIT, val);
|
||||||
|
|
||||||
for_each_available_child_of_node(np, child) {
|
for_each_available_child_of_node(np, child) {
|
||||||
|
@ -373,7 +392,7 @@ static int bcm6328_leds_probe(struct platform_device *pdev)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (reg >= BCM6328_LED_MAX_COUNT) {
|
if (reg >= BCM6328_LED_MAX_COUNT) {
|
||||||
dev_err(dev, "invalid LED (>= %d)\n",
|
dev_err(dev, "invalid LED (%u >= %d)\n", reg,
|
||||||
BCM6328_LED_MAX_COUNT);
|
BCM6328_LED_MAX_COUNT);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -384,8 +403,10 @@ static int bcm6328_leds_probe(struct platform_device *pdev)
|
||||||
rc = bcm6328_led(dev, child, reg, mem, lock,
|
rc = bcm6328_led(dev, child, reg, mem, lock,
|
||||||
blink_leds, blink_delay);
|
blink_leds, blink_delay);
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0) {
|
||||||
|
of_node_put(child);
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -215,8 +215,10 @@ static int bcm6358_leds_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = bcm6358_led(dev, child, reg, mem, lock);
|
rc = bcm6358_led(dev, child, reg, mem, lock);
|
||||||
if (rc < 0)
|
if (rc < 0) {
|
||||||
|
of_node_put(child);
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -36,7 +36,6 @@ static struct led_classdev qube_front_led = {
|
||||||
static int cobalt_qube_led_probe(struct platform_device *pdev)
|
static int cobalt_qube_led_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
int retval;
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
if (!res)
|
if (!res)
|
||||||
|
@ -49,31 +48,11 @@ static int cobalt_qube_led_probe(struct platform_device *pdev)
|
||||||
led_value = LED_FRONT_LEFT | LED_FRONT_RIGHT;
|
led_value = LED_FRONT_LEFT | LED_FRONT_RIGHT;
|
||||||
writeb(led_value, led_port);
|
writeb(led_value, led_port);
|
||||||
|
|
||||||
retval = led_classdev_register(&pdev->dev, &qube_front_led);
|
return devm_led_classdev_register(&pdev->dev, &qube_front_led);
|
||||||
if (retval)
|
|
||||||
goto err_null;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_null:
|
|
||||||
led_port = NULL;
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cobalt_qube_led_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
led_classdev_unregister(&qube_front_led);
|
|
||||||
|
|
||||||
if (led_port)
|
|
||||||
led_port = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver cobalt_qube_led_driver = {
|
static struct platform_driver cobalt_qube_led_driver = {
|
||||||
.probe = cobalt_qube_led_probe,
|
.probe = cobalt_qube_led_probe,
|
||||||
.remove = cobalt_qube_led_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "cobalt-qube-leds",
|
.name = "cobalt-qube-leds",
|
||||||
},
|
},
|
||||||
|
|
|
@ -291,9 +291,22 @@ static int gpio_led_remove(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gpio_led_shutdown(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct gpio_leds_priv *priv = platform_get_drvdata(pdev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < priv->num_leds; i++) {
|
||||||
|
struct gpio_led_data *led = &priv->leds[i];
|
||||||
|
|
||||||
|
gpio_led_set(&led->cdev, LED_OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct platform_driver gpio_led_driver = {
|
static struct platform_driver gpio_led_driver = {
|
||||||
.probe = gpio_led_probe,
|
.probe = gpio_led_probe,
|
||||||
.remove = gpio_led_remove,
|
.remove = gpio_led_remove,
|
||||||
|
.shutdown = gpio_led_shutdown,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "leds-gpio",
|
.name = "leds-gpio",
|
||||||
.of_match_table = of_gpio_leds_match,
|
.of_match_table = of_gpio_leds_match,
|
||||||
|
|
|
@ -59,28 +59,15 @@ static int hp6xxled_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = led_classdev_register(&pdev->dev, &hp6xx_red_led);
|
ret = devm_led_classdev_register(&pdev->dev, &hp6xx_red_led);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = led_classdev_register(&pdev->dev, &hp6xx_green_led);
|
return devm_led_classdev_register(&pdev->dev, &hp6xx_green_led);
|
||||||
if (ret < 0)
|
|
||||||
led_classdev_unregister(&hp6xx_red_led);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hp6xxled_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
led_classdev_unregister(&hp6xx_red_led);
|
|
||||||
led_classdev_unregister(&hp6xx_green_led);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver hp6xxled_driver = {
|
static struct platform_driver hp6xxled_driver = {
|
||||||
.probe = hp6xxled_probe,
|
.probe = hp6xxled_probe,
|
||||||
.remove = hp6xxled_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "hp6xx-led",
|
.name = "hp6xx-led",
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
#define LED_YELLOW 0x00
|
#define LED_YELLOW 0x00
|
||||||
#define LED_GREEN 0x01
|
#define LED_GREEN 0x01
|
||||||
|
|
||||||
#define LED_EN (1 << 4) /* LED ON/OFF 0:off, 1:on */
|
#define LED_EN (1 << 4) /* LED ON/OFF 0:off, 1:on */
|
||||||
#define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop set 0:disable, 1:enable */
|
#define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop set 0:disable, 1:enable */
|
||||||
#define LED_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */
|
#define LED_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */
|
||||||
|
|
||||||
static void micro_leds_brightness_set(struct led_classdev *led_cdev,
|
static void micro_leds_brightness_set(struct led_classdev *led_cdev,
|
||||||
enum led_brightness value)
|
enum led_brightness value)
|
||||||
|
@ -79,14 +79,14 @@ static int micro_leds_blink_set(struct led_classdev *led_cdev,
|
||||||
};
|
};
|
||||||
|
|
||||||
msg.tx_data[0] = LED_GREEN;
|
msg.tx_data[0] = LED_GREEN;
|
||||||
if (*delay_on > IPAQ_LED_MAX_DUTY ||
|
if (*delay_on > IPAQ_LED_MAX_DUTY ||
|
||||||
*delay_off > IPAQ_LED_MAX_DUTY)
|
*delay_off > IPAQ_LED_MAX_DUTY)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (*delay_on == 0 && *delay_off == 0) {
|
if (*delay_on == 0 && *delay_off == 0) {
|
||||||
*delay_on = 100;
|
*delay_on = 100;
|
||||||
*delay_off = 100;
|
*delay_off = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.tx_data[1] = 0;
|
msg.tx_data[1] = 0;
|
||||||
if (*delay_on >= IPAQ_LED_MAX_DUTY)
|
if (*delay_on >= IPAQ_LED_MAX_DUTY)
|
||||||
|
@ -111,7 +111,7 @@ static int micro_leds_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = led_classdev_register(&pdev->dev, µ_led);
|
ret = devm_led_classdev_register(&pdev->dev, µ_led);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "registering led failed: %d\n", ret);
|
dev_err(&pdev->dev, "registering led failed: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -121,18 +121,11 @@ static int micro_leds_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int micro_leds_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
led_classdev_unregister(µ_led);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct platform_driver micro_leds_device_driver = {
|
static struct platform_driver micro_leds_device_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "ipaq-micro-leds",
|
.name = "ipaq-micro-leds",
|
||||||
},
|
},
|
||||||
.probe = micro_leds_probe,
|
.probe = micro_leds_probe,
|
||||||
.remove = micro_leds_remove,
|
|
||||||
};
|
};
|
||||||
module_platform_driver(micro_leds_device_driver);
|
module_platform_driver(micro_leds_device_driver);
|
||||||
|
|
||||||
|
|
|
@ -59,23 +59,13 @@ static int locomoled_probe(struct locomo_dev *ldev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = led_classdev_register(&ldev->dev, &locomo_led0);
|
ret = devm_led_classdev_register(&ldev->dev, &locomo_led0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = led_classdev_register(&ldev->dev, &locomo_led1);
|
return devm_led_classdev_register(&ldev->dev, &locomo_led1);
|
||||||
if (ret < 0)
|
|
||||||
led_classdev_unregister(&locomo_led0);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int locomoled_remove(struct locomo_dev *dev)
|
|
||||||
{
|
|
||||||
led_classdev_unregister(&locomo_led0);
|
|
||||||
led_classdev_unregister(&locomo_led1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct locomo_driver locomoled_driver = {
|
static struct locomo_driver locomoled_driver = {
|
||||||
.drv = {
|
.drv = {
|
||||||
|
@ -83,7 +73,6 @@ static struct locomo_driver locomoled_driver = {
|
||||||
},
|
},
|
||||||
.devid = LOCOMO_DEVID_LED,
|
.devid = LOCOMO_DEVID_LED,
|
||||||
.probe = locomoled_probe,
|
.probe = locomoled_probe,
|
||||||
.remove = locomoled_remove,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init locomoled_init(void)
|
static int __init locomoled_init(void)
|
||||||
|
|
|
@ -87,36 +87,20 @@ static int menf21bmc_led_probe(struct platform_device *pdev)
|
||||||
leds[i].cdev.name = leds[i].name;
|
leds[i].cdev.name = leds[i].name;
|
||||||
leds[i].cdev.brightness_set = menf21bmc_led_set;
|
leds[i].cdev.brightness_set = menf21bmc_led_set;
|
||||||
leds[i].i2c_client = i2c_client;
|
leds[i].i2c_client = i2c_client;
|
||||||
ret = led_classdev_register(&pdev->dev, &leds[i].cdev);
|
ret = devm_led_classdev_register(&pdev->dev, &leds[i].cdev);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
goto err_free_leds;
|
dev_err(&pdev->dev, "failed to register LED device\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dev_info(&pdev->dev, "MEN 140F21P00 BMC LED device enabled\n");
|
dev_info(&pdev->dev, "MEN 140F21P00 BMC LED device enabled\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free_leds:
|
|
||||||
dev_err(&pdev->dev, "failed to register LED device\n");
|
|
||||||
|
|
||||||
for (i = i - 1; i >= 0; i--)
|
|
||||||
led_classdev_unregister(&leds[i].cdev);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int menf21bmc_led_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(leds); i++)
|
|
||||||
led_classdev_unregister(&leds[i].cdev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver menf21bmc_led = {
|
static struct platform_driver menf21bmc_led = {
|
||||||
.probe = menf21bmc_led_probe,
|
.probe = menf21bmc_led_probe,
|
||||||
.remove = menf21bmc_led_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "menf21bmc_led",
|
.name = "menf21bmc_led",
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,18 +39,11 @@ static struct led_classdev net48xx_error_led = {
|
||||||
|
|
||||||
static int net48xx_led_probe(struct platform_device *pdev)
|
static int net48xx_led_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
return led_classdev_register(&pdev->dev, &net48xx_error_led);
|
return devm_led_classdev_register(&pdev->dev, &net48xx_error_led);
|
||||||
}
|
|
||||||
|
|
||||||
static int net48xx_led_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
led_classdev_unregister(&net48xx_error_led);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver net48xx_led_driver = {
|
static struct platform_driver net48xx_led_driver = {
|
||||||
.probe = net48xx_led_probe,
|
.probe = net48xx_led_probe,
|
||||||
.remove = net48xx_led_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRVNAME,
|
.name = DRVNAME,
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/of_gpio.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
#include <linux/platform_data/leds-kirkwood-netxbig.h>
|
#include <linux/platform_data/leds-kirkwood-netxbig.h>
|
||||||
|
|
||||||
|
@ -70,7 +71,8 @@ static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext,
|
||||||
spin_unlock_irqrestore(&gpio_ext_lock, flags);
|
spin_unlock_irqrestore(&gpio_ext_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
|
static int gpio_ext_init(struct platform_device *pdev,
|
||||||
|
struct netxbig_gpio_ext *gpio_ext)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
|
@ -80,46 +82,28 @@ static int gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
|
||||||
|
|
||||||
/* Configure address GPIOs. */
|
/* Configure address GPIOs. */
|
||||||
for (i = 0; i < gpio_ext->num_addr; i++) {
|
for (i = 0; i < gpio_ext->num_addr; i++) {
|
||||||
err = gpio_request_one(gpio_ext->addr[i], GPIOF_OUT_INIT_LOW,
|
err = devm_gpio_request_one(&pdev->dev, gpio_ext->addr[i],
|
||||||
"GPIO extension addr");
|
GPIOF_OUT_INIT_LOW,
|
||||||
|
"GPIO extension addr");
|
||||||
if (err)
|
if (err)
|
||||||
goto err_free_addr;
|
return err;
|
||||||
}
|
}
|
||||||
/* Configure data GPIOs. */
|
/* Configure data GPIOs. */
|
||||||
for (i = 0; i < gpio_ext->num_data; i++) {
|
for (i = 0; i < gpio_ext->num_data; i++) {
|
||||||
err = gpio_request_one(gpio_ext->data[i], GPIOF_OUT_INIT_LOW,
|
err = devm_gpio_request_one(&pdev->dev, gpio_ext->data[i],
|
||||||
"GPIO extension data");
|
GPIOF_OUT_INIT_LOW,
|
||||||
|
"GPIO extension data");
|
||||||
if (err)
|
if (err)
|
||||||
goto err_free_data;
|
return err;
|
||||||
}
|
}
|
||||||
/* Configure "enable select" GPIO. */
|
/* Configure "enable select" GPIO. */
|
||||||
err = gpio_request_one(gpio_ext->enable, GPIOF_OUT_INIT_LOW,
|
err = devm_gpio_request_one(&pdev->dev, gpio_ext->enable,
|
||||||
"GPIO extension enable");
|
GPIOF_OUT_INIT_LOW,
|
||||||
|
"GPIO extension enable");
|
||||||
if (err)
|
if (err)
|
||||||
goto err_free_data;
|
return err;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free_data:
|
|
||||||
for (i = i - 1; i >= 0; i--)
|
|
||||||
gpio_free(gpio_ext->data[i]);
|
|
||||||
i = gpio_ext->num_addr;
|
|
||||||
err_free_addr:
|
|
||||||
for (i = i - 1; i >= 0; i--)
|
|
||||||
gpio_free(gpio_ext->addr[i]);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gpio_ext_free(struct netxbig_gpio_ext *gpio_ext)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
gpio_free(gpio_ext->enable);
|
|
||||||
for (i = gpio_ext->num_addr - 1; i >= 0; i--)
|
|
||||||
gpio_free(gpio_ext->addr[i]);
|
|
||||||
for (i = gpio_ext->num_data - 1; i >= 0; i--)
|
|
||||||
gpio_free(gpio_ext->data[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -132,7 +116,6 @@ struct netxbig_led_data {
|
||||||
int mode_addr;
|
int mode_addr;
|
||||||
int *mode_val;
|
int *mode_val;
|
||||||
int bright_addr;
|
int bright_addr;
|
||||||
int bright_max;
|
|
||||||
struct netxbig_led_timer *timer;
|
struct netxbig_led_timer *timer;
|
||||||
int num_timer;
|
int num_timer;
|
||||||
enum netxbig_led_mode mode;
|
enum netxbig_led_mode mode;
|
||||||
|
@ -194,7 +177,7 @@ static void netxbig_led_set(struct led_classdev *led_cdev,
|
||||||
struct netxbig_led_data *led_dat =
|
struct netxbig_led_data *led_dat =
|
||||||
container_of(led_cdev, struct netxbig_led_data, cdev);
|
container_of(led_cdev, struct netxbig_led_data, cdev);
|
||||||
enum netxbig_led_mode mode;
|
enum netxbig_led_mode mode;
|
||||||
int mode_val, bright_val;
|
int mode_val;
|
||||||
int set_brightness = 1;
|
int set_brightness = 1;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
@ -220,12 +203,9 @@ static void netxbig_led_set(struct led_classdev *led_cdev,
|
||||||
* SATA LEDs. So, change the brightness setting for a single
|
* SATA LEDs. So, change the brightness setting for a single
|
||||||
* SATA LED will affect all the others.
|
* SATA LED will affect all the others.
|
||||||
*/
|
*/
|
||||||
if (set_brightness) {
|
if (set_brightness)
|
||||||
bright_val = DIV_ROUND_UP(value * led_dat->bright_max,
|
|
||||||
LED_FULL);
|
|
||||||
gpio_ext_set_value(led_dat->gpio_ext,
|
gpio_ext_set_value(led_dat->gpio_ext,
|
||||||
led_dat->bright_addr, bright_val);
|
led_dat->bright_addr, value);
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&led_dat->lock, flags);
|
spin_unlock_irqrestore(&led_dat->lock, flags);
|
||||||
}
|
}
|
||||||
|
@ -299,18 +279,11 @@ static struct attribute *netxbig_led_attrs[] = {
|
||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(netxbig_led);
|
ATTRIBUTE_GROUPS(netxbig_led);
|
||||||
|
|
||||||
static void delete_netxbig_led(struct netxbig_led_data *led_dat)
|
static int create_netxbig_led(struct platform_device *pdev,
|
||||||
|
struct netxbig_led_platform_data *pdata,
|
||||||
|
struct netxbig_led_data *led_dat,
|
||||||
|
const struct netxbig_led *template)
|
||||||
{
|
{
|
||||||
led_classdev_unregister(&led_dat->cdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
create_netxbig_led(struct platform_device *pdev,
|
|
||||||
struct netxbig_led_data *led_dat,
|
|
||||||
const struct netxbig_led *template)
|
|
||||||
{
|
|
||||||
struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
|
||||||
|
|
||||||
spin_lock_init(&led_dat->lock);
|
spin_lock_init(&led_dat->lock);
|
||||||
led_dat->gpio_ext = pdata->gpio_ext;
|
led_dat->gpio_ext = pdata->gpio_ext;
|
||||||
led_dat->cdev.name = template->name;
|
led_dat->cdev.name = template->name;
|
||||||
|
@ -329,11 +302,11 @@ create_netxbig_led(struct platform_device *pdev,
|
||||||
*/
|
*/
|
||||||
led_dat->sata = 0;
|
led_dat->sata = 0;
|
||||||
led_dat->cdev.brightness = LED_OFF;
|
led_dat->cdev.brightness = LED_OFF;
|
||||||
|
led_dat->cdev.max_brightness = template->bright_max;
|
||||||
led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
|
led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
|
||||||
led_dat->mode_addr = template->mode_addr;
|
led_dat->mode_addr = template->mode_addr;
|
||||||
led_dat->mode_val = template->mode_val;
|
led_dat->mode_val = template->mode_val;
|
||||||
led_dat->bright_addr = template->bright_addr;
|
led_dat->bright_addr = template->bright_addr;
|
||||||
led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1;
|
|
||||||
led_dat->timer = pdata->timer;
|
led_dat->timer = pdata->timer;
|
||||||
led_dat->num_timer = pdata->num_timer;
|
led_dat->num_timer = pdata->num_timer;
|
||||||
/*
|
/*
|
||||||
|
@ -343,9 +316,233 @@ create_netxbig_led(struct platform_device *pdev,
|
||||||
if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
|
if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
|
||||||
led_dat->cdev.groups = netxbig_led_groups;
|
led_dat->cdev.groups = netxbig_led_groups;
|
||||||
|
|
||||||
return led_classdev_register(&pdev->dev, &led_dat->cdev);
|
return devm_led_classdev_register(&pdev->dev, &led_dat->cdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF_GPIO
|
||||||
|
static int gpio_ext_get_of_pdata(struct device *dev, struct device_node *np,
|
||||||
|
struct netxbig_gpio_ext *gpio_ext)
|
||||||
|
{
|
||||||
|
int *addr, *data;
|
||||||
|
int num_addr, num_data;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ret = of_gpio_named_count(np, "addr-gpios");
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev,
|
||||||
|
"Failed to count GPIOs in DT property addr-gpios\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
num_addr = ret;
|
||||||
|
addr = devm_kzalloc(dev, num_addr * sizeof(*addr), GFP_KERNEL);
|
||||||
|
if (!addr)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (i = 0; i < num_addr; i++) {
|
||||||
|
ret = of_get_named_gpio(np, "addr-gpios", i);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
addr[i] = ret;
|
||||||
|
}
|
||||||
|
gpio_ext->addr = addr;
|
||||||
|
gpio_ext->num_addr = num_addr;
|
||||||
|
|
||||||
|
ret = of_gpio_named_count(np, "data-gpios");
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev,
|
||||||
|
"Failed to count GPIOs in DT property data-gpios\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
num_data = ret;
|
||||||
|
data = devm_kzalloc(dev, num_data * sizeof(*data), GFP_KERNEL);
|
||||||
|
if (!data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (i = 0; i < num_data; i++) {
|
||||||
|
ret = of_get_named_gpio(np, "data-gpios", i);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
data[i] = ret;
|
||||||
|
}
|
||||||
|
gpio_ext->data = data;
|
||||||
|
gpio_ext->num_data = num_data;
|
||||||
|
|
||||||
|
ret = of_get_named_gpio(np, "enable-gpio", 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev,
|
||||||
|
"Failed to get GPIO from DT property enable-gpio\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
gpio_ext->enable = ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int netxbig_leds_get_of_pdata(struct device *dev,
|
||||||
|
struct netxbig_led_platform_data *pdata)
|
||||||
|
{
|
||||||
|
struct device_node *np = dev->of_node;
|
||||||
|
struct device_node *gpio_ext_np;
|
||||||
|
struct device_node *child;
|
||||||
|
struct netxbig_gpio_ext *gpio_ext;
|
||||||
|
struct netxbig_led_timer *timers;
|
||||||
|
struct netxbig_led *leds, *led;
|
||||||
|
int num_timers;
|
||||||
|
int num_leds = 0;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* GPIO extension */
|
||||||
|
gpio_ext_np = of_parse_phandle(np, "gpio-ext", 0);
|
||||||
|
if (!gpio_ext_np) {
|
||||||
|
dev_err(dev, "Failed to get DT handle gpio-ext\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_ext = devm_kzalloc(dev, sizeof(*gpio_ext), GFP_KERNEL);
|
||||||
|
if (!gpio_ext)
|
||||||
|
return -ENOMEM;
|
||||||
|
ret = gpio_ext_get_of_pdata(dev, gpio_ext_np, gpio_ext);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
of_node_put(gpio_ext_np);
|
||||||
|
pdata->gpio_ext = gpio_ext;
|
||||||
|
|
||||||
|
/* Timers (optional) */
|
||||||
|
ret = of_property_count_u32_elems(np, "timers");
|
||||||
|
if (ret > 0) {
|
||||||
|
if (ret % 3)
|
||||||
|
return -EINVAL;
|
||||||
|
num_timers = ret / 3;
|
||||||
|
timers = devm_kzalloc(dev, num_timers * sizeof(*timers),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!timers)
|
||||||
|
return -ENOMEM;
|
||||||
|
for (i = 0; i < num_timers; i++) {
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
of_property_read_u32_index(np, "timers", 3 * i,
|
||||||
|
&timers[i].mode);
|
||||||
|
if (timers[i].mode >= NETXBIG_LED_MODE_NUM)
|
||||||
|
return -EINVAL;
|
||||||
|
of_property_read_u32_index(np, "timers",
|
||||||
|
3 * i + 1, &tmp);
|
||||||
|
timers[i].delay_on = tmp;
|
||||||
|
of_property_read_u32_index(np, "timers",
|
||||||
|
3 * i + 2, &tmp);
|
||||||
|
timers[i].delay_off = tmp;
|
||||||
|
}
|
||||||
|
pdata->timer = timers;
|
||||||
|
pdata->num_timer = num_timers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LEDs */
|
||||||
|
num_leds = of_get_child_count(np);
|
||||||
|
if (!num_leds) {
|
||||||
|
dev_err(dev, "No LED subnodes found in DT\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
leds = devm_kzalloc(dev, num_leds * sizeof(*leds), GFP_KERNEL);
|
||||||
|
if (!leds)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
led = leds;
|
||||||
|
for_each_child_of_node(np, child) {
|
||||||
|
const char *string;
|
||||||
|
int *mode_val;
|
||||||
|
int num_modes;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(child, "mode-addr",
|
||||||
|
&led->mode_addr);
|
||||||
|
if (ret)
|
||||||
|
goto err_node_put;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(child, "bright-addr",
|
||||||
|
&led->bright_addr);
|
||||||
|
if (ret)
|
||||||
|
goto err_node_put;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(child, "max-brightness",
|
||||||
|
&led->bright_max);
|
||||||
|
if (ret)
|
||||||
|
goto err_node_put;
|
||||||
|
|
||||||
|
mode_val =
|
||||||
|
devm_kzalloc(dev,
|
||||||
|
NETXBIG_LED_MODE_NUM * sizeof(*mode_val),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!mode_val) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_node_put;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NETXBIG_LED_MODE_NUM; i++)
|
||||||
|
mode_val[i] = NETXBIG_LED_INVALID_MODE;
|
||||||
|
|
||||||
|
ret = of_property_count_u32_elems(child, "mode-val");
|
||||||
|
if (ret < 0 || ret % 2) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err_node_put;
|
||||||
|
}
|
||||||
|
num_modes = ret / 2;
|
||||||
|
if (num_modes > NETXBIG_LED_MODE_NUM) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err_node_put;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_modes; i++) {
|
||||||
|
int mode;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
of_property_read_u32_index(child,
|
||||||
|
"mode-val", 2 * i, &mode);
|
||||||
|
of_property_read_u32_index(child,
|
||||||
|
"mode-val", 2 * i + 1, &val);
|
||||||
|
if (mode >= NETXBIG_LED_MODE_NUM) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err_node_put;
|
||||||
|
}
|
||||||
|
mode_val[mode] = val;
|
||||||
|
}
|
||||||
|
led->mode_val = mode_val;
|
||||||
|
|
||||||
|
if (!of_property_read_string(child, "label", &string))
|
||||||
|
led->name = string;
|
||||||
|
else
|
||||||
|
led->name = child->name;
|
||||||
|
|
||||||
|
if (!of_property_read_string(child,
|
||||||
|
"linux,default-trigger", &string))
|
||||||
|
led->default_trigger = string;
|
||||||
|
|
||||||
|
led++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdata->leds = leds;
|
||||||
|
pdata->num_leds = num_leds;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_node_put:
|
||||||
|
of_node_put(child);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id of_netxbig_leds_match[] = {
|
||||||
|
{ .compatible = "lacie,netxbig-leds", },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
static inline int
|
||||||
|
netxbig_leds_get_of_pdata(struct device *dev,
|
||||||
|
struct netxbig_led_platform_data *pdata)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OF_GPIO */
|
||||||
|
|
||||||
static int netxbig_led_probe(struct platform_device *pdev)
|
static int netxbig_led_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||||
|
@ -353,57 +550,40 @@ static int netxbig_led_probe(struct platform_device *pdev)
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!pdata)
|
if (!pdata) {
|
||||||
return -EINVAL;
|
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||||
|
if (!pdata)
|
||||||
|
return -ENOMEM;
|
||||||
|
ret = netxbig_leds_get_of_pdata(&pdev->dev, pdata);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
leds_data = devm_kzalloc(&pdev->dev,
|
leds_data = devm_kzalloc(&pdev->dev,
|
||||||
sizeof(struct netxbig_led_data) * pdata->num_leds, GFP_KERNEL);
|
pdata->num_leds * sizeof(*leds_data),
|
||||||
|
GFP_KERNEL);
|
||||||
if (!leds_data)
|
if (!leds_data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = gpio_ext_init(pdata->gpio_ext);
|
ret = gpio_ext_init(pdev, pdata->gpio_ext);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
for (i = 0; i < pdata->num_leds; i++) {
|
for (i = 0; i < pdata->num_leds; i++) {
|
||||||
ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]);
|
ret = create_netxbig_led(pdev, pdata,
|
||||||
|
&leds_data[i], &pdata->leds[i]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_free_leds;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, leds_data);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_free_leds:
|
|
||||||
for (i = i - 1; i >= 0; i--)
|
|
||||||
delete_netxbig_led(&leds_data[i]);
|
|
||||||
|
|
||||||
gpio_ext_free(pdata->gpio_ext);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int netxbig_led_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
|
||||||
struct netxbig_led_data *leds_data;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
leds_data = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
for (i = 0; i < pdata->num_leds; i++)
|
|
||||||
delete_netxbig_led(&leds_data[i]);
|
|
||||||
|
|
||||||
gpio_ext_free(pdata->gpio_ext);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver netxbig_led_driver = {
|
static struct platform_driver netxbig_led_driver = {
|
||||||
.probe = netxbig_led_probe,
|
.probe = netxbig_led_probe,
|
||||||
.remove = netxbig_led_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "leds-netxbig",
|
.name = "leds-netxbig",
|
||||||
|
.of_match_table = of_match_ptr(of_netxbig_leds_match),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -124,9 +124,9 @@ static int ot200_led_probe(struct platform_device *pdev)
|
||||||
leds[i].cdev.name = leds[i].name;
|
leds[i].cdev.name = leds[i].name;
|
||||||
leds[i].cdev.brightness_set = ot200_led_brightness_set;
|
leds[i].cdev.brightness_set = ot200_led_brightness_set;
|
||||||
|
|
||||||
ret = led_classdev_register(&pdev->dev, &leds[i].cdev);
|
ret = devm_led_classdev_register(&pdev->dev, &leds[i].cdev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
leds_front = 0; /* turn off all front leds */
|
leds_front = 0; /* turn off all front leds */
|
||||||
|
@ -135,27 +135,10 @@ static int ot200_led_probe(struct platform_device *pdev)
|
||||||
outb(leds_back, 0x5a);
|
outb(leds_back, 0x5a);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
|
||||||
for (i = i - 1; i >= 0; i--)
|
|
||||||
led_classdev_unregister(&leds[i].cdev);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ot200_led_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(leds); i++)
|
|
||||||
led_classdev_unregister(&leds[i].cdev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver ot200_led_driver = {
|
static struct platform_driver ot200_led_driver = {
|
||||||
.probe = ot200_led_probe,
|
.probe = ot200_led_probe,
|
||||||
.remove = ot200_led_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "leds-ot200",
|
.name = "leds-ot200",
|
||||||
},
|
},
|
||||||
|
|
|
@ -262,15 +262,19 @@ static int powernv_led_classdev(struct platform_device *pdev,
|
||||||
while ((cur = of_prop_next_string(p, cur)) != NULL) {
|
while ((cur = of_prop_next_string(p, cur)) != NULL) {
|
||||||
powernv_led = devm_kzalloc(dev, sizeof(*powernv_led),
|
powernv_led = devm_kzalloc(dev, sizeof(*powernv_led),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!powernv_led)
|
if (!powernv_led) {
|
||||||
|
of_node_put(np);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
powernv_led->common = powernv_led_common;
|
powernv_led->common = powernv_led_common;
|
||||||
powernv_led->loc_code = (char *)np->name;
|
powernv_led->loc_code = (char *)np->name;
|
||||||
|
|
||||||
rc = powernv_led_create(dev, powernv_led, cur);
|
rc = powernv_led_create(dev, powernv_led, cur);
|
||||||
if (rc)
|
if (rc) {
|
||||||
|
of_node_put(np);
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
} /* while end */
|
} /* while end */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ static int sead3_led_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
led_classdev_unregister(&sead3_pled);
|
led_classdev_unregister(&sead3_pled);
|
||||||
led_classdev_unregister(&sead3_fled);
|
led_classdev_unregister(&sead3_fled);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,39 +76,19 @@ static int wrap_led_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = led_classdev_register(&pdev->dev, &wrap_power_led);
|
ret = devm_led_classdev_register(&pdev->dev, &wrap_power_led);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = led_classdev_register(&pdev->dev, &wrap_error_led);
|
ret = devm_led_classdev_register(&pdev->dev, &wrap_error_led);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err1;
|
return ret;
|
||||||
|
|
||||||
ret = led_classdev_register(&pdev->dev, &wrap_extra_led);
|
return devm_led_classdev_register(&pdev->dev, &wrap_extra_led);
|
||||||
if (ret < 0)
|
|
||||||
goto err2;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
err2:
|
|
||||||
led_classdev_unregister(&wrap_error_led);
|
|
||||||
err1:
|
|
||||||
led_classdev_unregister(&wrap_power_led);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int wrap_led_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
led_classdev_unregister(&wrap_power_led);
|
|
||||||
led_classdev_unregister(&wrap_error_led);
|
|
||||||
led_classdev_unregister(&wrap_extra_led);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver wrap_led_driver = {
|
static struct platform_driver wrap_led_driver = {
|
||||||
.probe = wrap_led_probe,
|
.probe = wrap_led_probe,
|
||||||
.remove = wrap_led_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRVNAME,
|
.name = DRVNAME,
|
||||||
},
|
},
|
||||||
|
|
|
@ -44,6 +44,7 @@ static inline int led_get_brightness(struct led_classdev *led_cdev)
|
||||||
return led_cdev->brightness;
|
return led_cdev->brightness;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void led_init_core(struct led_classdev *led_cdev);
|
||||||
void led_stop_software_blink(struct led_classdev *led_cdev);
|
void led_stop_software_blink(struct led_classdev *led_cdev);
|
||||||
|
|
||||||
extern struct rw_semaphore leds_list_lock;
|
extern struct rw_semaphore leds_list_lock;
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct heartbeat_trig_data {
|
||||||
unsigned int phase;
|
unsigned int phase;
|
||||||
unsigned int period;
|
unsigned int period;
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
|
unsigned int invert;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void led_heartbeat_function(unsigned long data)
|
static void led_heartbeat_function(unsigned long data)
|
||||||
|
@ -56,21 +57,27 @@ static void led_heartbeat_function(unsigned long data)
|
||||||
msecs_to_jiffies(heartbeat_data->period);
|
msecs_to_jiffies(heartbeat_data->period);
|
||||||
delay = msecs_to_jiffies(70);
|
delay = msecs_to_jiffies(70);
|
||||||
heartbeat_data->phase++;
|
heartbeat_data->phase++;
|
||||||
brightness = led_cdev->max_brightness;
|
if (!heartbeat_data->invert)
|
||||||
|
brightness = led_cdev->max_brightness;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
|
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
|
||||||
heartbeat_data->phase++;
|
heartbeat_data->phase++;
|
||||||
|
if (heartbeat_data->invert)
|
||||||
|
brightness = led_cdev->max_brightness;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
delay = msecs_to_jiffies(70);
|
delay = msecs_to_jiffies(70);
|
||||||
heartbeat_data->phase++;
|
heartbeat_data->phase++;
|
||||||
brightness = led_cdev->max_brightness;
|
if (!heartbeat_data->invert)
|
||||||
|
brightness = led_cdev->max_brightness;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
delay = heartbeat_data->period - heartbeat_data->period / 4 -
|
delay = heartbeat_data->period - heartbeat_data->period / 4 -
|
||||||
msecs_to_jiffies(70);
|
msecs_to_jiffies(70);
|
||||||
heartbeat_data->phase = 0;
|
heartbeat_data->phase = 0;
|
||||||
|
if (heartbeat_data->invert)
|
||||||
|
brightness = led_cdev->max_brightness;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,15 +85,50 @@ static void led_heartbeat_function(unsigned long data)
|
||||||
mod_timer(&heartbeat_data->timer, jiffies + delay);
|
mod_timer(&heartbeat_data->timer, jiffies + delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t led_invert_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||||
|
struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
|
||||||
|
|
||||||
|
return sprintf(buf, "%u\n", heartbeat_data->invert);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t led_invert_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t size)
|
||||||
|
{
|
||||||
|
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||||
|
struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
|
||||||
|
unsigned long state;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = kstrtoul(buf, 0, &state);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
heartbeat_data->invert = !!state;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store);
|
||||||
|
|
||||||
static void heartbeat_trig_activate(struct led_classdev *led_cdev)
|
static void heartbeat_trig_activate(struct led_classdev *led_cdev)
|
||||||
{
|
{
|
||||||
struct heartbeat_trig_data *heartbeat_data;
|
struct heartbeat_trig_data *heartbeat_data;
|
||||||
|
int rc;
|
||||||
|
|
||||||
heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL);
|
heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL);
|
||||||
if (!heartbeat_data)
|
if (!heartbeat_data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
led_cdev->trigger_data = heartbeat_data;
|
led_cdev->trigger_data = heartbeat_data;
|
||||||
|
rc = device_create_file(led_cdev->dev, &dev_attr_invert);
|
||||||
|
if (rc) {
|
||||||
|
kfree(led_cdev->trigger_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setup_timer(&heartbeat_data->timer,
|
setup_timer(&heartbeat_data->timer,
|
||||||
led_heartbeat_function, (unsigned long) led_cdev);
|
led_heartbeat_function, (unsigned long) led_cdev);
|
||||||
heartbeat_data->phase = 0;
|
heartbeat_data->phase = 0;
|
||||||
|
@ -100,6 +142,7 @@ static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)
|
||||||
|
|
||||||
if (led_cdev->activated) {
|
if (led_cdev->activated) {
|
||||||
del_timer_sync(&heartbeat_data->timer);
|
del_timer_sync(&heartbeat_data->timer);
|
||||||
|
device_remove_file(led_cdev->dev, &dev_attr_invert);
|
||||||
kfree(heartbeat_data);
|
kfree(heartbeat_data);
|
||||||
led_cdev->activated = false;
|
led_cdev->activated = false;
|
||||||
}
|
}
|
||||||
|
|
18
include/dt-bindings/leds/leds-netxbig.h
Normal file
18
include/dt-bindings/leds/leds-netxbig.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* This header provides constants for netxbig LED bindings.
|
||||||
|
*
|
||||||
|
* This file is licensed under the terms of the GNU General Public
|
||||||
|
* License version 2. This program is licensed "as is" without any
|
||||||
|
* warranty of any kind, whether express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DT_BINDINGS_LEDS_NETXBIG_H
|
||||||
|
#define _DT_BINDINGS_LEDS_NETXBIG_H
|
||||||
|
|
||||||
|
#define NETXBIG_LED_OFF 0
|
||||||
|
#define NETXBIG_LED_ON 1
|
||||||
|
#define NETXBIG_LED_SATA 2
|
||||||
|
#define NETXBIG_LED_TIMER1 3
|
||||||
|
#define NETXBIG_LED_TIMER2 4
|
||||||
|
|
||||||
|
#endif /* _DT_BINDINGS_LEDS_NETXBIG_H */
|
|
@ -40,6 +40,7 @@ struct netxbig_led {
|
||||||
int mode_addr;
|
int mode_addr;
|
||||||
int *mode_val;
|
int *mode_val;
|
||||||
int bright_addr;
|
int bright_addr;
|
||||||
|
int bright_max;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct netxbig_led_platform_data {
|
struct netxbig_led_platform_data {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue