forked from Minki/linux
LED updates for 4.13
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJZXUGpAAoJEL1qUBy3i3wmBdgP/jhpBsA9D+W4grLEzbTSTWSV GKm19egbgujyLWkTecs1ICtuPYQFI90xV2HqmoSsXa9BEZHErB7zbubBzPEqS4RW ghsqweaLllOe6LtHs/ZvgvTGILaivpvK1R9qawaqJi6Cmg0VZvG8ApQNNpQD6bnj YCknKetLK+pdcjVCTaG7hyf+Ess7ASrwiWwIBiU26K+X6p7YpilxT5AylYWH6erl s+Lr3U0As86Fj+/ELOgmYBMTO1phZ7r1FSR/sa7RTlfgEgJQxmgagCfAvPGH92K3 gK0UKKKirzfU08nUliHeHqn1K9ZaTKS15bbRNHpzl3/be/oLCuN3kB/Y/ZWtPgOc pEaCkWn2+4TeChlznyEmmTAeJgKLOBlt8ffSlz+wWNNL9wjG/LVm0Gq/eO49rWsG fJVbAT/lnWQ5dVEXlzQbw4uKU8DZDpjChjkv7shLMcValUtysnJ/w3edl5Czyx0y s2ckFmWnmQwTd+//PoJYnfdywPc3NfpsJD2j2VrEc0unsodAszwrdHdFVmsSgAJY u6cbrrxWYakXUcV/6gKVybhdMpNsV4f2KDthxrZmN3JGetQU/zoNsMBrNJu30l3d Iifry+UlYNHoozITKyk1+J3atEF6YzMIhuJTP1ifN07tvo5WaSESPFuoJdxLFlyt 4OZcjjWj+CGqZ6+RSUya =5JLc -----END PGP SIGNATURE----- Merge tag 'leds_for_4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds Pull LED updates from Jacek Anaszewski: "This time we're removing more than adding: Removed drivers: leds-versatile: - all users of the Versatile LED driver are deleted and replaced with the very generic leds-syscon leds-sead3: - SEAD3 is using the generic leds-syscon & regmap based register-bit-led driver LED class drivers improvements: ledtrig-gpio: - use threaded IRQ, which both simplifies the code because we can drop the workqueue indirection, and it enables using the trigger for GPIOs that work with threaded IRQs themselves - refresh LED state after GPIO change since the new GPIO may have a different state than the old one leds-lp55xx: - make various arrays static const leds-pca963x: - add bindings to invert polarity" * tag 'leds_for_4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds: leds: lp55xx: make various arrays static const leds: Remove SEAD-3 driver leds: trigger: gpio: Use threaded IRQ leds: trigger: gpio: Refresh LED state after GPIO change leds: Delete obsolete Versatile driver leds: pca963x: Add bindings to invert polarity
This commit is contained in:
commit
4f5dfdd290
@ -10,6 +10,7 @@ Optional properties:
|
||||
- nxp,period-scale : In some configurations, the chip blinks faster than expected.
|
||||
This parameter provides a scaling ratio (fixed point, decimal divided
|
||||
by 1000) to compensate, e.g. 1300=1.3x and 750=0.75x.
|
||||
- nxp,inverted-out: invert the polarity of the generated PWM
|
||||
|
||||
Each led is represented as a sub-node of the nxp,pca963x device.
|
||||
|
||||
|
@ -590,16 +590,6 @@ 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.
|
||||
|
||||
config LEDS_IS31FL319X
|
||||
tristate "LED Support for ISSI IS31FL319x I2C LED controller family"
|
||||
depends on LEDS_CLASS && I2C && OF
|
||||
@ -651,14 +641,6 @@ config LEDS_SYSCON
|
||||
devices. This will only work with device tree enabled
|
||||
devices.
|
||||
|
||||
config LEDS_VERSATILE
|
||||
tristate "LED support for the ARM Versatile and RealView"
|
||||
depends on ARCH_REALVIEW || ARCH_VERSATILE
|
||||
depends on LEDS_CLASS
|
||||
help
|
||||
This option enabled support for the LEDs on the ARM Versatile
|
||||
and RealView boards. Say Y to enabled these.
|
||||
|
||||
config LEDS_PM8058
|
||||
tristate "LED Support for the Qualcomm PM8058 PMIC"
|
||||
depends on MFD_PM8XXX
|
||||
|
@ -62,11 +62,9 @@ obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
|
||||
obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
|
||||
obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
|
||||
obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o
|
||||
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
|
||||
obj-$(CONFIG_LEDS_IS31FL319X) += leds-is31fl319x.o
|
||||
obj-$(CONFIG_LEDS_IS31FL32XX) += leds-is31fl32xx.o
|
||||
obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o
|
||||
|
@ -168,13 +168,13 @@ static int lp5523_post_init_device(struct lp55xx_chip *chip)
|
||||
static void lp5523_load_engine(struct lp55xx_chip *chip)
|
||||
{
|
||||
enum lp55xx_engine_index idx = chip->engine_idx;
|
||||
u8 mask[] = {
|
||||
static const u8 mask[] = {
|
||||
[LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M,
|
||||
[LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M,
|
||||
[LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M,
|
||||
};
|
||||
|
||||
u8 val[] = {
|
||||
static const u8 val[] = {
|
||||
[LP55XX_ENGINE_1] = LP5523_LOAD_ENG1,
|
||||
[LP55XX_ENGINE_2] = LP5523_LOAD_ENG2,
|
||||
[LP55XX_ENGINE_3] = LP5523_LOAD_ENG3,
|
||||
@ -188,7 +188,7 @@ static void lp5523_load_engine(struct lp55xx_chip *chip)
|
||||
static void lp5523_load_engine_and_select_page(struct lp55xx_chip *chip)
|
||||
{
|
||||
enum lp55xx_engine_index idx = chip->engine_idx;
|
||||
u8 page_sel[] = {
|
||||
static const u8 page_sel[] = {
|
||||
[LP55XX_ENGINE_1] = LP5523_PAGE_ENG1,
|
||||
[LP55XX_ENGINE_2] = LP5523_PAGE_ENG2,
|
||||
[LP55XX_ENGINE_3] = LP5523_PAGE_ENG3,
|
||||
@ -208,7 +208,7 @@ static void lp5523_stop_all_engines(struct lp55xx_chip *chip)
|
||||
static void lp5523_stop_engine(struct lp55xx_chip *chip)
|
||||
{
|
||||
enum lp55xx_engine_index idx = chip->engine_idx;
|
||||
u8 mask[] = {
|
||||
static const u8 mask[] = {
|
||||
[LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M,
|
||||
[LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M,
|
||||
[LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M,
|
||||
@ -505,7 +505,7 @@ static int lp5523_load_mux(struct lp55xx_chip *chip, u16 mux, int nr)
|
||||
{
|
||||
struct lp55xx_engine *engine = &chip->engines[nr - 1];
|
||||
int ret;
|
||||
u8 mux_page[] = {
|
||||
static const u8 mux_page[] = {
|
||||
[LP55XX_ENGINE_1] = LP5523_PAGE_MUX1,
|
||||
[LP55XX_ENGINE_2] = LP5523_PAGE_MUX2,
|
||||
[LP55XX_ENGINE_3] = LP5523_PAGE_MUX3,
|
||||
|
@ -342,6 +342,12 @@ pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip)
|
||||
if (of_property_read_u32(np, "nxp,period-scale", &chip->scaling))
|
||||
chip->scaling = 1000;
|
||||
|
||||
/* default to non-inverted output, unless inverted is specified */
|
||||
if (of_property_read_bool(np, "nxp,inverted-out"))
|
||||
pdata->dir = PCA963X_INVERTED;
|
||||
else
|
||||
pdata->dir = PCA963X_NORMAL;
|
||||
|
||||
return pdata;
|
||||
}
|
||||
|
||||
@ -452,11 +458,18 @@ static int pca963x_probe(struct i2c_client *client,
|
||||
i2c_smbus_write_byte_data(client, PCA963X_MODE1, BIT(4));
|
||||
|
||||
if (pdata) {
|
||||
u8 mode2 = i2c_smbus_read_byte_data(pca963x->chip->client,
|
||||
PCA963X_MODE2);
|
||||
/* Configure output: open-drain or totem pole (push-pull) */
|
||||
if (pdata->outdrv == PCA963X_OPEN_DRAIN)
|
||||
i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x01);
|
||||
mode2 |= 0x01;
|
||||
else
|
||||
i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x05);
|
||||
mode2 |= 0x05;
|
||||
/* Configure direction: normal or inverted */
|
||||
if (pdata->dir == PCA963X_INVERTED)
|
||||
mode2 |= 0x10;
|
||||
i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2,
|
||||
mode2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||
* Copyright (C) 2015 Imagination Technologies, Inc.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/mips-boards/sead3-addr.h>
|
||||
|
||||
static void sead3_pled_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
writel(value, (void __iomem *)SEAD3_CPLD_P_LED);
|
||||
}
|
||||
|
||||
static void sead3_fled_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
writel(value, (void __iomem *)SEAD3_CPLD_F_LED);
|
||||
}
|
||||
|
||||
static struct led_classdev sead3_pled = {
|
||||
.name = "sead3::pled",
|
||||
.brightness_set = sead3_pled_set,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
};
|
||||
|
||||
static struct led_classdev sead3_fled = {
|
||||
.name = "sead3::fled",
|
||||
.brightness_set = sead3_fled_set,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
};
|
||||
|
||||
static int sead3_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &sead3_pled);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &sead3_fled);
|
||||
if (ret < 0)
|
||||
led_classdev_unregister(&sead3_pled);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sead3_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
led_classdev_unregister(&sead3_pled);
|
||||
led_classdev_unregister(&sead3_fled);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver sead3_led_driver = {
|
||||
.probe = sead3_led_probe,
|
||||
.remove = sead3_led_remove,
|
||||
.driver = {
|
||||
.name = "sead3-led",
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(sead3_led_driver);
|
||||
|
||||
MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>");
|
||||
MODULE_DESCRIPTION("SEAD3 LED driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Driver for the 8 user LEDs found on the RealViews and Versatiles
|
||||
* Based on DaVinci's DM365 board code
|
||||
*
|
||||
* License terms: GNU General Public License (GPL) version 2
|
||||
* Author: Linus Walleij <triad@df.lth.se>
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
struct versatile_led {
|
||||
void __iomem *base;
|
||||
struct led_classdev cdev;
|
||||
u8 mask;
|
||||
};
|
||||
|
||||
/*
|
||||
* The triggers lines up below will only be used if the
|
||||
* LED triggers are compiled in.
|
||||
*/
|
||||
static const struct {
|
||||
const char *name;
|
||||
const char *trigger;
|
||||
} versatile_leds[] = {
|
||||
{ "versatile:0", "heartbeat", },
|
||||
{ "versatile:1", "mmc0", },
|
||||
{ "versatile:2", "cpu0" },
|
||||
{ "versatile:3", "cpu1" },
|
||||
{ "versatile:4", "cpu2" },
|
||||
{ "versatile:5", "cpu3" },
|
||||
{ "versatile:6", },
|
||||
{ "versatile:7", },
|
||||
};
|
||||
|
||||
static void versatile_led_set(struct led_classdev *cdev,
|
||||
enum led_brightness b)
|
||||
{
|
||||
struct versatile_led *led = container_of(cdev,
|
||||
struct versatile_led, cdev);
|
||||
u32 reg = readl(led->base);
|
||||
|
||||
if (b != LED_OFF)
|
||||
reg |= led->mask;
|
||||
else
|
||||
reg &= ~led->mask;
|
||||
writel(reg, led->base);
|
||||
}
|
||||
|
||||
static enum led_brightness versatile_led_get(struct led_classdev *cdev)
|
||||
{
|
||||
struct versatile_led *led = container_of(cdev,
|
||||
struct versatile_led, cdev);
|
||||
u32 reg = readl(led->base);
|
||||
|
||||
return (reg & led->mask) ? LED_FULL : LED_OFF;
|
||||
}
|
||||
|
||||
static int versatile_leds_probe(struct platform_device *dev)
|
||||
{
|
||||
int i;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
|
||||
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&dev->dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
/* All off */
|
||||
writel(0, base);
|
||||
for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) {
|
||||
struct versatile_led *led;
|
||||
|
||||
led = kzalloc(sizeof(*led), GFP_KERNEL);
|
||||
if (!led)
|
||||
break;
|
||||
|
||||
led->base = base;
|
||||
led->cdev.name = versatile_leds[i].name;
|
||||
led->cdev.brightness_set = versatile_led_set;
|
||||
led->cdev.brightness_get = versatile_led_get;
|
||||
led->cdev.default_trigger = versatile_leds[i].trigger;
|
||||
led->mask = BIT(i);
|
||||
|
||||
if (led_classdev_register(NULL, &led->cdev) < 0) {
|
||||
kfree(led);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver versatile_leds_driver = {
|
||||
.driver = {
|
||||
.name = "versatile-leds",
|
||||
},
|
||||
.probe = versatile_leds_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(versatile_leds_driver);
|
||||
|
||||
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
|
||||
MODULE_DESCRIPTION("ARM Versatile LED driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -14,14 +14,12 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/slab.h>
|
||||
#include "../leds.h"
|
||||
|
||||
struct gpio_trig_data {
|
||||
struct led_classdev *led;
|
||||
struct work_struct work;
|
||||
|
||||
unsigned desired_brightness; /* desired brightness when led is on */
|
||||
unsigned inverted; /* true when gpio is inverted */
|
||||
@ -32,22 +30,8 @@ static irqreturn_t gpio_trig_irq(int irq, void *_led)
|
||||
{
|
||||
struct led_classdev *led = _led;
|
||||
struct gpio_trig_data *gpio_data = led->trigger_data;
|
||||
|
||||
/* just schedule_work since gpio_get_value can sleep */
|
||||
schedule_work(&gpio_data->work);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
};
|
||||
|
||||
static void gpio_trig_work(struct work_struct *work)
|
||||
{
|
||||
struct gpio_trig_data *gpio_data = container_of(work,
|
||||
struct gpio_trig_data, work);
|
||||
int tmp;
|
||||
|
||||
if (!gpio_data->gpio)
|
||||
return;
|
||||
|
||||
tmp = gpio_get_value_cansleep(gpio_data->gpio);
|
||||
if (gpio_data->inverted)
|
||||
tmp = !tmp;
|
||||
@ -61,6 +45,8 @@ static void gpio_trig_work(struct work_struct *work)
|
||||
} else {
|
||||
led_set_brightness_nosleep(gpio_data->led, LED_OFF);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static ssize_t gpio_trig_brightness_show(struct device *dev,
|
||||
@ -120,7 +106,7 @@ static ssize_t gpio_trig_inverted_store(struct device *dev,
|
||||
gpio_data->inverted = inverted;
|
||||
|
||||
/* After inverting, we need to update the LED. */
|
||||
schedule_work(&gpio_data->work);
|
||||
gpio_trig_irq(0, led);
|
||||
|
||||
return n;
|
||||
}
|
||||
@ -147,7 +133,6 @@ static ssize_t gpio_trig_gpio_store(struct device *dev,
|
||||
ret = sscanf(buf, "%u", &gpio);
|
||||
if (ret < 1) {
|
||||
dev_err(dev, "couldn't read gpio number\n");
|
||||
flush_work(&gpio_data->work);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -161,8 +146,8 @@ static ssize_t gpio_trig_gpio_store(struct device *dev,
|
||||
return n;
|
||||
}
|
||||
|
||||
ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq,
|
||||
IRQF_SHARED | IRQF_TRIGGER_RISING
|
||||
ret = request_threaded_irq(gpio_to_irq(gpio), NULL, gpio_trig_irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING
|
||||
| IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
|
||||
if (ret) {
|
||||
dev_err(dev, "request_irq failed with error %d\n", ret);
|
||||
@ -170,6 +155,8 @@ static ssize_t gpio_trig_gpio_store(struct device *dev,
|
||||
if (gpio_data->gpio != 0)
|
||||
free_irq(gpio_to_irq(gpio_data->gpio), led);
|
||||
gpio_data->gpio = gpio;
|
||||
/* After changing the GPIO, we need to update the LED. */
|
||||
gpio_trig_irq(0, led);
|
||||
}
|
||||
|
||||
return ret ? ret : n;
|
||||
@ -199,7 +186,6 @@ static void gpio_trig_activate(struct led_classdev *led)
|
||||
|
||||
gpio_data->led = led;
|
||||
led->trigger_data = gpio_data;
|
||||
INIT_WORK(&gpio_data->work, gpio_trig_work);
|
||||
led->activated = true;
|
||||
|
||||
return;
|
||||
@ -222,7 +208,6 @@ static void gpio_trig_deactivate(struct led_classdev *led)
|
||||
device_remove_file(led->dev, &dev_attr_gpio);
|
||||
device_remove_file(led->dev, &dev_attr_inverted);
|
||||
device_remove_file(led->dev, &dev_attr_desired_brightness);
|
||||
flush_work(&gpio_data->work);
|
||||
if (gpio_data->gpio != 0)
|
||||
free_irq(gpio_to_irq(gpio_data->gpio), led);
|
||||
kfree(gpio_data);
|
||||
|
@ -33,10 +33,16 @@ enum pca963x_blink_type {
|
||||
PCA963X_HW_BLINK,
|
||||
};
|
||||
|
||||
enum pca963x_direction {
|
||||
PCA963X_NORMAL,
|
||||
PCA963X_INVERTED,
|
||||
};
|
||||
|
||||
struct pca963x_platform_data {
|
||||
struct led_platform_data leds;
|
||||
enum pca963x_outdrv outdrv;
|
||||
enum pca963x_blink_type blink_type;
|
||||
enum pca963x_direction dir;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_PCA963X_H*/
|
||||
|
Loading…
Reference in New Issue
Block a user