[Port from R2-stable] Intel Keypad LED driver patches
authorShijie Zhang <shijie.zhang@intel.com>
Fri, 16 Dec 2011 00:23:17 +0000 (08:23 +0800)
committerbuildbot <buildbot@intel.com>
Fri, 16 Dec 2011 08:57:41 +0000 (00:57 -0800)
BZ: 17581

This BZ includes the following BZ:
10361, 13071, 13148, 13751, 14636, 14411, 15649

Change-Id: I801658043354cd0de3f680425e63790c6c5fd040
Signed-off-by: Shijie Zhang <shijie.zhang@intel.com>
Reviewed-on: http://android.intel.com:8080/27709
Reviewed-by: Du, Alek <alek.du@intel.com>
Reviewed-by: Yang, Bin <bin.yang@intel.com>
Tested-by: Wang, Zhifeng <zhifeng.wang@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
arch/x86/configs/i386_mfld_defconfig
arch/x86/include/asm/intel_scu_ipc.h
arch/x86/platform/mrst/mrst.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/leds-intel-kpd.c [new file with mode: 0644]

index 18c7545..b86697f 100644 (file)
@@ -1964,7 +1964,13 @@ CONFIG_MMC_SDHCI_PCI=y
 # CONFIG_MMC_VUB300 is not set
 # CONFIG_MMC_USHC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
+
+# LED Drivers
+
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_INTEL_KPD=y
+
 CONFIG_NFC_DEVICES=y
 CONFIG_PN544_NFC=y
 CONFIG_SWITCH=y
index c2985ea..7c365a2 100644 (file)
@@ -116,10 +116,6 @@ static inline int intel_scu_notifier_post(unsigned long v, void *p)
 #define MSIC_VPROG_ON          0xFF
 #define MSIC_VPROG_OFF         0
 
-#define MSIC_REG_PWM0CLKDIV1 0x61
-#define MSIC_REG_PWM0CLKDIV0 0x62
-#define MSIC_REG_PWM0DUTYCYCLE 0x67
-
 /* Helpers to turn on/off msic vprog1 and vprog2 */
 static inline int intel_scu_ipc_msic_vprog1(int on)
 {
index 6bb98cf..b249edb 100644 (file)
@@ -1846,6 +1846,7 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
        struct i2c_board_info i2c_info;
        struct hsi_board_info hsi_info;
        struct sd_board_info sd_info;
+       struct platform_device *pdev;
        int num, i, bus;
        int ioapic;
        struct io_apic_irq_attr irq_attr;
@@ -1954,6 +1955,19 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
                        ;
                }
        }
+
+#ifdef CONFIG_LEDS_INTEL_KPD
+       pdev = platform_device_alloc("intel_kpd_led", 0);
+       if (!pdev)
+               pr_err("out of memory for SFI platform dev 'intel_kpd_led'.\n");
+       else {
+               install_irq_resource(pdev, 0xff);
+               pr_info("info[%2d]: IPC bus, name = %16.16s, "
+                       "irq = 0x%2x\n", i, "intel_kpd_led", pentry->irq);
+               intel_scu_device_register(pdev);
+       }
+#endif
+
        return 0;
 }
 
index b84e46b..75b35d1 100644 (file)
@@ -369,6 +369,16 @@ config LEDS_MC13783
          This option enable support for on-chip LED drivers found
          on Freescale Semiconductor MC13783 PMIC.
 
+config LEDS_INTEL_KPD
+        tristate "LED driver for Intel Keypad LED"
+        depends on INTEL_SCU_IPC
+        help
+          This option enables to support for Intel Keypad LED on Medfield 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 cb77b9b..8ab64bb 100644 (file)
@@ -43,6 +43,7 @@ obj-$(CONFIG_LEDS_MC13783)            += leds-mc13783.o
 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
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)          += leds-dac124s085.o
diff --git a/drivers/leds/leds-intel-kpd.c b/drivers/leds/leds-intel-kpd.c
new file mode 100644 (file)
index 0000000..08edcdc
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * leds-intel-kpd.c - Intel Keypad LED driver
+ *
+ * Copyright (C) 2011 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/device.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/earlysuspend.h>
+#include <asm/intel_scu_ipc.h>
+
+#define        MSIC_REG_PWM0CLKDIV1    0x061
+#define        MSIC_REG_PWM0CLKDIV0    0x062
+#define        MSIC_REG_PWM0DUTYCYCLE  0x067
+
+static void intel_keypad_led_set(struct led_classdev *led_cdev,
+       enum led_brightness value)
+{
+       int ret;
+
+       ret = intel_scu_ipc_iowrite8(MSIC_REG_PWM0CLKDIV1, 0x00);
+       if (ret)
+               dev_err(led_cdev->dev, "set MSIC_REG_PWM0CLKDIV1 failed");
+
+       ret = intel_scu_ipc_iowrite8(MSIC_REG_PWM0CLKDIV0, 0x03);
+       if (ret)
+               dev_err(led_cdev->dev, "set MSIC_REG_PWM0CLKDIV0 failed");
+
+       ret = intel_scu_ipc_iowrite8(MSIC_REG_PWM0DUTYCYCLE, value);
+       if (ret)
+               dev_err(led_cdev->dev, "set MSIC_REG_PWM0DUTYCYCLE failed");
+
+       if (value == 0) {
+               ret = intel_scu_ipc_iowrite8(MSIC_REG_PWM0CLKDIV0, 0x00);
+               if (ret)
+                       dev_err(led_cdev->dev, "set MSIC_REG_PWM0CLKDIV0 failed\n");
+       }
+
+}
+
+static struct led_classdev intel_kpd_led = {
+       .name                   = "intel_keypad_led",
+       .brightness_set         = intel_keypad_led_set,
+       .brightness             = LED_OFF,
+       .max_brightness         = 15,
+};
+
+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;
+
+       ret = led_classdev_register(&pdev->dev, &intel_kpd_led);
+       if (ret) {
+               dev_err(&pdev->dev, "register intel_kpd_led failed");
+               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);
+
+       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)
+{
+       int ret;
+       ret = platform_driver_register(&kpd_led_driver);
+       return ret;
+}
+
+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_DESCRIPTION("Intel Keypad LED Driver");
+MODULE_LICENSE("GPL v2");