mirror of
https://github.com/torvalds/linux.git
synced 2024-11-07 20:51:47 +00:00
- 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
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
|
||||
Maximum flash LED supply current can be calculated using
|
||||
following formula: I = 1A * 162kohm / Rset.
|
||||
- flash-timeout-us : see Documentation/devicetree/bindings/leds/common.txt
|
||||
Maximum flash timeout can be calculated using following
|
||||
formula: T = 8.82 * 10^9 * Ct.
|
||||
- flash-max-timeout-us : see Documentation/devicetree/bindings/leds/common.txt
|
||||
Maximum flash timeout can be calculated using following
|
||||
formula: T = 8.82 * 10^9 * Ct.
|
||||
|
||||
Optional properties of the LED child node:
|
||||
- label : see Documentation/devicetree/bindings/leds/common.txt
|
||||
@ -54,7 +54,7 @@ aat1290 {
|
||||
label = "aat1290-flash";
|
||||
led-max-microamp = <520833>;
|
||||
flash-max-microamp = <1012500>;
|
||||
flash-timeout-us = <1940000>;
|
||||
flash-max-timeout-us = <1940000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -29,6 +29,14 @@ Required properties:
|
||||
Optional properties:
|
||||
- brcm,serial-leds : Boolean, enables Serial LEDs.
|
||||
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.
|
||||
|
||||
@ -110,6 +118,8 @@ Scenario 2 : BCM63268 with Serial/GPHY0 LEDs
|
||||
#size-cells = <0>;
|
||||
reg = <0x10001900 0x24>;
|
||||
brcm,serial-leds;
|
||||
brcm,serial-dat-low;
|
||||
brcm,serial-shift-inv;
|
||||
|
||||
gphy0_spd0@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>;
|
||||
};
|
||||
};
|
||||
|
||||
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 {
|
||||
|
@ -13,6 +13,7 @@
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/leds/leds-netxbig.h>
|
||||
#include "kirkwood.dtsi"
|
||||
#include "kirkwood-6281.dtsi"
|
||||
|
||||
@ -105,6 +106,85 @@
|
||||
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 {
|
||||
|
@ -117,11 +117,4 @@ config MACH_KIRKWOOD
|
||||
Say 'Y' here if you want your kernel to support boards based
|
||||
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
|
||||
|
@ -13,4 +13,3 @@ endif
|
||||
|
||||
obj-$(CONFIG_MACH_DOVE) += dove.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-pm.h"
|
||||
#include "common.h"
|
||||
#include "board.h"
|
||||
|
||||
static struct resource kirkwood_cpufreq_resources[] = {
|
||||
[0] = {
|
||||
@ -180,9 +179,6 @@ static void __init kirkwood_dt_init(void)
|
||||
kirkwood_pm_init();
|
||||
kirkwood_dt_eth_fixup();
|
||||
|
||||
if (of_machine_is_compatible("lacie,netxbig"))
|
||||
netxbig_init();
|
||||
|
||||
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-setup.o sead3-time.o
|
||||
|
||||
obj-y += leds-sead3.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o
|
||||
|
@ -556,6 +556,16 @@ config LEDS_KTD2692
|
||||
|
||||
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)"
|
||||
|
||||
config LEDS_BLINKM
|
||||
|
@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o
|
||||
obj-$(CONFIG_LEDS_MENF21BMC) += leds-menf21bmc.o
|
||||
obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o
|
||||
obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
|
||||
obj-$(CONFIG_LEDS_SEAD3) += leds-sead3.o
|
||||
|
||||
# LED SPI Drivers
|
||||
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
|
||||
|
@ -102,70 +102,6 @@ static const struct attribute_group *led_groups[] = {
|
||||
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_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);
|
||||
|
||||
INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
|
||||
|
||||
setup_timer(&led_cdev->blink_timer, led_timer_function,
|
||||
(unsigned long)led_cdev);
|
||||
led_init_core(led_cdev);
|
||||
|
||||
#ifdef CONFIG_LEDS_TRIGGERS
|
||||
led_trigger_set_default(led_cdev);
|
||||
|
@ -25,6 +25,70 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
|
||||
LIST_HEAD(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,
|
||||
unsigned long delay_on,
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
unsigned long *delay_on,
|
||||
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",
|
||||
&iset);
|
||||
data->iset = PM8606_LED_CURRENT(iset);
|
||||
of_node_put(np);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,11 @@
|
||||
#define BCM6328_SERIAL_LED_SHIFT_DIR BIT(16)
|
||||
#define BCM6328_LED_SHIFT_TEST BIT(30)
|
||||
#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_OFF 0
|
||||
@ -281,11 +286,10 @@ static int bcm6328_led(struct device *dev, struct device_node *nc, u32 reg,
|
||||
"linux,default-trigger",
|
||||
NULL);
|
||||
|
||||
spin_lock_irqsave(lock, flags);
|
||||
if (!of_property_read_string(nc, "default-state", &state)) {
|
||||
spin_lock_irqsave(lock, flags);
|
||||
if (!strcmp(state, "on")) {
|
||||
led->cdev.brightness = LED_FULL;
|
||||
bcm6328_led_mode(led, BCM6328_LED_MODE_ON);
|
||||
} else if (!strcmp(state, "keep")) {
|
||||
void __iomem *mode;
|
||||
unsigned long val, shift;
|
||||
@ -296,21 +300,28 @@ static int bcm6328_led(struct device *dev, struct device_node *nc, u32 reg,
|
||||
else
|
||||
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;
|
||||
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;
|
||||
else {
|
||||
else
|
||||
led->cdev.brightness = LED_OFF;
|
||||
bcm6328_led_mode(led, BCM6328_LED_MODE_OFF);
|
||||
}
|
||||
} else {
|
||||
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.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);
|
||||
|
||||
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"))
|
||||
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);
|
||||
|
||||
for_each_available_child_of_node(np, child) {
|
||||
@ -373,7 +392,7 @@ static int bcm6328_leds_probe(struct platform_device *pdev)
|
||||
continue;
|
||||
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
@ -384,8 +403,10 @@ static int bcm6328_leds_probe(struct platform_device *pdev)
|
||||
rc = bcm6328_led(dev, child, reg, mem, lock,
|
||||
blink_leds, blink_delay);
|
||||
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
of_node_put(child);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -215,8 +215,10 @@ static int bcm6358_leds_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
rc = bcm6358_led(dev, child, reg, mem, lock);
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
of_node_put(child);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -36,7 +36,6 @@ static struct led_classdev qube_front_led = {
|
||||
static int cobalt_qube_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
int retval;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
@ -49,31 +48,11 @@ static int cobalt_qube_led_probe(struct platform_device *pdev)
|
||||
led_value = LED_FRONT_LEFT | LED_FRONT_RIGHT;
|
||||
writeb(led_value, led_port);
|
||||
|
||||
retval = 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;
|
||||
return devm_led_classdev_register(&pdev->dev, &qube_front_led);
|
||||
}
|
||||
|
||||
static struct platform_driver cobalt_qube_led_driver = {
|
||||
.probe = cobalt_qube_led_probe,
|
||||
.remove = cobalt_qube_led_remove,
|
||||
.driver = {
|
||||
.name = "cobalt-qube-leds",
|
||||
},
|
||||
|
@ -291,9 +291,22 @@ static int gpio_led_remove(struct platform_device *pdev)
|
||||
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 = {
|
||||
.probe = gpio_led_probe,
|
||||
.remove = gpio_led_remove,
|
||||
.shutdown = gpio_led_shutdown,
|
||||
.driver = {
|
||||
.name = "leds-gpio",
|
||||
.of_match_table = of_gpio_leds_match,
|
||||
|
@ -59,28 +59,15 @@ static int hp6xxled_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &hp6xx_red_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, &hp6xx_red_led);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = 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;
|
||||
return devm_led_classdev_register(&pdev->dev, &hp6xx_green_led);
|
||||
}
|
||||
|
||||
static struct platform_driver hp6xxled_driver = {
|
||||
.probe = hp6xxled_probe,
|
||||
.remove = hp6xxled_remove,
|
||||
.driver = {
|
||||
.name = "hp6xx-led",
|
||||
},
|
||||
|
@ -16,9 +16,9 @@
|
||||
#define LED_YELLOW 0x00
|
||||
#define LED_GREEN 0x01
|
||||
|
||||
#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_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */
|
||||
#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_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */
|
||||
|
||||
static void micro_leds_brightness_set(struct led_classdev *led_cdev,
|
||||
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;
|
||||
if (*delay_on > IPAQ_LED_MAX_DUTY ||
|
||||
if (*delay_on > IPAQ_LED_MAX_DUTY ||
|
||||
*delay_off > IPAQ_LED_MAX_DUTY)
|
||||
return -EINVAL;
|
||||
return -EINVAL;
|
||||
|
||||
if (*delay_on == 0 && *delay_off == 0) {
|
||||
*delay_on = 100;
|
||||
*delay_off = 100;
|
||||
}
|
||||
if (*delay_on == 0 && *delay_off == 0) {
|
||||
*delay_on = 100;
|
||||
*delay_off = 100;
|
||||
}
|
||||
|
||||
msg.tx_data[1] = 0;
|
||||
if (*delay_on >= IPAQ_LED_MAX_DUTY)
|
||||
@ -111,7 +111,7 @@ static int micro_leds_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, µ_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, µ_led);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "registering led failed: %d\n", ret);
|
||||
return ret;
|
||||
@ -121,18 +121,11 @@ static int micro_leds_probe(struct platform_device *pdev)
|
||||
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 = {
|
||||
.driver = {
|
||||
.name = "ipaq-micro-leds",
|
||||
},
|
||||
.probe = micro_leds_probe,
|
||||
.remove = micro_leds_remove,
|
||||
};
|
||||
module_platform_driver(micro_leds_device_driver);
|
||||
|
||||
|
@ -59,23 +59,13 @@ static int locomoled_probe(struct locomo_dev *ldev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = led_classdev_register(&ldev->dev, &locomo_led0);
|
||||
ret = devm_led_classdev_register(&ldev->dev, &locomo_led0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&ldev->dev, &locomo_led1);
|
||||
if (ret < 0)
|
||||
led_classdev_unregister(&locomo_led0);
|
||||
|
||||
return ret;
|
||||
return devm_led_classdev_register(&ldev->dev, &locomo_led1);
|
||||
}
|
||||
|
||||
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 = {
|
||||
.drv = {
|
||||
@ -83,7 +73,6 @@ static struct locomo_driver locomoled_driver = {
|
||||
},
|
||||
.devid = LOCOMO_DEVID_LED,
|
||||
.probe = locomoled_probe,
|
||||
.remove = locomoled_remove,
|
||||
};
|
||||
|
||||
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.brightness_set = menf21bmc_led_set;
|
||||
leds[i].i2c_client = i2c_client;
|
||||
ret = led_classdev_register(&pdev->dev, &leds[i].cdev);
|
||||
if (ret < 0)
|
||||
goto err_free_leds;
|
||||
ret = devm_led_classdev_register(&pdev->dev, &leds[i].cdev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to register LED device\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
dev_info(&pdev->dev, "MEN 140F21P00 BMC LED device enabled\n");
|
||||
|
||||
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 = {
|
||||
.probe = menf21bmc_led_probe,
|
||||
.remove = menf21bmc_led_remove,
|
||||
.driver = {
|
||||
.name = "menf21bmc_led",
|
||||
},
|
||||
|
@ -39,18 +39,11 @@ static struct led_classdev net48xx_error_led = {
|
||||
|
||||
static int net48xx_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
return 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;
|
||||
return devm_led_classdev_register(&pdev->dev, &net48xx_error_led);
|
||||
}
|
||||
|
||||
static struct platform_driver net48xx_led_driver = {
|
||||
.probe = net48xx_led_probe,
|
||||
.remove = net48xx_led_remove,
|
||||
.driver = {
|
||||
.name = DRVNAME,
|
||||
},
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/leds.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);
|
||||
}
|
||||
|
||||
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 i;
|
||||
@ -80,46 +82,28 @@ static int gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
|
||||
|
||||
/* Configure address GPIOs. */
|
||||
for (i = 0; i < gpio_ext->num_addr; i++) {
|
||||
err = gpio_request_one(gpio_ext->addr[i], GPIOF_OUT_INIT_LOW,
|
||||
"GPIO extension addr");
|
||||
err = devm_gpio_request_one(&pdev->dev, gpio_ext->addr[i],
|
||||
GPIOF_OUT_INIT_LOW,
|
||||
"GPIO extension addr");
|
||||
if (err)
|
||||
goto err_free_addr;
|
||||
return err;
|
||||
}
|
||||
/* Configure data GPIOs. */
|
||||
for (i = 0; i < gpio_ext->num_data; i++) {
|
||||
err = gpio_request_one(gpio_ext->data[i], GPIOF_OUT_INIT_LOW,
|
||||
"GPIO extension data");
|
||||
err = devm_gpio_request_one(&pdev->dev, gpio_ext->data[i],
|
||||
GPIOF_OUT_INIT_LOW,
|
||||
"GPIO extension data");
|
||||
if (err)
|
||||
goto err_free_data;
|
||||
return err;
|
||||
}
|
||||
/* Configure "enable select" GPIO. */
|
||||
err = gpio_request_one(gpio_ext->enable, GPIOF_OUT_INIT_LOW,
|
||||
"GPIO extension enable");
|
||||
err = devm_gpio_request_one(&pdev->dev, gpio_ext->enable,
|
||||
GPIOF_OUT_INIT_LOW,
|
||||
"GPIO extension enable");
|
||||
if (err)
|
||||
goto err_free_data;
|
||||
return err;
|
||||
|
||||
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_val;
|
||||
int bright_addr;
|
||||
int bright_max;
|
||||
struct netxbig_led_timer *timer;
|
||||
int num_timer;
|
||||
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 =
|
||||
container_of(led_cdev, struct netxbig_led_data, cdev);
|
||||
enum netxbig_led_mode mode;
|
||||
int mode_val, bright_val;
|
||||
int mode_val;
|
||||
int set_brightness = 1;
|
||||
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 LED will affect all the others.
|
||||
*/
|
||||
if (set_brightness) {
|
||||
bright_val = DIV_ROUND_UP(value * led_dat->bright_max,
|
||||
LED_FULL);
|
||||
if (set_brightness)
|
||||
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);
|
||||
}
|
||||
@ -299,18 +279,11 @@ static struct attribute *netxbig_led_attrs[] = {
|
||||
};
|
||||
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);
|
||||
led_dat->gpio_ext = pdata->gpio_ext;
|
||||
led_dat->cdev.name = template->name;
|
||||
@ -329,11 +302,11 @@ create_netxbig_led(struct platform_device *pdev,
|
||||
*/
|
||||
led_dat->sata = 0;
|
||||
led_dat->cdev.brightness = LED_OFF;
|
||||
led_dat->cdev.max_brightness = template->bright_max;
|
||||
led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
|
||||
led_dat->mode_addr = template->mode_addr;
|
||||
led_dat->mode_val = template->mode_val;
|
||||
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->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)
|
||||
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)
|
||||
{
|
||||
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 ret;
|
||||
|
||||
if (!pdata)
|
||||
return -EINVAL;
|
||||
if (!pdata) {
|
||||
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,
|
||||
sizeof(struct netxbig_led_data) * pdata->num_leds, GFP_KERNEL);
|
||||
pdata->num_leds * sizeof(*leds_data),
|
||||
GFP_KERNEL);
|
||||
if (!leds_data)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = gpio_ext_init(pdata->gpio_ext);
|
||||
ret = gpio_ext_init(pdev, pdata->gpio_ext);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
static struct platform_driver netxbig_led_driver = {
|
||||
.probe = netxbig_led_probe,
|
||||
.remove = netxbig_led_remove,
|
||||
.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.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)
|
||||
goto err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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 = {
|
||||
.probe = ot200_led_probe,
|
||||
.remove = ot200_led_remove,
|
||||
.driver = {
|
||||
.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) {
|
||||
powernv_led = devm_kzalloc(dev, sizeof(*powernv_led),
|
||||
GFP_KERNEL);
|
||||
if (!powernv_led)
|
||||
if (!powernv_led) {
|
||||
of_node_put(np);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
powernv_led->common = powernv_led_common;
|
||||
powernv_led->loc_code = (char *)np->name;
|
||||
|
||||
rc = powernv_led_create(dev, powernv_led, cur);
|
||||
if (rc)
|
||||
if (rc) {
|
||||
of_node_put(np);
|
||||
return rc;
|
||||
}
|
||||
} /* while end */
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@ static int sead3_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
led_classdev_unregister(&sead3_pled);
|
||||
led_classdev_unregister(&sead3_fled);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -76,39 +76,19 @@ static int wrap_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &wrap_power_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, &wrap_power_led);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &wrap_error_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, &wrap_error_led);
|
||||
if (ret < 0)
|
||||
goto err1;
|
||||
return ret;
|
||||
|
||||
ret = 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;
|
||||
return devm_led_classdev_register(&pdev->dev, &wrap_extra_led);
|
||||
}
|
||||
|
||||
static struct platform_driver wrap_led_driver = {
|
||||
.probe = wrap_led_probe,
|
||||
.remove = wrap_led_remove,
|
||||
.driver = {
|
||||
.name = DRVNAME,
|
||||
},
|
||||
|
@ -44,6 +44,7 @@ static inline int led_get_brightness(struct led_classdev *led_cdev)
|
||||
return led_cdev->brightness;
|
||||
}
|
||||
|
||||
void led_init_core(struct led_classdev *led_cdev);
|
||||
void led_stop_software_blink(struct led_classdev *led_cdev);
|
||||
|
||||
extern struct rw_semaphore leds_list_lock;
|
||||
|
@ -27,6 +27,7 @@ struct heartbeat_trig_data {
|
||||
unsigned int phase;
|
||||
unsigned int period;
|
||||
struct timer_list timer;
|
||||
unsigned int invert;
|
||||
};
|
||||
|
||||
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);
|
||||
delay = msecs_to_jiffies(70);
|
||||
heartbeat_data->phase++;
|
||||
brightness = led_cdev->max_brightness;
|
||||
if (!heartbeat_data->invert)
|
||||
brightness = led_cdev->max_brightness;
|
||||
break;
|
||||
case 1:
|
||||
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
|
||||
heartbeat_data->phase++;
|
||||
if (heartbeat_data->invert)
|
||||
brightness = led_cdev->max_brightness;
|
||||
break;
|
||||
case 2:
|
||||
delay = msecs_to_jiffies(70);
|
||||
heartbeat_data->phase++;
|
||||
brightness = led_cdev->max_brightness;
|
||||
if (!heartbeat_data->invert)
|
||||
brightness = led_cdev->max_brightness;
|
||||
break;
|
||||
default:
|
||||
delay = heartbeat_data->period - heartbeat_data->period / 4 -
|
||||
msecs_to_jiffies(70);
|
||||
heartbeat_data->phase = 0;
|
||||
if (heartbeat_data->invert)
|
||||
brightness = led_cdev->max_brightness;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -78,15 +85,50 @@ static void led_heartbeat_function(unsigned long data)
|
||||
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)
|
||||
{
|
||||
struct heartbeat_trig_data *heartbeat_data;
|
||||
int rc;
|
||||
|
||||
heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL);
|
||||
if (!heartbeat_data)
|
||||
return;
|
||||
|
||||
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,
|
||||
led_heartbeat_function, (unsigned long) led_cdev);
|
||||
heartbeat_data->phase = 0;
|
||||
@ -100,6 +142,7 @@ static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)
|
||||
|
||||
if (led_cdev->activated) {
|
||||
del_timer_sync(&heartbeat_data->timer);
|
||||
device_remove_file(led_cdev->dev, &dev_attr_invert);
|
||||
kfree(heartbeat_data);
|
||||
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_val;
|
||||
int bright_addr;
|
||||
int bright_max;
|
||||
};
|
||||
|
||||
struct netxbig_led_platform_data {
|
||||
|
Loading…
Reference in New Issue
Block a user