From 92e015cb31c0a312bf2e0e5b96aef76a8c57e645 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= <nm127@freemail.hu>
Date: Wed, 31 Oct 2007 15:09:05 +0100
Subject: [PATCH] leds: hw acceleration for Clevo mail LED driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add support for hardware accelerated LED blinking for the mail LED
commonly found on Clevo notebooks.

Signed-off-by: Márton Németh <nm127@freemail.hu>
Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
---
 drivers/leds/Kconfig           |  8 +++++---
 drivers/leds/leds-clevo-mail.c | 37 ++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 659448ead6858..922c3df548a54 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -122,9 +122,11 @@ config LEDS_CLEVO_MAIL
 	  programs through the leds subsystem. This LED have three
 	  known mode: off, blink at 0.5Hz and blink at 1Hz.
 
-	  As this LED cannot change it's brightness it blinks instead.
-	  The brightness value 0 means off, 1..127 means blink at 0.5Hz
-	  and 128..255 means blink at 1Hz.
+	  The driver supports two kinds of interface: using ledtrig-timer
+	  or through /sys/class/leds/clevo::mail/brightness. As this LED
+	  cannot change it's brightness it blinks instead. The brightness
+	  value 0 means off, 1..127 means blink at 0.5Hz and 128..255 means
+	  blink at 1Hz.
 
 	  This module can drive the mail LED for the following notebooks:
 
diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c
index 49a7972459c94..6c3d33b8e3830 100644
--- a/drivers/leds/leds-clevo-mail.c
+++ b/drivers/leds/leds-clevo-mail.c
@@ -92,9 +92,46 @@ 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)
+{
+	int status = -EINVAL;
+
+	if (*delay_on == 0 /* ms */ && *delay_off == 0 /* ms */) {
+		/* Special case: the leds subsystem requested us to
+		 * chose one user friendly blinking of the LED, and
+		 * start it. Let's blink the led slowly (0.5Hz).
+		 */
+		*delay_on = 1000; /* ms */
+		*delay_off = 1000; /* ms */
+		i8042_command(NULL, CLEVO_MAIL_LED_BLINK_0_5HZ);
+		status = 0;
+
+	} else if (*delay_on == 500 /* ms */ && *delay_off == 500 /* ms */) {
+		/* blink the led with 1Hz */
+		i8042_command(NULL, CLEVO_MAIL_LED_BLINK_1HZ);
+		status = 0;
+
+	} else if (*delay_on == 1000 /* ms */ && *delay_off == 1000 /* ms */) {
+		/* blink the led with 0.5Hz */
+		i8042_command(NULL, CLEVO_MAIL_LED_BLINK_0_5HZ);
+		status = 0;
+
+	} else {
+		printk(KERN_DEBUG KBUILD_MODNAME
+		       ": clevo_mail_led_blink(..., %lu, %lu),"
+		       " returning -EINVAL (unsupported)\n",
+		       *delay_on, *delay_off);
+	}
+
+	return status;
+}
+
 static struct led_classdev clevo_mail_led = {
 	.name			= "clevo::mail",
 	.brightness_set		= clevo_mail_led_set,
+	.blink_set		= clevo_mail_led_blink,
 };
 
 static int __init clevo_mail_led_probe(struct platform_device *pdev)
-- 
GitLab