staging: nvec: add LED support
authorIlya Petrov <ilya.muromec@gmail.com>
Tue, 27 Sep 2011 17:00:44 +0000 (19:00 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 30 Sep 2011 00:40:38 +0000 (17:40 -0700)
This patch adds support for LEDs connect to a nvec. A single brightness
property is exported to sysfs. LEDs are selected via bitfields in the
brightness value. Also the blinking behavior is selected through this
method. Vendors may use different values for different HW designs.

Signed-off-by: Ilya Petrov <ilya.muromec@gmail.com>
Signed-off-by: Marc Dietrich <marvin24@gmx.de>
[jak@jak-linux.org: Fixed checkpatch warnings]
Signed-off-by: Julian Andres Klode <jak@jak-linux.org>
Acked-by: Marc Dietrich <marvin24@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/nvec/Kconfig
drivers/staging/nvec/Makefile
drivers/staging/nvec/nvec.c
drivers/staging/nvec/nvec_kbd.c
drivers/staging/nvec/nvec_leds.c [new file with mode: 0644]

index 987ad48ff939a3600f8a55a00851cb9676ba21c4..a86cf27ae244d003919bd864591cb8530ca3357b 100644 (file)
@@ -25,3 +25,9 @@ config NVEC_POWER
        help
          Say Y to enable support for battery and charger interface for
          nVidia compliant embedded controllers.
+
+config NVEC_LEDS
+       bool "NVEC leds"
+       depends on MFD_NVEC && LEDS_CLASS
+       help
+         Say Y to enable yellow side leds on AC100 or other nVidia tegra nvec leds
index 4b5fcec1a10fed6fd99794c26c3384e04b7b6bda..b844d604e3acad21da871584ec93b002ee6cbb17 100644 (file)
@@ -2,3 +2,4 @@ obj-$(CONFIG_SERIO_NVEC_PS2)    += nvec_ps2.o
 obj-$(CONFIG_MFD_NVEC)         += nvec.o
 obj-$(CONFIG_NVEC_POWER)       += nvec_power.o
 obj-$(CONFIG_KEYBOARD_NVEC)    += nvec_kbd.o
+obj-$(CONFIG_NVEC_LEDS)        += nvec_leds.o
index 6913018979852eb1a7c8e16b95ca9d6cf3091cd3..43a83a953d46fe475f3641b200538b9cfb3152e9 100644 (file)
@@ -63,6 +63,10 @@ static struct mfd_cell nvec_devices[] = {
                .name = "nvec-power",
                .id = 2,
        },
+       {
+               .name = "nvec-leds",
+               .id = 1,
+       },
 };
 
 int nvec_register_notifier(struct nvec_chip *nvec, struct notifier_block *nb,
index 06e877cf1518c9bffafc04d0eb6efb43c9be62c7..eaaafac6806de48f11f16e5a3d1c1d77a8e4b0fd 100644 (file)
@@ -99,8 +99,8 @@ static int __devinit nvec_kbd_probe(struct platform_device *pdev)
                keycodes[j++] = extcode_tab_us102[i];
 
        idev = input_allocate_device();
-       idev->name = "Tegra nvec keyboard";
-       idev->phys = "i2c3_slave/nvec";
+       idev->name = "nvec keyboard";
+       idev->phys = "nvec";
        idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_LED);
        idev->ledbit[0] = BIT_MASK(LED_CAPSL);
        idev->event = nvec_kbd_event;
diff --git a/drivers/staging/nvec/nvec_leds.c b/drivers/staging/nvec/nvec_leds.c
new file mode 100644 (file)
index 0000000..f4cbcd6
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * nvec_leds: LED driver for a NVIDIA compliant embedded controller
+ *
+ * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.launchpad.net>
+ *
+ * Authors:  Ilya Petrov <ilya.muromec@gmail.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include "nvec.h"
+
+#define to_nvec_led(led_cdev) \
+       container_of(led_cdev, struct nvec_led, cdev)
+
+#define NVEC_LED_REQ {'\x0d', '\x10', '\x45', '\x10', '\x00'}
+
+#define NVEC_LED_MAX 8
+
+struct nvec_led {
+       struct led_classdev cdev;
+       struct nvec_chip *nvec;
+};
+
+static void nvec_led_brightness_set(struct led_classdev *led_cdev,
+                                   enum led_brightness value)
+{
+       struct nvec_led *led = to_nvec_led(led_cdev);
+       unsigned char buf[] = NVEC_LED_REQ;
+       buf[4] = value;
+
+       nvec_write_async(led->nvec, buf, sizeof(buf));
+
+       led->cdev.brightness = value;
+
+}
+
+static int __devinit nvec_led_probe(struct platform_device *pdev)
+{
+       struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+       struct nvec_led *led;
+       int ret = 0;
+
+       led = kzalloc(sizeof(*led), GFP_KERNEL);
+       if (led == NULL)
+               return -ENOMEM;
+
+       led->cdev.max_brightness = NVEC_LED_MAX;
+
+       led->cdev.brightness_set = nvec_led_brightness_set;
+       led->cdev.name = "nvec-led";
+       led->cdev.flags |= LED_CORE_SUSPENDRESUME;
+       led->nvec = nvec;
+
+       platform_set_drvdata(pdev, led);
+
+       ret = led_classdev_register(&pdev->dev, &led->cdev);
+       if (ret < 0)
+               goto err_led;
+
+       /* to expose the default value to userspace */
+       led->cdev.brightness = 0;
+
+       return 0;
+
+err_led:
+       kfree(led);
+       return ret;
+}
+
+static int __devexit nvec_led_remove(struct platform_device *pdev)
+{
+       struct nvec_led *led = platform_get_drvdata(pdev);
+
+       led_classdev_unregister(&led->cdev);
+       kfree(led);
+       return 0;
+}
+
+static struct platform_driver nvec_led_driver = {
+       .probe  = nvec_led_probe,
+       .remove = __devexit_p(nvec_led_remove),
+       .driver = {
+                  .name  = "nvec-leds",
+                  .owner = THIS_MODULE,
+       },
+};
+
+static int __init nvec_led_init(void)
+{
+       return platform_driver_register(&nvec_led_driver);
+}
+
+module_init(nvec_led_init);
+
+static void __exit nvec_led_exit(void)
+{
+       platform_driver_unregister(&nvec_led_driver);
+}
+
+module_exit(nvec_led_exit);
+
+MODULE_AUTHOR("Ilya Petrov <ilya.muromec@gmail.com>");
+MODULE_DESCRIPTION("Tegra NVEC LED driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:nvec-leds");