Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds
* 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds: leds: Add default-on trigger leds: Document the context brightness_set needs leds: Add new driver for the LEDs on the Freecom FSG-3 leds: Add support to leds with readable status leds: enable support for blink_set() platform hook in leds-gpio leds: Cleanup various whitespace and code style issues leds: disable triggers on brightness set leds: Add mail LED support for "Clevo D400P"
This commit is contained in:
Коммит
eb855fd8e7
|
@ -19,6 +19,12 @@ optimises away.
|
|||
|
||||
Complex triggers whilst available to all LEDs have LED specific
|
||||
parameters and work on a per LED basis. The timer trigger is an example.
|
||||
The timer trigger will periodically change the LED brightness between
|
||||
LED_OFF and the current brightness setting. The "on" and "off" time can
|
||||
be specified via /sys/class/leds/<device>/delay_{on,off} in milliseconds.
|
||||
You can change the brightness value of a LED independently of the timer
|
||||
trigger. However, if you set the brightness value to LED_OFF it will
|
||||
also disable the timer trigger.
|
||||
|
||||
You can change triggers in a similar manner to the way an IO scheduler
|
||||
is chosen (via /sys/class/leds/<device>/trigger). Trigger specific
|
||||
|
@ -63,9 +69,9 @@ value if it is called with *delay_on==0 && *delay_off==0 parameters. In
|
|||
this case the driver should give back the chosen value through delay_on
|
||||
and delay_off parameters to the leds subsystem.
|
||||
|
||||
Any call to the brightness_set() callback function should cancel the
|
||||
previously programmed hardware blinking function so setting the brightness
|
||||
to 0 can also cancel the blinking of the LED.
|
||||
Setting the brightness to zero with brightness_set() callback function
|
||||
should completely turn off the LED and cancel the previously programmed
|
||||
hardware blinking function, if any.
|
||||
|
||||
|
||||
Known Issues
|
||||
|
|
|
@ -65,6 +65,12 @@ config LEDS_NET48XX
|
|||
This option enables support for the Soekris net4801 and net4826 error
|
||||
LED.
|
||||
|
||||
config LEDS_FSG
|
||||
tristate "LED Support for the Freecom FSG-3"
|
||||
depends on LEDS_CLASS && MACH_FSG
|
||||
help
|
||||
This option enables support for the LEDs on the Freecom FSG-3.
|
||||
|
||||
config LEDS_WRAP
|
||||
tristate "LED Support for the WRAP series LEDs"
|
||||
depends on LEDS_CLASS && SCx200_GPIO
|
||||
|
@ -127,6 +133,7 @@ config LEDS_CLEVO_MAIL
|
|||
|
||||
This module can drive the mail LED for the following notebooks:
|
||||
|
||||
Clevo D400P
|
||||
Clevo D410J
|
||||
Clevo D410V
|
||||
Clevo D400V/D470V (not tested, but might work)
|
||||
|
@ -134,6 +141,9 @@ config LEDS_CLEVO_MAIL
|
|||
Clevo M5x0N (not tested, but might work)
|
||||
Positivo Mobile (Clevo M5x0V)
|
||||
|
||||
If your model is not listed here you can try the "nodetect"
|
||||
module paramter.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called leds-clevo-mail.
|
||||
|
||||
|
@ -173,4 +183,11 @@ config LEDS_TRIGGER_HEARTBEAT
|
|||
load average.
|
||||
If unsure, say Y.
|
||||
|
||||
config LEDS_TRIGGER_DEFAULT_ON
|
||||
tristate "LED Default ON Trigger"
|
||||
depends on LEDS_TRIGGERS
|
||||
help
|
||||
This allows LEDs to be initialised in the ON state.
|
||||
If unsure, say Y.
|
||||
|
||||
endif # NEW_LEDS
|
||||
|
|
|
@ -20,8 +20,10 @@ obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
|
|||
obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o
|
||||
obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
|
||||
obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
|
||||
obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
|
||||
|
||||
# LED Triggers
|
||||
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
|
||||
obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
|
||||
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
|
||||
obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
|
||||
static struct class *leds_class;
|
||||
|
||||
static void led_update_brightness(struct led_classdev *led_cdev)
|
||||
{
|
||||
if (led_cdev->brightness_get)
|
||||
led_cdev->brightness = led_cdev->brightness_get(led_cdev);
|
||||
}
|
||||
|
||||
static ssize_t led_brightness_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
@ -31,6 +37,7 @@ static ssize_t led_brightness_show(struct device *dev,
|
|||
ssize_t ret = 0;
|
||||
|
||||
/* no lock needed for this */
|
||||
led_update_brightness(led_cdev);
|
||||
sprintf(buf, "%u\n", led_cdev->brightness);
|
||||
ret = strlen(buf) + 1;
|
||||
|
||||
|
@ -51,6 +58,9 @@ static ssize_t led_brightness_store(struct device *dev,
|
|||
|
||||
if (count == size) {
|
||||
ret = count;
|
||||
|
||||
if (state == LED_OFF)
|
||||
led_trigger_remove(led_cdev);
|
||||
led_set_brightness(led_cdev, state);
|
||||
}
|
||||
|
||||
|
@ -110,6 +120,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
|
|||
list_add_tail(&led_cdev->node, &leds_list);
|
||||
up_write(&leds_list_lock);
|
||||
|
||||
led_update_brightness(led_cdev);
|
||||
|
||||
#ifdef CONFIG_LEDS_TRIGGERS
|
||||
init_rwsem(&led_cdev->trigger_lock);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "leds.h"
|
||||
|
||||
DECLARE_RWSEM(leds_list_lock);
|
||||
LIST_HEAD(leds_list);
|
||||
|
||||
EXPORT_SYMBOL_GPL(leds_list);
|
||||
EXPORT_SYMBOL_GPL(leds_list_lock);
|
||||
|
||||
LIST_HEAD(leds_list);
|
||||
EXPORT_SYMBOL_GPL(leds_list);
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
static DECLARE_RWSEM(triggers_list_lock);
|
||||
static LIST_HEAD(trigger_list);
|
||||
|
||||
/* Used by LED Class */
|
||||
|
||||
ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
|
@ -45,9 +47,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
|
|||
trigger_name[len - 1] = '\0';
|
||||
|
||||
if (!strcmp(trigger_name, "none")) {
|
||||
down_write(&led_cdev->trigger_lock);
|
||||
led_trigger_set(led_cdev, NULL);
|
||||
up_write(&led_cdev->trigger_lock);
|
||||
led_trigger_remove(led_cdev);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
|
|||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(led_trigger_store);
|
||||
|
||||
ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
|
@ -96,24 +96,7 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
|
|||
len += sprintf(len+buf, "\n");
|
||||
return len;
|
||||
}
|
||||
|
||||
void led_trigger_event(struct led_trigger *trigger,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct list_head *entry;
|
||||
|
||||
if (!trigger)
|
||||
return;
|
||||
|
||||
read_lock(&trigger->leddev_list_lock);
|
||||
list_for_each(entry, &trigger->led_cdevs) {
|
||||
struct led_classdev *led_cdev;
|
||||
|
||||
led_cdev = list_entry(entry, struct led_classdev, trig_list);
|
||||
led_set_brightness(led_cdev, brightness);
|
||||
}
|
||||
read_unlock(&trigger->leddev_list_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_show);
|
||||
|
||||
/* Caller must ensure led_cdev->trigger_lock held */
|
||||
void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
|
||||
|
@ -124,7 +107,8 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
|
|||
if (led_cdev->trigger) {
|
||||
write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags);
|
||||
list_del(&led_cdev->trig_list);
|
||||
write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags);
|
||||
write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock,
|
||||
flags);
|
||||
if (led_cdev->trigger->deactivate)
|
||||
led_cdev->trigger->deactivate(led_cdev);
|
||||
led_set_brightness(led_cdev, LED_OFF);
|
||||
|
@ -138,6 +122,15 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
|
|||
}
|
||||
led_cdev->trigger = trigger;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_set);
|
||||
|
||||
void led_trigger_remove(struct led_classdev *led_cdev)
|
||||
{
|
||||
down_write(&led_cdev->trigger_lock);
|
||||
led_trigger_set(led_cdev, NULL);
|
||||
up_write(&led_cdev->trigger_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_remove);
|
||||
|
||||
void led_trigger_set_default(struct led_classdev *led_cdev)
|
||||
{
|
||||
|
@ -155,6 +148,9 @@ void led_trigger_set_default(struct led_classdev *led_cdev)
|
|||
up_write(&led_cdev->trigger_lock);
|
||||
up_read(&triggers_list_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_set_default);
|
||||
|
||||
/* LED Trigger Interface */
|
||||
|
||||
int led_trigger_register(struct led_trigger *trigger)
|
||||
{
|
||||
|
@ -181,26 +177,7 @@ int led_trigger_register(struct led_trigger *trigger)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void led_trigger_register_simple(const char *name, struct led_trigger **tp)
|
||||
{
|
||||
struct led_trigger *trigger;
|
||||
int err;
|
||||
|
||||
trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
|
||||
|
||||
if (trigger) {
|
||||
trigger->name = name;
|
||||
err = led_trigger_register(trigger);
|
||||
if (err < 0)
|
||||
printk(KERN_WARNING "LED trigger %s failed to register"
|
||||
" (%d)\n", name, err);
|
||||
} else
|
||||
printk(KERN_WARNING "LED trigger %s failed to register"
|
||||
" (no memory)\n", name);
|
||||
|
||||
*tp = trigger;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_register);
|
||||
|
||||
void led_trigger_unregister(struct led_trigger *trigger)
|
||||
{
|
||||
|
@ -221,6 +198,49 @@ void led_trigger_unregister(struct led_trigger *trigger)
|
|||
}
|
||||
up_read(&leds_list_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_unregister);
|
||||
|
||||
/* Simple LED Tigger Interface */
|
||||
|
||||
void led_trigger_event(struct led_trigger *trigger,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct list_head *entry;
|
||||
|
||||
if (!trigger)
|
||||
return;
|
||||
|
||||
read_lock(&trigger->leddev_list_lock);
|
||||
list_for_each(entry, &trigger->led_cdevs) {
|
||||
struct led_classdev *led_cdev;
|
||||
|
||||
led_cdev = list_entry(entry, struct led_classdev, trig_list);
|
||||
led_set_brightness(led_cdev, brightness);
|
||||
}
|
||||
read_unlock(&trigger->leddev_list_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_event);
|
||||
|
||||
void led_trigger_register_simple(const char *name, struct led_trigger **tp)
|
||||
{
|
||||
struct led_trigger *trigger;
|
||||
int err;
|
||||
|
||||
trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
|
||||
|
||||
if (trigger) {
|
||||
trigger->name = name;
|
||||
err = led_trigger_register(trigger);
|
||||
if (err < 0)
|
||||
printk(KERN_WARNING "LED trigger %s failed to register"
|
||||
" (%d)\n", name, err);
|
||||
} else
|
||||
printk(KERN_WARNING "LED trigger %s failed to register"
|
||||
" (no memory)\n", name);
|
||||
|
||||
*tp = trigger;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_register_simple);
|
||||
|
||||
void led_trigger_unregister_simple(struct led_trigger *trigger)
|
||||
{
|
||||
|
@ -228,21 +248,7 @@ void led_trigger_unregister_simple(struct led_trigger *trigger)
|
|||
led_trigger_unregister(trigger);
|
||||
kfree(trigger);
|
||||
}
|
||||
|
||||
/* Used by LED Class */
|
||||
EXPORT_SYMBOL_GPL(led_trigger_set);
|
||||
EXPORT_SYMBOL_GPL(led_trigger_set_default);
|
||||
EXPORT_SYMBOL_GPL(led_trigger_show);
|
||||
EXPORT_SYMBOL_GPL(led_trigger_store);
|
||||
|
||||
/* LED Trigger Interface */
|
||||
EXPORT_SYMBOL_GPL(led_trigger_register);
|
||||
EXPORT_SYMBOL_GPL(led_trigger_unregister);
|
||||
|
||||
/* Simple LED Tigger Interface */
|
||||
EXPORT_SYMBOL_GPL(led_trigger_register_simple);
|
||||
EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);
|
||||
EXPORT_SYMBOL_GPL(led_trigger_event);
|
||||
|
||||
MODULE_AUTHOR("Richard Purdie");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#define CLEVO_MAIL_LED_BLINK_1HZ 0x008A
|
||||
#define CLEVO_MAIL_LED_BLINK_0_5HZ 0x0083
|
||||
|
||||
MODULE_AUTHOR("Márton Németh <nm127@freemail.hu>");
|
||||
MODULE_AUTHOR("Márton Németh <nm127@freemail.hu>");
|
||||
MODULE_DESCRIPTION("Clevo mail LED driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
@ -67,6 +67,16 @@ static struct dmi_system_id __initdata mail_led_whitelist[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_VERSION, "VT6198")
|
||||
}
|
||||
},
|
||||
{
|
||||
.callback = clevo_mail_led_dmi_callback,
|
||||
.ident = "Clevo D400P",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Clevo"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "D400P"),
|
||||
DMI_MATCH(DMI_BOARD_VERSION, "Rev.A"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "0106")
|
||||
}
|
||||
},
|
||||
{
|
||||
.callback = clevo_mail_led_dmi_callback,
|
||||
.ident = "Clevo D410V",
|
||||
|
@ -93,8 +103,8 @@ static void clevo_mail_led_set(struct led_classdev *led_cdev,
|
|||
}
|
||||
|
||||
static int clevo_mail_led_blink(struct led_classdev *led_cdev,
|
||||
unsigned long* delay_on,
|
||||
unsigned long* delay_off)
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ static void __iomem *led_port;
|
|||
static u8 led_value;
|
||||
|
||||
static void qube_front_led_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
if (brightness)
|
||||
led_value = LED_FRONT_LEFT | LED_FRONT_RIGHT;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -33,7 +33,7 @@ static u8 led_value;
|
|||
static DEFINE_SPINLOCK(led_value_lock);
|
||||
|
||||
static void raq_web_led_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -54,7 +54,7 @@ static struct led_classdev raq_web_led = {
|
|||
};
|
||||
|
||||
static void raq_power_off_led_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
#include <asm/arch/pxa-regs.h>
|
||||
#include <asm/hardware/scoop.h>
|
||||
|
||||
static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightness value)
|
||||
static void corgiled_amber_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value)
|
||||
GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
|
||||
|
@ -29,7 +30,8 @@ static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightnes
|
|||
GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
|
||||
}
|
||||
|
||||
static void corgiled_green_set(struct led_classdev *led_cdev, enum led_brightness value)
|
||||
static void corgiled_green_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value)
|
||||
set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
|
||||
|
@ -53,7 +55,8 @@ static struct led_classdev corgi_green_led = {
|
|||
static int corgiled_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
#ifdef CONFIG_LEDS_TRIGGERS
|
||||
if (corgi_amber_led.trigger && strcmp(corgi_amber_led.trigger->name, "sharpsl-charge"))
|
||||
if (corgi_amber_led.trigger &&
|
||||
strcmp(corgi_amber_led.trigger->name, "sharpsl-charge"))
|
||||
#endif
|
||||
led_classdev_suspend(&corgi_amber_led);
|
||||
led_classdev_suspend(&corgi_green_led);
|
||||
|
@ -110,7 +113,7 @@ static int __init corgiled_init(void)
|
|||
|
||||
static void __exit corgiled_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&corgiled_driver);
|
||||
platform_driver_unregister(&corgiled_driver);
|
||||
}
|
||||
|
||||
module_init(corgiled_init);
|
||||
|
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* LED Driver for the Freecom FSG-3
|
||||
*
|
||||
* Copyright (c) 2008 Rod Whitby <rod@whitby.id.au>
|
||||
*
|
||||
* Author: Rod Whitby <rod@whitby.id.au>
|
||||
*
|
||||
* Based on leds-spitz.c
|
||||
* Copyright 2005-2006 Openedhand Ltd.
|
||||
* Author: Richard Purdie <rpurdie@openedhand.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/leds.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
static short __iomem *latch_address;
|
||||
static unsigned short latch_value;
|
||||
|
||||
|
||||
static void fsg_led_wlan_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value) {
|
||||
latch_value &= ~(1 << FSG_LED_WLAN_BIT);
|
||||
*latch_address = latch_value;
|
||||
} else {
|
||||
latch_value |= (1 << FSG_LED_WLAN_BIT);
|
||||
*latch_address = latch_value;
|
||||
}
|
||||
}
|
||||
|
||||
static void fsg_led_wan_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value) {
|
||||
latch_value &= ~(1 << FSG_LED_WAN_BIT);
|
||||
*latch_address = latch_value;
|
||||
} else {
|
||||
latch_value |= (1 << FSG_LED_WAN_BIT);
|
||||
*latch_address = latch_value;
|
||||
}
|
||||
}
|
||||
|
||||
static void fsg_led_sata_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value) {
|
||||
latch_value &= ~(1 << FSG_LED_SATA_BIT);
|
||||
*latch_address = latch_value;
|
||||
} else {
|
||||
latch_value |= (1 << FSG_LED_SATA_BIT);
|
||||
*latch_address = latch_value;
|
||||
}
|
||||
}
|
||||
|
||||
static void fsg_led_usb_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value) {
|
||||
latch_value &= ~(1 << FSG_LED_USB_BIT);
|
||||
*latch_address = latch_value;
|
||||
} else {
|
||||
latch_value |= (1 << FSG_LED_USB_BIT);
|
||||
*latch_address = latch_value;
|
||||
}
|
||||
}
|
||||
|
||||
static void fsg_led_sync_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value) {
|
||||
latch_value &= ~(1 << FSG_LED_SYNC_BIT);
|
||||
*latch_address = latch_value;
|
||||
} else {
|
||||
latch_value |= (1 << FSG_LED_SYNC_BIT);
|
||||
*latch_address = latch_value;
|
||||
}
|
||||
}
|
||||
|
||||
static void fsg_led_ring_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value) {
|
||||
latch_value &= ~(1 << FSG_LED_RING_BIT);
|
||||
*latch_address = latch_value;
|
||||
} else {
|
||||
latch_value |= (1 << FSG_LED_RING_BIT);
|
||||
*latch_address = latch_value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct led_classdev fsg_wlan_led = {
|
||||
.name = "fsg:blue:wlan",
|
||||
.brightness_set = fsg_led_wlan_set,
|
||||
};
|
||||
|
||||
static struct led_classdev fsg_wan_led = {
|
||||
.name = "fsg:blue:wan",
|
||||
.brightness_set = fsg_led_wan_set,
|
||||
};
|
||||
|
||||
static struct led_classdev fsg_sata_led = {
|
||||
.name = "fsg:blue:sata",
|
||||
.brightness_set = fsg_led_sata_set,
|
||||
};
|
||||
|
||||
static struct led_classdev fsg_usb_led = {
|
||||
.name = "fsg:blue:usb",
|
||||
.brightness_set = fsg_led_usb_set,
|
||||
};
|
||||
|
||||
static struct led_classdev fsg_sync_led = {
|
||||
.name = "fsg:blue:sync",
|
||||
.brightness_set = fsg_led_sync_set,
|
||||
};
|
||||
|
||||
static struct led_classdev fsg_ring_led = {
|
||||
.name = "fsg:blue:ring",
|
||||
.brightness_set = fsg_led_ring_set,
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int fsg_led_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
led_classdev_suspend(&fsg_wlan_led);
|
||||
led_classdev_suspend(&fsg_wan_led);
|
||||
led_classdev_suspend(&fsg_sata_led);
|
||||
led_classdev_suspend(&fsg_usb_led);
|
||||
led_classdev_suspend(&fsg_sync_led);
|
||||
led_classdev_suspend(&fsg_ring_led);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsg_led_resume(struct platform_device *dev)
|
||||
{
|
||||
led_classdev_resume(&fsg_wlan_led);
|
||||
led_classdev_resume(&fsg_wan_led);
|
||||
led_classdev_resume(&fsg_sata_led);
|
||||
led_classdev_resume(&fsg_usb_led);
|
||||
led_classdev_resume(&fsg_sync_led);
|
||||
led_classdev_resume(&fsg_ring_led);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int fsg_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_wlan_led);
|
||||
if (ret < 0)
|
||||
goto failwlan;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_wan_led);
|
||||
if (ret < 0)
|
||||
goto failwan;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_sata_led);
|
||||
if (ret < 0)
|
||||
goto failsata;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_usb_led);
|
||||
if (ret < 0)
|
||||
goto failusb;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_sync_led);
|
||||
if (ret < 0)
|
||||
goto failsync;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &fsg_ring_led);
|
||||
if (ret < 0)
|
||||
goto failring;
|
||||
|
||||
/* Map the LED chip select address space */
|
||||
latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512);
|
||||
if (!latch_address) {
|
||||
ret = -ENOMEM;
|
||||
goto failremap;
|
||||
}
|
||||
|
||||
latch_value = 0xffff;
|
||||
*latch_address = latch_value;
|
||||
|
||||
return ret;
|
||||
|
||||
failremap:
|
||||
led_classdev_unregister(&fsg_ring_led);
|
||||
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;
|
||||
}
|
||||
|
||||
static int fsg_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
iounmap(latch_address);
|
||||
|
||||
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,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = fsg_led_suspend,
|
||||
.resume = fsg_led_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = "fsg-led",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static int __init fsg_led_init(void)
|
||||
{
|
||||
return platform_driver_register(&fsg_led_driver);
|
||||
}
|
||||
|
||||
static void __exit fsg_led_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&fsg_led_driver);
|
||||
}
|
||||
|
||||
|
||||
module_init(fsg_led_init);
|
||||
module_exit(fsg_led_exit);
|
||||
|
||||
MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>");
|
||||
MODULE_DESCRIPTION("Freecom FSG-3 LED driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -24,6 +24,8 @@ struct gpio_led_data {
|
|||
u8 new_level;
|
||||
u8 can_sleep;
|
||||
u8 active_low;
|
||||
int (*platform_gpio_blink_set)(unsigned gpio,
|
||||
unsigned long *delay_on, unsigned long *delay_off);
|
||||
};
|
||||
|
||||
static void gpio_led_work(struct work_struct *work)
|
||||
|
@ -60,6 +62,15 @@ static void gpio_led_set(struct led_classdev *led_cdev,
|
|||
gpio_set_value(led_dat->gpio, level);
|
||||
}
|
||||
|
||||
static int gpio_blink_set(struct led_classdev *led_cdev,
|
||||
unsigned long *delay_on, unsigned long *delay_off)
|
||||
{
|
||||
struct gpio_led_data *led_dat =
|
||||
container_of(led_cdev, struct gpio_led_data, cdev);
|
||||
|
||||
return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off);
|
||||
}
|
||||
|
||||
static int gpio_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
@ -88,6 +99,10 @@ static int gpio_led_probe(struct platform_device *pdev)
|
|||
led_dat->gpio = cur_led->gpio;
|
||||
led_dat->can_sleep = gpio_cansleep(cur_led->gpio);
|
||||
led_dat->active_low = cur_led->active_low;
|
||||
if (pdata->gpio_blink_set) {
|
||||
led_dat->platform_gpio_blink_set = pdata->gpio_blink_set;
|
||||
led_dat->cdev.blink_set = gpio_blink_set;
|
||||
}
|
||||
led_dat->cdev.brightness_set = gpio_led_set;
|
||||
led_dat->cdev.brightness = LED_OFF;
|
||||
|
||||
|
|
|
@ -26,20 +26,20 @@
|
|||
void h1940_greenled_set(struct led_classdev *led_dev, enum led_brightness value)
|
||||
{
|
||||
switch (value) {
|
||||
case LED_HALF:
|
||||
h1940_latch_control(0,H1940_LATCH_LED_FLASH);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA7,1);
|
||||
break;
|
||||
case LED_FULL:
|
||||
h1940_latch_control(0,H1940_LATCH_LED_GREEN);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA7,1);
|
||||
break;
|
||||
default:
|
||||
case LED_OFF:
|
||||
h1940_latch_control(H1940_LATCH_LED_FLASH,0);
|
||||
h1940_latch_control(H1940_LATCH_LED_GREEN,0);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA7,0);
|
||||
break;
|
||||
case LED_HALF:
|
||||
h1940_latch_control(0, H1940_LATCH_LED_FLASH);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA7, 1);
|
||||
break;
|
||||
case LED_FULL:
|
||||
h1940_latch_control(0, H1940_LATCH_LED_GREEN);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA7, 1);
|
||||
break;
|
||||
default:
|
||||
case LED_OFF:
|
||||
h1940_latch_control(H1940_LATCH_LED_FLASH, 0);
|
||||
h1940_latch_control(H1940_LATCH_LED_GREEN, 0);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA7, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,20 +55,20 @@ static struct led_classdev h1940_greenled = {
|
|||
void h1940_redled_set(struct led_classdev *led_dev, enum led_brightness value)
|
||||
{
|
||||
switch (value) {
|
||||
case LED_HALF:
|
||||
h1940_latch_control(0,H1940_LATCH_LED_FLASH);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA1,1);
|
||||
break;
|
||||
case LED_FULL:
|
||||
h1940_latch_control(0,H1940_LATCH_LED_RED);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA1,1);
|
||||
break;
|
||||
default:
|
||||
case LED_OFF:
|
||||
h1940_latch_control(H1940_LATCH_LED_FLASH,0);
|
||||
h1940_latch_control(H1940_LATCH_LED_RED,0);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA1,0);
|
||||
break;
|
||||
case LED_HALF:
|
||||
h1940_latch_control(0, H1940_LATCH_LED_FLASH);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA1, 1);
|
||||
break;
|
||||
case LED_FULL:
|
||||
h1940_latch_control(0, H1940_LATCH_LED_RED);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA1, 1);
|
||||
break;
|
||||
default:
|
||||
case LED_OFF:
|
||||
h1940_latch_control(H1940_LATCH_LED_FLASH, 0);
|
||||
h1940_latch_control(H1940_LATCH_LED_RED, 0);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA1, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,11 +86,11 @@ void h1940_blueled_set(struct led_classdev *led_dev, enum led_brightness value)
|
|||
{
|
||||
if (value) {
|
||||
/* flashing Blue */
|
||||
h1940_latch_control(0,H1940_LATCH_LED_FLASH);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA3,1);
|
||||
h1940_latch_control(0, H1940_LATCH_LED_FLASH);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA3, 1);
|
||||
} else {
|
||||
h1940_latch_control(H1940_LATCH_LED_FLASH,0);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA3,0);
|
||||
h1940_latch_control(H1940_LATCH_LED_FLASH, 0);
|
||||
s3c2410_gpio_setpin(S3C2410_GPA3, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
#include <asm/hd64461.h>
|
||||
#include <asm/hp6xx.h>
|
||||
|
||||
static void hp6xxled_green_set(struct led_classdev *led_cdev, enum led_brightness value)
|
||||
static void hp6xxled_green_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
u8 v8;
|
||||
|
||||
|
@ -28,7 +29,8 @@ static void hp6xxled_green_set(struct led_classdev *led_cdev, enum led_brightnes
|
|||
outb(v8 | PKDR_LED_GREEN, PKDR);
|
||||
}
|
||||
|
||||
static void hp6xxled_red_set(struct led_classdev *led_cdev, enum led_brightness value)
|
||||
static void hp6xxled_red_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
u16 v16;
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ static void s3c24xx_led_set(struct led_classdev *led_cdev,
|
|||
|
||||
if (pd->flags & S3C24XX_LEDF_TRISTATE)
|
||||
s3c2410_gpio_cfgpin(pd->gpio,
|
||||
value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT);
|
||||
value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT);
|
||||
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ static int __init s3c24xx_led_init(void)
|
|||
|
||||
static void __exit s3c24xx_led_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&s3c24xx_led_driver);
|
||||
platform_driver_unregister(&s3c24xx_led_driver);
|
||||
}
|
||||
|
||||
module_init(s3c24xx_led_init);
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
#include <asm/arch/pxa-regs.h>
|
||||
#include <asm/arch/spitz.h>
|
||||
|
||||
static void spitzled_amber_set(struct led_classdev *led_cdev, enum led_brightness value)
|
||||
static void spitzled_amber_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value)
|
||||
set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
|
||||
|
@ -29,7 +30,8 @@ static void spitzled_amber_set(struct led_classdev *led_cdev, enum led_brightnes
|
|||
reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
|
||||
}
|
||||
|
||||
static void spitzled_green_set(struct led_classdev *led_cdev, enum led_brightness value)
|
||||
static void spitzled_green_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value)
|
||||
set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
|
||||
|
@ -53,7 +55,8 @@ static struct led_classdev spitz_green_led = {
|
|||
static int spitzled_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
#ifdef CONFIG_LEDS_TRIGGERS
|
||||
if (spitz_amber_led.trigger && strcmp(spitz_amber_led.trigger->name, "sharpsl-charge"))
|
||||
if (spitz_amber_led.trigger &&
|
||||
strcmp(spitz_amber_led.trigger->name, "sharpsl-charge"))
|
||||
#endif
|
||||
led_classdev_suspend(&spitz_amber_led);
|
||||
led_classdev_suspend(&spitz_green_led);
|
||||
|
@ -116,7 +119,7 @@ static int __init spitzled_init(void)
|
|||
|
||||
static void __exit spitzled_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&spitzled_driver);
|
||||
platform_driver_unregister(&spitzled_driver);
|
||||
}
|
||||
|
||||
module_init(spitzled_init);
|
||||
|
|
|
@ -27,6 +27,11 @@ static inline void led_set_brightness(struct led_classdev *led_cdev,
|
|||
led_cdev->brightness_set(led_cdev, value);
|
||||
}
|
||||
|
||||
static inline int led_get_brightness(struct led_classdev *led_cdev)
|
||||
{
|
||||
return led_cdev->brightness;
|
||||
}
|
||||
|
||||
extern struct rw_semaphore leds_list_lock;
|
||||
extern struct list_head leds_list;
|
||||
|
||||
|
@ -34,9 +39,11 @@ extern struct list_head leds_list;
|
|||
void led_trigger_set_default(struct led_classdev *led_cdev);
|
||||
void led_trigger_set(struct led_classdev *led_cdev,
|
||||
struct led_trigger *trigger);
|
||||
void led_trigger_remove(struct led_classdev *led_cdev);
|
||||
#else
|
||||
#define led_trigger_set_default(x) do {} while(0)
|
||||
#define led_trigger_set(x, y) do {} while(0)
|
||||
#define led_trigger_set_default(x) do {} while (0)
|
||||
#define led_trigger_set(x, y) do {} while (0)
|
||||
#define led_trigger_remove(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* LED Kernel Default ON Trigger
|
||||
*
|
||||
* Copyright 2008 Nick Forbes <nick.forbes@incepta.com>
|
||||
*
|
||||
* Based on Richard Purdie's ledtrig-timer.c.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/leds.h>
|
||||
#include "leds.h"
|
||||
|
||||
static void defon_trig_activate(struct led_classdev *led_cdev)
|
||||
{
|
||||
led_set_brightness(led_cdev, LED_FULL);
|
||||
}
|
||||
|
||||
static struct led_trigger defon_led_trigger = {
|
||||
.name = "default-on",
|
||||
.activate = defon_trig_activate,
|
||||
};
|
||||
|
||||
static int __init defon_trig_init(void)
|
||||
{
|
||||
return led_trigger_register(&defon_led_trigger);
|
||||
}
|
||||
|
||||
static void __exit defon_trig_exit(void)
|
||||
{
|
||||
led_trigger_unregister(&defon_led_trigger);
|
||||
}
|
||||
|
||||
module_init(defon_trig_init);
|
||||
module_exit(defon_trig_exit);
|
||||
|
||||
MODULE_AUTHOR("Nick Forbes <nick.forbes@incepta.com>");
|
||||
MODULE_DESCRIPTION("Default-ON LED trigger");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -38,7 +38,7 @@ static void ledtrig_ide_timerfunc(unsigned long data)
|
|||
if (ide_lastactivity != ide_activity) {
|
||||
ide_lastactivity = ide_activity;
|
||||
led_trigger_event(ledtrig_ide, LED_FULL);
|
||||
mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
|
||||
mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
|
||||
} else {
|
||||
led_trigger_event(ledtrig_ide, LED_OFF);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include "leds.h"
|
||||
|
||||
struct timer_trig_data {
|
||||
int brightness_on; /* LED brightness during "on" period.
|
||||
* (LED_OFF < brightness_on <= LED_FULL)
|
||||
*/
|
||||
unsigned long delay_on; /* milliseconds on */
|
||||
unsigned long delay_off; /* milliseconds off */
|
||||
struct timer_list timer;
|
||||
|
@ -34,17 +37,26 @@ static void led_timer_function(unsigned long data)
|
|||
{
|
||||
struct led_classdev *led_cdev = (struct led_classdev *) data;
|
||||
struct timer_trig_data *timer_data = led_cdev->trigger_data;
|
||||
unsigned long brightness = LED_OFF;
|
||||
unsigned long delay = timer_data->delay_off;
|
||||
unsigned long brightness;
|
||||
unsigned long delay;
|
||||
|
||||
if (!timer_data->delay_on || !timer_data->delay_off) {
|
||||
led_set_brightness(led_cdev, LED_OFF);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!led_cdev->brightness) {
|
||||
brightness = LED_FULL;
|
||||
brightness = led_get_brightness(led_cdev);
|
||||
if (!brightness) {
|
||||
/* Time to switch the LED on. */
|
||||
brightness = timer_data->brightness_on;
|
||||
delay = timer_data->delay_on;
|
||||
} else {
|
||||
/* Store the current brightness value to be able
|
||||
* to restore it when the delay_off period is over.
|
||||
*/
|
||||
timer_data->brightness_on = brightness;
|
||||
brightness = LED_OFF;
|
||||
delay = timer_data->delay_off;
|
||||
}
|
||||
|
||||
led_set_brightness(led_cdev, brightness);
|
||||
|
@ -52,7 +64,7 @@ static void led_timer_function(unsigned long data)
|
|||
mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay));
|
||||
}
|
||||
|
||||
static ssize_t led_delay_on_show(struct device *dev,
|
||||
static ssize_t led_delay_on_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
|
@ -63,7 +75,7 @@ static ssize_t led_delay_on_show(struct device *dev,
|
|||
return strlen(buf) + 1;
|
||||
}
|
||||
|
||||
static ssize_t led_delay_on_store(struct device *dev,
|
||||
static ssize_t led_delay_on_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
|
@ -87,7 +99,7 @@ static ssize_t led_delay_on_store(struct device *dev,
|
|||
/* try to activate hardware acceleration, if any */
|
||||
if (!led_cdev->blink_set ||
|
||||
led_cdev->blink_set(led_cdev,
|
||||
&timer_data->delay_on, &timer_data->delay_off)) {
|
||||
&timer_data->delay_on, &timer_data->delay_off)) {
|
||||
/* no hardware acceleration, blink via timer */
|
||||
mod_timer(&timer_data->timer, jiffies + 1);
|
||||
}
|
||||
|
@ -98,7 +110,7 @@ static ssize_t led_delay_on_store(struct device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t led_delay_off_show(struct device *dev,
|
||||
static ssize_t led_delay_off_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
|
@ -109,7 +121,7 @@ static ssize_t led_delay_off_show(struct device *dev,
|
|||
return strlen(buf) + 1;
|
||||
}
|
||||
|
||||
static ssize_t led_delay_off_store(struct device *dev,
|
||||
static ssize_t led_delay_off_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
|
@ -133,7 +145,7 @@ static ssize_t led_delay_off_store(struct device *dev,
|
|||
/* try to activate hardware acceleration, if any */
|
||||
if (!led_cdev->blink_set ||
|
||||
led_cdev->blink_set(led_cdev,
|
||||
&timer_data->delay_on, &timer_data->delay_off)) {
|
||||
&timer_data->delay_on, &timer_data->delay_off)) {
|
||||
/* no hardware acceleration, blink via timer */
|
||||
mod_timer(&timer_data->timer, jiffies + 1);
|
||||
}
|
||||
|
@ -156,6 +168,9 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
|
|||
if (!timer_data)
|
||||
return;
|
||||
|
||||
timer_data->brightness_on = led_get_brightness(led_cdev);
|
||||
if (timer_data->brightness_on == LED_OFF)
|
||||
timer_data->brightness_on = LED_FULL;
|
||||
led_cdev->trigger_data = timer_data;
|
||||
|
||||
init_timer(&timer_data->timer);
|
||||
|
|
|
@ -35,8 +35,11 @@ struct led_classdev {
|
|||
#define LED_SUSPENDED (1 << 0)
|
||||
|
||||
/* Set LED brightness level */
|
||||
/* Must not sleep, use a workqueue if needed */
|
||||
void (*brightness_set)(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness);
|
||||
/* Get LED brightness level */
|
||||
enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);
|
||||
|
||||
/* Activate hardware accelerated blink */
|
||||
int (*blink_set)(struct led_classdev *led_cdev,
|
||||
|
@ -126,6 +129,9 @@ struct gpio_led {
|
|||
struct gpio_led_platform_data {
|
||||
int num_leds;
|
||||
struct gpio_led *leds;
|
||||
int (*gpio_blink_set)(unsigned gpio,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off);
|
||||
};
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче