Enable KPD LED on Lexington
authorShijie Zhang <shijie.zhang@intel.com>
Mon, 9 Apr 2012 13:13:19 +0000 (21:13 +0800)
committerbuildbot <buildbot@intel.com>
Thu, 12 Apr 2012 23:36:59 +0000 (16:36 -0700)
BZ: 29806

This patch adds support for keypad LED function for Lexington
platform.

Change-Id: I3eab691ea4aa546921dbff650feb2b19ace93268
Signed-off-by: Shijie Zhang <shijie.zhang@intel.com>
Reviewed-on: http://android.intel.com:8080/42762
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>
arch/x86/include/asm/intel_kpd_gpio_led.h [new file with mode: 0644]
arch/x86/platform/intel-mid/board-blackbay.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/leds-intel-kpd-gpio.c [new file with mode: 0644]

diff --git a/arch/x86/include/asm/intel_kpd_gpio_led.h b/arch/x86/include/asm/intel_kpd_gpio_led.h
new file mode 100644 (file)
index 0000000..54e66fb
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _ASM_X86_INTEL_KPD_LED_GPIO_H_
+#define _ASM_X86_INTEL_KPD_LED_GPIO_H_
+
+struct intel_kpd_gpio_led_pdata {
+       int gpio;
+};
+
+#endif
index b43c081..df0fc7c 100644 (file)
@@ -69,6 +69,7 @@
 #include <asm/io.h>
 #include <asm/i8259.h>
 #include <asm/intel_scu_ipc.h>
+#include <asm/intel_kpd_gpio_led.h>
 #include <asm/apb_timer.h>
 #include <asm/intel_mid_gpadc.h>
 #include <asm/intel_mid_pwm.h>
@@ -2050,6 +2051,33 @@ static int __init intel_kpd_led_init(void)
 fs_initcall(intel_kpd_led_init);
 #endif
 
+#ifdef CONFIG_LEDS_INTEL_KPD_GPIO
+static int __init intel_kpd_gpio_led_init(void)
+{
+       int ret;
+       struct platform_device *pdev;
+       static struct intel_kpd_gpio_led_pdata pdata;
+
+       pdev = platform_device_alloc("intel_kpd_led", -1);
+       if (!pdev) {
+               pr_err("Failed to create platform device: intel_kpd_led\n");
+               return -ENOMEM;
+       }
+
+       ret = get_gpio_by_name("intel_kpd_led");
+       if (ret == -1) {
+               pr_err("Failed to get KPD LED gpio pin from SFI table\n");
+               return -ENODEV;
+       }
+
+       pdata.gpio = ret;
+       pdev->dev.platform_data = &pdata;
+
+       return platform_device_add(pdev);
+}
+device_initcall(intel_kpd_gpio_led_init);
+#endif
+
 static int __init intel_msic_thermal_init(void)
 {
        int ret;
index 75b35d1..ef09231 100644 (file)
@@ -379,6 +379,16 @@ config LEDS_INTEL_KPD
           For detail information of sysfs control, Please refer to kernel document
           Documentation/ABI/testing/sysfs-class-led.
 
+config LEDS_INTEL_KPD_GPIO
+       tristate "LED driver for Intel Keypad GPIO LED"
+       depends on GPIOLIB
+       help
+         This option enables to support for Intel Keypad GPIO LED on Lexington
+         Platform. LED brightness can be controlled via sysfs.
+
+         For detail information of sysfs control, Please refer to kernel document
+         Documentation/ABI/testing/sysfs-class-led.
+
 config LEDS_NS2
        tristate "LED support for Network Space v2 GPIO LEDs"
        depends on LEDS_CLASS
index 8ab64bb..04e522d 100644 (file)
@@ -44,6 +44,7 @@ obj-$(CONFIG_LEDS_NS2)                        += leds-ns2.o
 obj-$(CONFIG_LEDS_NETXBIG)             += leds-netxbig.o
 obj-$(CONFIG_LEDS_ASIC3)               += leds-asic3.o
 obj-$(CONFIG_LEDS_INTEL_KPD)           += leds-intel-kpd.o
+obj-$(CONFIG_LEDS_INTEL_KPD_GPIO)      += leds-intel-kpd-gpio.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)          += leds-dac124s085.o
diff --git a/drivers/leds/leds-intel-kpd-gpio.c b/drivers/leds/leds-intel-kpd-gpio.c
new file mode 100644 (file)
index 0000000..c3c2fff
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * leds-intel-kpd-gpio.c - Intel GPIO Keypad LED driver
+ *
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/earlysuspend.h>
+#include <asm/intel_kpd_gpio_led.h>
+
+static int gpio;
+
+static void intel_keypad_led_set(struct led_classdev *led_cdev,
+               enum led_brightness value)
+{
+       if (value > 0)
+               gpio_set_value(gpio, 1);
+       else
+               gpio_set_value(gpio, 0);
+}
+
+static struct led_classdev intel_kpd_led = {
+       .name                   = "intel_keypad_led",
+       .brightness_set         = intel_keypad_led_set,
+       .brightness             = LED_OFF,
+       .max_brightness         = LED_FULL,
+};
+
+static void intel_kpd_led_early_suspend(struct early_suspend *h)
+{
+       led_classdev_suspend(&intel_kpd_led);
+}
+
+static void intel_kpd_led_late_resume(struct early_suspend *h)
+{
+       led_classdev_resume(&intel_kpd_led);
+}
+
+static struct early_suspend intel_kpd_led_suspend_desc = {
+       .level   = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
+       .suspend = intel_kpd_led_early_suspend,
+       .resume  = intel_kpd_led_late_resume,
+};
+
+static int __devinit intel_kpd_led_probe(struct platform_device *pdev)
+{
+       int ret;
+       struct intel_kpd_gpio_led_pdata *pdata;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata)
+               return -EINVAL;
+
+       gpio = pdata->gpio;
+       if (gpio < 0)
+               return -EINVAL;
+
+       ret = gpio_request(gpio, "intel_kpd_led");
+       if (ret)
+               return ret;
+
+       ret = gpio_direction_output(gpio, 0);
+       if (ret) {
+               gpio_free(gpio);
+               return ret;
+       }
+
+       ret = led_classdev_register(&pdev->dev, &intel_kpd_led);
+       if (ret) {
+               dev_err(&pdev->dev, "register intel_kpd_led failed");
+               gpio_free(gpio);
+               return ret;
+       }
+       intel_keypad_led_set(&intel_kpd_led, intel_kpd_led.brightness);
+       register_early_suspend(&intel_kpd_led_suspend_desc);
+
+       return 0;
+}
+
+static int __devexit intel_kpd_led_remove(struct platform_device *pdev)
+{
+       intel_keypad_led_set(&intel_kpd_led, LED_OFF);
+       unregister_early_suspend(&intel_kpd_led_suspend_desc);
+       led_classdev_unregister(&intel_kpd_led);
+       gpio_free(gpio);
+
+       return 0;
+}
+
+static struct platform_driver kpd_led_driver = {
+       .driver = {
+                  .name = "intel_kpd_led",
+                  .owner = THIS_MODULE,
+       },
+       .probe = intel_kpd_led_probe,
+       .remove = __devexit_p(intel_kpd_led_remove),
+};
+
+static int __init intel_kpd_led_init(void)
+{
+       return platform_driver_register(&kpd_led_driver);
+}
+
+static void __exit intel_kpd_led_exit(void)
+{
+       platform_driver_unregister(&kpd_led_driver);
+}
+
+module_init(intel_kpd_led_init);
+module_exit(intel_kpd_led_exit);
+
+MODULE_AUTHOR("Shijie Zhang <shijie.zhang@intel.com>");
+MODULE_DESCRIPTION("Intel GPIO Keypad LED Driver");
+MODULE_LICENSE("GPL v2");