leds-intel-kpd-gpio.c: adjust the kpd led brightness
authorShijie Zhang <shijie.zhang@intel.com>
Mon, 16 Apr 2012 15:46:32 +0000 (23:46 +0800)
committerbuildbot <buildbot@intel.com>
Tue, 24 Apr 2012 08:35:02 +0000 (01:35 -0700)
BZ: 31930

On Lexington, KPD LED brightness is set too high. This patch
lowers the KPD LED brightbess to save power, and changes the
KPD LED output current level setting method according to the
AHK3292 Datasheet.

Change-Id: I99649b48a29dbc2939b3421042dfb8371b623347
Signed-off-by: Shijie Zhang <shijie.zhang@intel.com>
Reviewed-on: http://android.intel.com:8080/43534
Reviewed-by: Chen, Jie D <jie.d.chen@intel.com>
Reviewed-by: Yang, Bin <bin.yang@intel.com>
Reviewed-by: Du, Alek <alek.du@intel.com>
Tested-by: Wang, Zhifeng <zhifeng.wang@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/leds/leds-intel-kpd-gpio.c

index c3c2fff..d528803 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/ktime.h>
+#include <linux/hrtimer.h>
+#include <linux/spinlock.h>
 #include <linux/earlysuspend.h>
 #include <asm/intel_kpd_gpio_led.h>
 
 static int gpio;
+static spinlock_t lock;
 
 static void intel_keypad_led_set(struct led_classdev *led_cdev,
                enum led_brightness value)
 {
-       if (value > 0)
-               gpio_set_value(gpio, 1);
-       else
+       int i, level;
+       u32 elapsed, needed;
+       unsigned long flags;
+       static ktime_t out;
+
+       elapsed = ktime_to_us(ktime_sub(ktime_get(), out));
+       if (unlikely(elapsed < 500)) {
+               needed = 500 - elapsed;
+               usleep_range(needed, needed + 50);
+       }
+
+       /* According to the AHK3292 Datasheet, AHK3292 has 32 level output
+        * current settings, range from 1 ~ 32, 1 is the highest and 32 is
+        * the lowest.*/
+       if (value > 0) {
+               level = ((100 - value) * 32 / 100) + 1;
+               spin_lock_irqsave(&lock, flags);
+               for (i = 0; i < level; i++) {
+                       gpio_set_value(gpio, 0);
+                       udelay(1);
+                       gpio_set_value(gpio, 1);
+                       udelay(1);
+               }
+               spin_unlock_irqrestore(&lock, flags);
+       } else {
                gpio_set_value(gpio, 0);
+       }
+
+       out = ktime_get();
 }
 
 static struct led_classdev intel_kpd_led = {
        .name                   = "intel_keypad_led",
        .brightness_set         = intel_keypad_led_set,
        .brightness             = LED_OFF,
-       .max_brightness         = LED_FULL,
+       .max_brightness         = 15,
 };
 
 static void intel_kpd_led_early_suspend(struct early_suspend *h)
@@ -68,6 +98,8 @@ static int __devinit intel_kpd_led_probe(struct platform_device *pdev)
        int ret;
        struct intel_kpd_gpio_led_pdata *pdata;
 
+       spin_lock_init(&lock);
+
        pdata = pdev->dev.platform_data;
        if (!pdata)
                return -EINVAL;