Besides the changes in MAINTAINERS we have:
- optimizations and improvements to existing LED class drivers - improvements to the common LEDs DT documentation - modifications of kirkwood-* dts files, to be in sync with patches for leds-ns2 driver, that move LEDs mode mapping outside of the driver -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.17 (GNU/Linux) iQIcBAABAgAGBQJV5EAlAAoJEL1qUBy3i3wmcZkP/3ZdQZsv5EbF5XLZFXPORs2s BQESLaTVdbgDuSP6CoNkpOGucc5115z+/8GmskWreSck8qxUzgwR8sClU9T2eNi4 epA3SUBi2QaqjK8sl7tRbva0kAXNT+KqHgPwCuN0Pui0EgXsPHEnDYKfLWULx+wi 6NVofK2pTHTV+V3QccjMvO4443Mi9FNO9Ee0EaSVPdE/Mh2rIUPhtB5KmK/XUEv1 gBqVysRoTw/sE5z6SDX2FaSs+98L6UNP9tC8qZCLFqwe2SdQZNqwYJklzHlm3ErI lrkxJaJ7NixB4zAO5MKJ7eZJmJ+YMroC2uIa4DjKiiekfA1d18ioOB6jFgkFyH0o cErLiXKbJoabIc1XsoE/XT7v8a+dSVB9Tj3OPWQcx6HlGpBXTRcV5sayh0wX895Z mn0taprYqS+MnPY/M8jrsl6btsUVRfV6jyneExhIxc3gArkjEjb9m/h3mQNauB8h I0kZ56q1nYCcp/4JhfrUEwnD0sdX9jUqvr3yIOFgNknOHAsqgXMgW38H0RxsBiI4 Tx33cXkp6zh0wqVTPmWe2Ic1xAVY/dSd3ZF2smjzhbwe37unPrXNym6eRguu0ezb 4ZFjvetkqmz8uqyyTq3Lfc5rfbGPOgtCLvKXOgEyo2HaNPPAxeHqRI3HU8bBDtqp j0CCXXXhVqRg4VTzJiXk =sa6j -----END PGP SIGNATURE----- Merge tag 'leds_for_4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds Pull LED updates from Jacek Anaszewski: "In this merge window we'd like to announce a change on the list of LED subsystem maintainers - Bryan Wu decided to step back and handed over the maintainership to me (Jacek Anaszewski), which entailed an update of LED subsystem git tree URL. Besides the changes in MAINTAINERS we have: - optimizations and improvements to existing LED class drivers - improvements to the common LEDs DT documentation - modifications of kirkwood-* dts files, to be in sync with patches for leds-ns2 driver, that move LEDs mode mapping outside of the driver" * tag 'leds_for_4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds: leds: Export OF module alias information in missing drivers leds:lp55xx: use the private data instead of updating I2C device platform data leds: syscon: Correct check for syscon_node_to_regmap() errors leds: leds-fsg: Use devm_led_classdev_register MAINTAINERS: Change LED subsystem git tree URL leds/led-class: Add missing put_device() ARM: Kirkwood: add modes-map property to ns2-leds nodes leds: tlc591xx: Remove redundant I2C_FUNC_SMBUS_BYTE_DATA functionality check leds: leds-ns2: depends on MACH_ARMADA_370 leds: leds-ns2: handle can_sleep GPIOs leds: leds-ns2: move LED modes mapping outside of the driver leds: lp8860: Constify reg_default tables leds: Drop owner assignment from i2c_driver leds: Allow compile test of LEDS_AAT1290 and LEDS_KTD2692 if !GPIOLIB leds: Allow compile test of GPIO consumers if !GPIOLIB DT: leds: Improve description of flash LEDs related properties
This commit is contained in:
commit
edc837da4b
|
@ -29,14 +29,23 @@ Optional properties for child nodes:
|
|||
"ide-disk" - LED indicates disk activity
|
||||
"timer" - LED flashes at a fixed, configurable rate
|
||||
|
||||
- max-microamp : maximum intensity in microamperes of the LED
|
||||
(torch LED for flash devices)
|
||||
- flash-max-microamp : maximum intensity in microamperes of the
|
||||
flash LED; it is mandatory if the LED should
|
||||
support the flash mode
|
||||
- flash-timeout-us : timeout in microseconds after which the flash
|
||||
LED is turned off
|
||||
- led-max-microamp : Maximum LED supply current in microamperes. This property
|
||||
can be made mandatory for the board configurations
|
||||
introducing a risk of hardware damage in case an excessive
|
||||
current is set.
|
||||
For flash LED controllers with configurable current this
|
||||
property is mandatory for the LEDs in the non-flash modes
|
||||
(e.g. torch or indicator).
|
||||
|
||||
Required properties for flash LED child nodes:
|
||||
- flash-max-microamp : Maximum flash LED supply current in microamperes.
|
||||
- flash-max-timeout-us : Maximum timeout in microseconds after which the flash
|
||||
LED is turned off.
|
||||
|
||||
For controllers that have no configurable current the flash-max-microamp
|
||||
property can be omitted.
|
||||
For controllers that have no configurable timeout the flash-max-timeout-us
|
||||
property can be omitted.
|
||||
|
||||
Examples:
|
||||
|
||||
|
@ -49,7 +58,7 @@ system-status {
|
|||
camera-flash {
|
||||
label = "Flash";
|
||||
led-sources = <0>, <1>;
|
||||
max-microamp = <50000>;
|
||||
led-max-microamp = <50000>;
|
||||
flash-max-microamp = <320000>;
|
||||
flash-timeout-us = <500000>;
|
||||
flash-max-timeout-us = <500000>;
|
||||
};
|
||||
|
|
|
@ -8,6 +8,9 @@ Each LED is represented as a sub-node of the ns2-leds device.
|
|||
Required sub-node properties:
|
||||
- cmd-gpio: Command LED GPIO. See OF device-tree GPIO specification.
|
||||
- slow-gpio: Slow LED GPIO. See OF device-tree GPIO specification.
|
||||
- modes-map: A mapping between LED modes (off, on or SATA activity blinking) and
|
||||
the corresponding cmd-gpio/slow-gpio values. All the GPIO values combinations
|
||||
should be given in order to avoid having an unknown mode at driver probe time.
|
||||
|
||||
Optional sub-node properties:
|
||||
- label: Name for this LED. If omitted, the label is taken from the node name.
|
||||
|
@ -15,6 +18,8 @@ Optional sub-node properties:
|
|||
|
||||
Example:
|
||||
|
||||
#include <dt-bindings/leds/leds-ns2.h>
|
||||
|
||||
ns2-leds {
|
||||
compatible = "lacie,ns2-leds";
|
||||
|
||||
|
@ -22,5 +27,9 @@ ns2-leds {
|
|||
label = "ns2:blue:sata";
|
||||
slow-gpio = <&gpio0 29 0>;
|
||||
cmd-gpio = <&gpio0 30 0>;
|
||||
modes-map = <NS_V2_LED_OFF 0 1
|
||||
NS_V2_LED_ON 1 0
|
||||
NS_V2_LED_ON 0 0
|
||||
NS_V2_LED_SATA 1 1>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6042,11 +6042,10 @@ F: Documentation/scsi/53c700.txt
|
|||
F: drivers/scsi/53c700*
|
||||
|
||||
LED SUBSYSTEM
|
||||
M: Bryan Wu <cooloney@gmail.com>
|
||||
M: Richard Purdie <rpurdie@rpsys.net>
|
||||
M: Jacek Anaszewski <j.anaszewski@samsung.com>
|
||||
L: linux-leds@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git
|
||||
S: Maintained
|
||||
F: drivers/leds/
|
||||
F: include/linux/leds.h
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/leds/leds-ns2.h>
|
||||
#include "kirkwood-netxbig.dtsi"
|
||||
|
||||
/ {
|
||||
|
@ -28,6 +29,10 @@
|
|||
label = "d2net_v2:blue:sata";
|
||||
slow-gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
|
||||
cmd-gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
|
||||
modes-map = <NS_V2_LED_OFF 1 0
|
||||
NS_V2_LED_ON 0 1
|
||||
NS_V2_LED_ON 1 1
|
||||
NS_V2_LED_SATA 0 0>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/leds/leds-ns2.h>
|
||||
#include "kirkwood-ns2-common.dtsi"
|
||||
|
||||
/ {
|
||||
|
@ -27,6 +28,10 @@
|
|||
label = "ns2:blue:sata";
|
||||
slow-gpio = <&gpio0 29 0>;
|
||||
cmd-gpio = <&gpio0 30 0>;
|
||||
modes-map = <NS_V2_LED_OFF 1 0
|
||||
NS_V2_LED_ON 0 1
|
||||
NS_V2_LED_ON 1 1
|
||||
NS_V2_LED_SATA 0 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/leds/leds-ns2.h>
|
||||
#include "kirkwood-ns2-common.dtsi"
|
||||
|
||||
/ {
|
||||
|
@ -27,6 +28,10 @@
|
|||
label = "ns2:blue:sata";
|
||||
slow-gpio = <&gpio0 29 0>;
|
||||
cmd-gpio = <&gpio0 30 0>;
|
||||
modes-map = <NS_V2_LED_OFF 1 0
|
||||
NS_V2_LED_ON 0 1
|
||||
NS_V2_LED_ON 1 1
|
||||
NS_V2_LED_SATA 0 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/leds/leds-ns2.h>
|
||||
#include "kirkwood-ns2-common.dtsi"
|
||||
|
||||
/ {
|
||||
|
@ -46,6 +47,10 @@
|
|||
label = "ns2:blue:sata";
|
||||
slow-gpio = <&gpio0 29 0>;
|
||||
cmd-gpio = <&gpio0 30 0>;
|
||||
modes-map = <NS_V2_LED_OFF 1 0
|
||||
NS_V2_LED_ON 0 1
|
||||
NS_V2_LED_ON 1 1
|
||||
NS_V2_LED_SATA 0 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/leds/leds-ns2.h>
|
||||
#include "kirkwood-ns2-common.dtsi"
|
||||
|
||||
/ {
|
||||
|
@ -47,6 +48,10 @@
|
|||
label = "ns2:blue:sata";
|
||||
slow-gpio = <&gpio0 29 0>;
|
||||
cmd-gpio = <&gpio0 30 0>;
|
||||
modes-map = <NS_V2_LED_OFF 1 0
|
||||
NS_V2_LED_ON 0 1
|
||||
NS_V2_LED_ON 1 1
|
||||
NS_V2_LED_SATA 0 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -43,7 +43,7 @@ config LEDS_AAT1290
|
|||
tristate "LED support for the AAT1290"
|
||||
depends on LEDS_CLASS_FLASH
|
||||
depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
|
||||
depends on GPIOLIB
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
depends on OF
|
||||
depends on PINCTRL
|
||||
help
|
||||
|
@ -419,7 +419,7 @@ config LEDS_INTEL_SS4200
|
|||
config LEDS_LT3593
|
||||
tristate "LED driver for LT3593 controllers"
|
||||
depends on LEDS_CLASS
|
||||
depends on GPIOLIB
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
help
|
||||
This option enables support for LEDs driven by a Linear Technology
|
||||
LT3593 controller. This controller uses a special one-wire pulse
|
||||
|
@ -455,12 +455,16 @@ config LEDS_MC13783
|
|||
config LEDS_NS2
|
||||
tristate "LED support for Network Space v2 GPIO LEDs"
|
||||
depends on LEDS_CLASS
|
||||
depends on MACH_KIRKWOOD
|
||||
depends on MACH_KIRKWOOD || MACH_ARMADA_370
|
||||
default y
|
||||
help
|
||||
This option enable support for the dual-GPIO LED found on the
|
||||
Network Space v2 board (and parents). This include Internet Space v2,
|
||||
Network Space (Max) v2 and d2 Network v2 boards.
|
||||
This option enables support for the dual-GPIO LEDs found on the
|
||||
following LaCie/Seagate boards:
|
||||
|
||||
Network Space v2 (and parents: Max, Mini)
|
||||
Internet Space v2
|
||||
d2 Network v2
|
||||
n090401 (Seagate NAS 4-Bay)
|
||||
|
||||
config LEDS_NETXBIG
|
||||
tristate "LED support for Big Network series LEDs"
|
||||
|
@ -543,7 +547,8 @@ config LEDS_MENF21BMC
|
|||
|
||||
config LEDS_KTD2692
|
||||
tristate "LED support for KTD2692 flash LED controller"
|
||||
depends on LEDS_CLASS_FLASH && GPIOLIB && OF
|
||||
depends on LEDS_CLASS_FLASH && OF
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
help
|
||||
This option enables support for KTD2692 LED flash connected
|
||||
through ExpressWire interface.
|
||||
|
|
|
@ -228,12 +228,15 @@ static int led_classdev_next_name(const char *init_name, char *name,
|
|||
{
|
||||
unsigned int i = 0;
|
||||
int ret = 0;
|
||||
struct device *dev;
|
||||
|
||||
strlcpy(name, init_name, len);
|
||||
|
||||
while (class_find_device(leds_class, NULL, name, match_name) &&
|
||||
(ret < len))
|
||||
while ((ret < len) &&
|
||||
(dev = class_find_device(leds_class, NULL, name, match_name))) {
|
||||
put_device(dev);
|
||||
ret = snprintf(name, len, "%s_%u", init_name, ++i);
|
||||
}
|
||||
|
||||
if (ret >= len)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -156,63 +156,35 @@ static int fsg_led_probe(struct platform_device *pdev)
|
|||
latch_value = 0xffff;
|
||||
*latch_address = latch_value;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_wlan_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, &fsg_wlan_led);
|
||||
if (ret < 0)
|
||||
goto failwlan;
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_wan_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, &fsg_wan_led);
|
||||
if (ret < 0)
|
||||
goto failwan;
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_sata_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, &fsg_sata_led);
|
||||
if (ret < 0)
|
||||
goto failsata;
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_usb_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, &fsg_usb_led);
|
||||
if (ret < 0)
|
||||
goto failusb;
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_sync_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, &fsg_sync_led);
|
||||
if (ret < 0)
|
||||
goto failsync;
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_ring_led);
|
||||
ret = devm_led_classdev_register(&pdev->dev, &fsg_ring_led);
|
||||
if (ret < 0)
|
||||
goto failring;
|
||||
|
||||
return ret;
|
||||
|
||||
failring:
|
||||
led_classdev_unregister(&fsg_sync_led);
|
||||
failsync:
|
||||
led_classdev_unregister(&fsg_usb_led);
|
||||
failusb:
|
||||
led_classdev_unregister(&fsg_sata_led);
|
||||
failsata:
|
||||
led_classdev_unregister(&fsg_wan_led);
|
||||
failwan:
|
||||
led_classdev_unregister(&fsg_wlan_led);
|
||||
failwlan:
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fsg_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
led_classdev_unregister(&fsg_wlan_led);
|
||||
led_classdev_unregister(&fsg_wan_led);
|
||||
led_classdev_unregister(&fsg_sata_led);
|
||||
led_classdev_unregister(&fsg_usb_led);
|
||||
led_classdev_unregister(&fsg_sync_led);
|
||||
led_classdev_unregister(&fsg_ring_led);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct platform_driver fsg_led_driver = {
|
||||
.probe = fsg_led_probe,
|
||||
.remove = fsg_led_remove,
|
||||
.driver = {
|
||||
.name = "fsg-led",
|
||||
},
|
||||
|
|
|
@ -492,7 +492,6 @@ static struct i2c_driver lm3530_i2c_driver = {
|
|||
.id_table = lm3530_id,
|
||||
.driver = {
|
||||
.name = LM3530_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -555,7 +555,6 @@ MODULE_DEVICE_TABLE(i2c, lm355x_id);
|
|||
static struct i2c_driver lm355x_i2c_driver = {
|
||||
.driver = {
|
||||
.name = LM355x_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = NULL,
|
||||
},
|
||||
.probe = lm355x_probe,
|
||||
|
|
|
@ -446,7 +446,6 @@ MODULE_DEVICE_TABLE(i2c, lm3642_id);
|
|||
static struct i2c_driver lm3642_i2c_driver = {
|
||||
.driver = {
|
||||
.name = LM3642_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = NULL,
|
||||
},
|
||||
.probe = lm3642_probe,
|
||||
|
|
|
@ -514,20 +514,19 @@ static int lp5521_probe(struct i2c_client *client,
|
|||
int ret;
|
||||
struct lp55xx_chip *chip;
|
||||
struct lp55xx_led *led;
|
||||
struct lp55xx_platform_data *pdata;
|
||||
struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
struct device_node *np = client->dev.of_node;
|
||||
|
||||
if (!dev_get_platdata(&client->dev)) {
|
||||
if (!pdata) {
|
||||
if (np) {
|
||||
ret = lp55xx_of_populate_pdata(&client->dev, np);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pdata = lp55xx_of_populate_pdata(&client->dev, np);
|
||||
if (IS_ERR(pdata))
|
||||
return PTR_ERR(pdata);
|
||||
} else {
|
||||
dev_err(&client->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
|
||||
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
|
|
|
@ -880,20 +880,19 @@ static int lp5523_probe(struct i2c_client *client,
|
|||
int ret;
|
||||
struct lp55xx_chip *chip;
|
||||
struct lp55xx_led *led;
|
||||
struct lp55xx_platform_data *pdata;
|
||||
struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
struct device_node *np = client->dev.of_node;
|
||||
|
||||
if (!dev_get_platdata(&client->dev)) {
|
||||
if (!pdata) {
|
||||
if (np) {
|
||||
ret = lp55xx_of_populate_pdata(&client->dev, np);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pdata = lp55xx_of_populate_pdata(&client->dev, np);
|
||||
if (IS_ERR(pdata))
|
||||
return PTR_ERR(pdata);
|
||||
} else {
|
||||
dev_err(&client->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
|
||||
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
|
|
|
@ -515,20 +515,19 @@ static int lp5562_probe(struct i2c_client *client,
|
|||
int ret;
|
||||
struct lp55xx_chip *chip;
|
||||
struct lp55xx_led *led;
|
||||
struct lp55xx_platform_data *pdata;
|
||||
struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
struct device_node *np = client->dev.of_node;
|
||||
|
||||
if (!dev_get_platdata(&client->dev)) {
|
||||
if (!pdata) {
|
||||
if (np) {
|
||||
ret = lp55xx_of_populate_pdata(&client->dev, np);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pdata = lp55xx_of_populate_pdata(&client->dev, np);
|
||||
if (IS_ERR(pdata))
|
||||
return PTR_ERR(pdata);
|
||||
} else {
|
||||
dev_err(&client->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
|
||||
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
|
|
|
@ -543,7 +543,8 @@ void lp55xx_unregister_sysfs(struct lp55xx_chip *chip)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs);
|
||||
|
||||
int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np)
|
||||
struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev,
|
||||
struct device_node *np)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct lp55xx_platform_data *pdata;
|
||||
|
@ -553,17 +554,17 @@ int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np)
|
|||
|
||||
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
num_channels = of_get_child_count(np);
|
||||
if (num_channels == 0) {
|
||||
dev_err(dev, "no LED channels\n");
|
||||
return -EINVAL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
cfg = devm_kzalloc(dev, sizeof(*cfg) * num_channels, GFP_KERNEL);
|
||||
if (!cfg)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pdata->led_config = &cfg[0];
|
||||
pdata->num_channels = num_channels;
|
||||
|
@ -588,9 +589,7 @@ int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np)
|
|||
/* LP8501 specific */
|
||||
of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel);
|
||||
|
||||
dev->platform_data = pdata;
|
||||
|
||||
return 0;
|
||||
return pdata;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata);
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ extern int lp55xx_register_sysfs(struct lp55xx_chip *chip);
|
|||
extern void lp55xx_unregister_sysfs(struct lp55xx_chip *chip);
|
||||
|
||||
/* common device tree population function */
|
||||
extern int lp55xx_of_populate_pdata(struct device *dev,
|
||||
struct device_node *np);
|
||||
extern struct lp55xx_platform_data
|
||||
*lp55xx_of_populate_pdata(struct device *dev, struct device_node *np);
|
||||
|
||||
#endif /* _LEDS_LP55XX_COMMON_H */
|
||||
|
|
|
@ -308,20 +308,19 @@ static int lp8501_probe(struct i2c_client *client,
|
|||
int ret;
|
||||
struct lp55xx_chip *chip;
|
||||
struct lp55xx_led *led;
|
||||
struct lp55xx_platform_data *pdata;
|
||||
struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
struct device_node *np = client->dev.of_node;
|
||||
|
||||
if (!dev_get_platdata(&client->dev)) {
|
||||
if (!pdata) {
|
||||
if (np) {
|
||||
ret = lp55xx_of_populate_pdata(&client->dev, np);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pdata = lp55xx_of_populate_pdata(&client->dev, np);
|
||||
if (IS_ERR(pdata))
|
||||
return PTR_ERR(pdata);
|
||||
} else {
|
||||
dev_err(&client->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
|
||||
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
|
|
|
@ -302,7 +302,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct reg_default lp8860_reg_defs[] = {
|
||||
static const struct reg_default lp8860_reg_defs[] = {
|
||||
{ LP8860_DISP_CL1_BRT_MSB, 0x00},
|
||||
{ LP8860_DISP_CL1_BRT_LSB, 0x00},
|
||||
{ LP8860_DISP_CL1_CURR_MSB, 0x00},
|
||||
|
@ -332,7 +332,7 @@ static const struct regmap_config lp8860_regmap_config = {
|
|||
.cache_type = REGCACHE_NONE,
|
||||
};
|
||||
|
||||
static struct reg_default lp8860_eeprom_defs[] = {
|
||||
static const struct reg_default lp8860_eeprom_defs[] = {
|
||||
{ LP8860_EEPROM_REG_0, 0x00 },
|
||||
{ LP8860_EEPROM_REG_1, 0x00 },
|
||||
{ LP8860_EEPROM_REG_2, 0x00 },
|
||||
|
|
|
@ -31,50 +31,38 @@
|
|||
#include <linux/platform_data/leds-kirkwood-ns2.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include "leds.h"
|
||||
|
||||
/*
|
||||
* The Network Space v2 dual-GPIO LED is wired to a CPLD and can blink in
|
||||
* relation with the SATA activity. This capability is exposed through the
|
||||
* "sata" sysfs attribute.
|
||||
*
|
||||
* The following array detail the different LED registers and the combination
|
||||
* of their possible values:
|
||||
*
|
||||
* cmd_led | slow_led | /SATA active | LED state
|
||||
* | | |
|
||||
* 1 | 0 | x | off
|
||||
* - | 1 | x | on
|
||||
* 0 | 0 | 1 | on
|
||||
* 0 | 0 | 0 | blink (rate 300ms)
|
||||
* The Network Space v2 dual-GPIO LED is wired to a CPLD. Three different LED
|
||||
* modes are available: off, on and SATA activity blinking. The LED modes are
|
||||
* controlled through two GPIOs (command and slow): each combination of values
|
||||
* for the command/slow GPIOs corresponds to a LED mode.
|
||||
*/
|
||||
|
||||
enum ns2_led_modes {
|
||||
NS_V2_LED_OFF,
|
||||
NS_V2_LED_ON,
|
||||
NS_V2_LED_SATA,
|
||||
};
|
||||
|
||||
struct ns2_led_mode_value {
|
||||
enum ns2_led_modes mode;
|
||||
int cmd_level;
|
||||
int slow_level;
|
||||
};
|
||||
|
||||
static struct ns2_led_mode_value ns2_led_modval[] = {
|
||||
{ NS_V2_LED_OFF , 1, 0 },
|
||||
{ NS_V2_LED_ON , 0, 1 },
|
||||
{ NS_V2_LED_ON , 1, 1 },
|
||||
{ NS_V2_LED_SATA, 0, 0 },
|
||||
};
|
||||
|
||||
struct ns2_led_data {
|
||||
struct led_classdev cdev;
|
||||
unsigned cmd;
|
||||
unsigned slow;
|
||||
bool can_sleep;
|
||||
int mode_index;
|
||||
unsigned char sata; /* True when SATA mode active. */
|
||||
rwlock_t rw_lock; /* Lock GPIOs. */
|
||||
struct work_struct work;
|
||||
int num_modes;
|
||||
struct ns2_led_modval *modval;
|
||||
};
|
||||
|
||||
static void ns2_led_work(struct work_struct *work)
|
||||
{
|
||||
struct ns2_led_data *led_dat =
|
||||
container_of(work, struct ns2_led_data, work);
|
||||
int i = led_dat->mode_index;
|
||||
|
||||
gpio_set_value_cansleep(led_dat->cmd, led_dat->modval[i].cmd_level);
|
||||
gpio_set_value_cansleep(led_dat->slow, led_dat->modval[i].slow_level);
|
||||
}
|
||||
|
||||
static int ns2_led_get_mode(struct ns2_led_data *led_dat,
|
||||
enum ns2_led_modes *mode)
|
||||
{
|
||||
|
@ -83,22 +71,18 @@ static int ns2_led_get_mode(struct ns2_led_data *led_dat,
|
|||
int cmd_level;
|
||||
int slow_level;
|
||||
|
||||
read_lock_irq(&led_dat->rw_lock);
|
||||
cmd_level = gpio_get_value_cansleep(led_dat->cmd);
|
||||
slow_level = gpio_get_value_cansleep(led_dat->slow);
|
||||
|
||||
cmd_level = gpio_get_value(led_dat->cmd);
|
||||
slow_level = gpio_get_value(led_dat->slow);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) {
|
||||
if (cmd_level == ns2_led_modval[i].cmd_level &&
|
||||
slow_level == ns2_led_modval[i].slow_level) {
|
||||
*mode = ns2_led_modval[i].mode;
|
||||
for (i = 0; i < led_dat->num_modes; i++) {
|
||||
if (cmd_level == led_dat->modval[i].cmd_level &&
|
||||
slow_level == led_dat->modval[i].slow_level) {
|
||||
*mode = led_dat->modval[i].mode;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
read_unlock_irq(&led_dat->rw_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -106,19 +90,32 @@ static void ns2_led_set_mode(struct ns2_led_data *led_dat,
|
|||
enum ns2_led_modes mode)
|
||||
{
|
||||
int i;
|
||||
bool found = false;
|
||||
unsigned long flags;
|
||||
|
||||
for (i = 0; i < led_dat->num_modes; i++)
|
||||
if (mode == led_dat->modval[i].mode) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return;
|
||||
|
||||
write_lock_irqsave(&led_dat->rw_lock, flags);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) {
|
||||
if (mode == ns2_led_modval[i].mode) {
|
||||
gpio_set_value(led_dat->cmd,
|
||||
ns2_led_modval[i].cmd_level);
|
||||
gpio_set_value(led_dat->slow,
|
||||
ns2_led_modval[i].slow_level);
|
||||
}
|
||||
if (!led_dat->can_sleep) {
|
||||
gpio_set_value(led_dat->cmd,
|
||||
led_dat->modval[i].cmd_level);
|
||||
gpio_set_value(led_dat->slow,
|
||||
led_dat->modval[i].slow_level);
|
||||
goto exit_unlock;
|
||||
}
|
||||
|
||||
led_dat->mode_index = i;
|
||||
schedule_work(&led_dat->work);
|
||||
|
||||
exit_unlock:
|
||||
write_unlock_irqrestore(&led_dat->rw_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -148,7 +145,6 @@ static ssize_t ns2_led_sata_store(struct device *dev,
|
|||
container_of(led_cdev, struct ns2_led_data, cdev);
|
||||
int ret;
|
||||
unsigned long enable;
|
||||
enum ns2_led_modes mode;
|
||||
|
||||
ret = kstrtoul(buff, 10, &enable);
|
||||
if (ret < 0)
|
||||
|
@ -157,19 +153,19 @@ static ssize_t ns2_led_sata_store(struct device *dev,
|
|||
enable = !!enable;
|
||||
|
||||
if (led_dat->sata == enable)
|
||||
return count;
|
||||
|
||||
ret = ns2_led_get_mode(led_dat, &mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (enable && mode == NS_V2_LED_ON)
|
||||
ns2_led_set_mode(led_dat, NS_V2_LED_SATA);
|
||||
if (!enable && mode == NS_V2_LED_SATA)
|
||||
ns2_led_set_mode(led_dat, NS_V2_LED_ON);
|
||||
goto exit;
|
||||
|
||||
led_dat->sata = enable;
|
||||
|
||||
if (!led_get_brightness(led_cdev))
|
||||
goto exit;
|
||||
|
||||
if (enable)
|
||||
ns2_led_set_mode(led_dat, NS_V2_LED_SATA);
|
||||
else
|
||||
ns2_led_set_mode(led_dat, NS_V2_LED_ON);
|
||||
|
||||
exit:
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -199,7 +195,7 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
|
|||
enum ns2_led_modes mode;
|
||||
|
||||
ret = devm_gpio_request_one(&pdev->dev, template->cmd,
|
||||
gpio_get_value(template->cmd) ?
|
||||
gpio_get_value_cansleep(template->cmd) ?
|
||||
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
|
||||
template->name);
|
||||
if (ret) {
|
||||
|
@ -209,7 +205,7 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
|
|||
}
|
||||
|
||||
ret = devm_gpio_request_one(&pdev->dev, template->slow,
|
||||
gpio_get_value(template->slow) ?
|
||||
gpio_get_value_cansleep(template->slow) ?
|
||||
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
|
||||
template->name);
|
||||
if (ret) {
|
||||
|
@ -228,6 +224,10 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
|
|||
led_dat->cdev.groups = ns2_led_groups;
|
||||
led_dat->cmd = template->cmd;
|
||||
led_dat->slow = template->slow;
|
||||
led_dat->can_sleep = gpio_cansleep(led_dat->cmd) |
|
||||
gpio_cansleep(led_dat->slow);
|
||||
led_dat->modval = template->modval;
|
||||
led_dat->num_modes = template->num_modes;
|
||||
|
||||
ret = ns2_led_get_mode(led_dat, &mode);
|
||||
if (ret < 0)
|
||||
|
@ -238,6 +238,8 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
|
|||
led_dat->cdev.brightness =
|
||||
(mode == NS_V2_LED_OFF) ? LED_OFF : LED_FULL;
|
||||
|
||||
INIT_WORK(&led_dat->work, ns2_led_work);
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -248,6 +250,7 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
|
|||
static void delete_ns2_led(struct ns2_led_data *led_dat)
|
||||
{
|
||||
led_classdev_unregister(&led_dat->cdev);
|
||||
cancel_work_sync(&led_dat->work);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_GPIO
|
||||
|
@ -259,9 +262,8 @@ ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)
|
|||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
struct device_node *child;
|
||||
struct ns2_led *leds;
|
||||
struct ns2_led *led, *leds;
|
||||
int num_leds = 0;
|
||||
int i = 0;
|
||||
|
||||
num_leds = of_get_child_count(np);
|
||||
if (!num_leds)
|
||||
|
@ -272,26 +274,57 @@ ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)
|
|||
if (!leds)
|
||||
return -ENOMEM;
|
||||
|
||||
led = leds;
|
||||
for_each_child_of_node(np, child) {
|
||||
const char *string;
|
||||
int ret;
|
||||
int ret, i, num_modes;
|
||||
struct ns2_led_modval *modval;
|
||||
|
||||
ret = of_get_named_gpio(child, "cmd-gpio", 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
leds[i].cmd = ret;
|
||||
led->cmd = ret;
|
||||
ret = of_get_named_gpio(child, "slow-gpio", 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
leds[i].slow = ret;
|
||||
led->slow = ret;
|
||||
ret = of_property_read_string(child, "label", &string);
|
||||
leds[i].name = (ret == 0) ? string : child->name;
|
||||
led->name = (ret == 0) ? string : child->name;
|
||||
ret = of_property_read_string(child, "linux,default-trigger",
|
||||
&string);
|
||||
if (ret == 0)
|
||||
leds[i].default_trigger = string;
|
||||
led->default_trigger = string;
|
||||
|
||||
i++;
|
||||
ret = of_property_count_u32_elems(child, "modes-map");
|
||||
if (ret < 0 || ret % 3) {
|
||||
dev_err(dev,
|
||||
"Missing or malformed modes-map property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
num_modes = ret / 3;
|
||||
modval = devm_kzalloc(dev,
|
||||
num_modes * sizeof(struct ns2_led_modval),
|
||||
GFP_KERNEL);
|
||||
if (!modval)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num_modes; i++) {
|
||||
of_property_read_u32_index(child,
|
||||
"modes-map", 3 * i,
|
||||
(u32 *) &modval[i].mode);
|
||||
of_property_read_u32_index(child,
|
||||
"modes-map", 3 * i + 1,
|
||||
(u32 *) &modval[i].cmd_level);
|
||||
of_property_read_u32_index(child,
|
||||
"modes-map", 3 * i + 2,
|
||||
(u32 *) &modval[i].slow_level);
|
||||
}
|
||||
|
||||
led->num_modes = num_modes;
|
||||
led->modval = modval;
|
||||
|
||||
led++;
|
||||
}
|
||||
|
||||
pdata->leds = leds;
|
||||
|
|
|
@ -379,7 +379,6 @@ static int pca955x_remove(struct i2c_client *client)
|
|||
static struct i2c_driver pca955x_driver = {
|
||||
.driver = {
|
||||
.name = "leds-pca955x",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = pca955x_probe,
|
||||
.remove = pca955x_remove,
|
||||
|
|
|
@ -332,6 +332,7 @@ static const struct of_device_id of_pca963x_match[] = {
|
|||
{ .compatible = "nxp,pca9635", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_pca963x_match);
|
||||
#else
|
||||
static struct pca963x_platform_data *
|
||||
pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip)
|
||||
|
@ -458,7 +459,6 @@ static int pca963x_remove(struct i2c_client *client)
|
|||
static struct i2c_driver pca963x_driver = {
|
||||
.driver = {
|
||||
.name = "leds-pca963x",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(of_pca963x_match),
|
||||
},
|
||||
.probe = pca963x_probe,
|
||||
|
|
|
@ -83,9 +83,9 @@ static int syscon_led_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
map = syscon_node_to_regmap(parent->of_node);
|
||||
if (!map) {
|
||||
if (IS_ERR(map)) {
|
||||
dev_err(dev, "no regmap for syscon LED parent\n");
|
||||
return -ENODEV;
|
||||
return PTR_ERR(map);
|
||||
}
|
||||
|
||||
sled = devm_kzalloc(dev, sizeof(*sled), GFP_KERNEL);
|
||||
|
|
|
@ -735,6 +735,7 @@ static const struct of_device_id of_tca6507_leds_match[] = {
|
|||
{ .compatible = "ti,tca6507", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_tca6507_leds_match);
|
||||
|
||||
#else
|
||||
static struct tca6507_platform_data *
|
||||
|
@ -830,7 +831,6 @@ static int tca6507_remove(struct i2c_client *client)
|
|||
static struct i2c_driver tca6507_driver = {
|
||||
.driver = {
|
||||
.name = "leds-tca6507",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(of_tca6507_leds_match),
|
||||
},
|
||||
.probe = tca6507_probe,
|
||||
|
|
|
@ -231,10 +231,6 @@ tlc591xx_probe(struct i2c_client *client,
|
|||
if (!count || count > tlc591xx->max_leds)
|
||||
return -EINVAL;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -EIO;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -72,7 +72,7 @@ config LEDS_TRIGGER_CPU
|
|||
config LEDS_TRIGGER_GPIO
|
||||
tristate "LED GPIO Trigger"
|
||||
depends on LEDS_TRIGGERS
|
||||
depends on GPIOLIB
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
help
|
||||
This allows LEDs to be controlled by gpio events. It's good
|
||||
when using gpios as switches and triggering the needed LEDs
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _DT_BINDINGS_LEDS_NS2_H
|
||||
#define _DT_BINDINGS_LEDS_NS2_H
|
||||
|
||||
#define NS_V2_LED_OFF 0
|
||||
#define NS_V2_LED_ON 1
|
||||
#define NS_V2_LED_SATA 2
|
||||
|
||||
#endif
|
|
@ -9,11 +9,25 @@
|
|||
#ifndef __LEDS_KIRKWOOD_NS2_H
|
||||
#define __LEDS_KIRKWOOD_NS2_H
|
||||
|
||||
enum ns2_led_modes {
|
||||
NS_V2_LED_OFF,
|
||||
NS_V2_LED_ON,
|
||||
NS_V2_LED_SATA,
|
||||
};
|
||||
|
||||
struct ns2_led_modval {
|
||||
enum ns2_led_modes mode;
|
||||
int cmd_level;
|
||||
int slow_level;
|
||||
};
|
||||
|
||||
struct ns2_led {
|
||||
const char *name;
|
||||
const char *default_trigger;
|
||||
unsigned cmd;
|
||||
unsigned slow;
|
||||
int num_modes;
|
||||
struct ns2_led_modval *modval;
|
||||
};
|
||||
|
||||
struct ns2_led_platform_data {
|
||||
|
|
Loading…
Reference in New Issue