[patch] New leds-gpiodev driver

View: New views
1 Messages — Rating Filter:   Alert me  

[patch] New leds-gpiodev driver

by Kevin O'Connor-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I've found that on htc apache there are several LED devices that are
controlled by a simple gpio pin.  In order to simplify things, I've
created an led driver that can manipulate gpios conforming to the
gpiodev system.

I've converted the htc apache code to use this system.  (Patch to
follow shortly.)  I haven't looked at other platforms, but I suspect
this will be useful in other places.

Comments welcome.

-Kevin

--- /dev/null 2007-06-27 19:11:51.515574419 -0400
+++ drivers/leds/leds-gpiodev.c 2007-06-30 10:31:28.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * Support for LEDS attached to simple output GPIOs.
+ *
+ * (c) Copyright 2007 Kevin O'Connor <kevin@...>
+ *
+ * This file may be distributed under the terms of the GNU GPL license.
+ */
+
+#include <linux/kernel.h>
+#include <linux/leds.h> /* led_classdev */
+#include <linux/platform_device.h> /* platform_device */
+#include <linux/gpiodev.h> /* struct gpio */
+
+#include <linux/leds-gpiodev.h>
+
+struct leds_gpiodev {
+ struct led_classdev led;
+ struct gpio gpio;
+};
+
+#define ledtogd(Led) container_of((Led), struct leds_gpiodev, led)
+
+static void
+set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness)
+{
+ struct leds_gpiodev *al = ledtogd(led_cdev);
+ gpiodev_set_value(&al->gpio, brightness);
+}
+
+static int leds_probe(struct platform_device *pdev)
+{
+ struct leds_gpiodev_platform_data *pdata = pdev->dev.platform_data;
+ int i, ret=0;
+ struct leds_gpiodev *lgd;
+
+ lgd = kzalloc(sizeof(*lgd) * pdata->nr_leds, GFP_KERNEL);
+ if (!lgd)
+ return -ENOMEM;
+
+ for (i=0; i<pdata->nr_leds; i++) {
+ lgd[i].led.brightness_set = set_brightness;
+ lgd[i].led.name = pdata->leds[i].name;
+ lgd[i].gpio = pdata->leds[i].gpio;
+ ret = led_classdev_register(&pdev->dev, &lgd[i].led);
+ if (ret) {
+ printk(KERN_ERR "Error: can't register %s led\n",
+       lgd[i].led.name);
+ goto err;
+ }
+ }
+ /* Turn off all LEDs */
+ for (i=0; i<pdata->nr_leds; i++)
+ lgd[i].led.brightness_set(&lgd[i].led, 0);
+ platform_set_drvdata(pdev, lgd);
+ return 0;
+err:
+ while (--i >= 0)
+ led_classdev_unregister(&lgd[i].led);
+ kfree(lgd);
+ return ret;
+}
+
+static int leds_remove(struct platform_device *pdev)
+{
+ struct leds_gpiodev_platform_data *pdata = pdev->dev.platform_data;
+ struct leds_gpiodev *lgd = platform_get_drvdata(pdev);
+ int i;
+ for (i=0; i<pdata->nr_leds; i++)
+                led_classdev_unregister(&lgd[i].led);
+ kfree(lgd);
+ return 0;
+}
+
+static struct platform_driver leds_driver = {
+        .probe = leds_probe,
+        .remove = leds_remove,
+        .driver = {
+                .name = "leds-gpiodev",
+        },
+};
+
+static int __init leds_init(void)
+{
+ return platform_driver_register(&leds_driver);
+}
+
+static void __exit leds_exit(void)
+{
+ platform_driver_unregister(&leds_driver);
+}
+
+module_init(leds_init)
+module_exit(leds_exit)
+
+MODULE_LICENSE("GPL");
--- /dev/null 2007-06-27 19:11:51.515574419 -0400
+++ include/linux/leds-gpiodev.h 2007-06-30 10:31:07.000000000 -0400
@@ -0,0 +1,11 @@
+/* Information on each of the leds. */
+struct leds_gpiodev_info {
+ const char *name;
+ struct gpio gpio;
+};
+
+/* List of leds to register. */
+struct leds_gpiodev_platform_data {
+ struct leds_gpiodev_info *leds;
+ int nr_leds;
+};
? drivers/leds/.built-in.o.cmd
? drivers/leds/.led-class.o.cmd
? drivers/leds/.led-core.o.cmd
? drivers/leds/.leds-gpiodev.o.cmd
? drivers/leds/leds-gpiodev.c
Index: drivers/leds/Kconfig
===================================================================
RCS file: /cvs/linux/kernel26/drivers/leds/Kconfig,v
retrieving revision 1.20
diff -u -r1.20 Kconfig
--- drivers/leds/Kconfig 18 Jun 2007 16:55:55 -0000 1.20
+++ drivers/leds/Kconfig 30 Jun 2007 14:45:03 -0000
@@ -110,6 +110,13 @@
   This option enables support for the LEDs connected to the
   Samsung's HAMCOP chip.
 
+config LEDS_GPIODEV
+ tristate "Support for LEDs attached to GPIOs"
+ depends LEDS_CLASS
+ help
+  This option enables support for the LEDs connected to
+  various gpio chips conforming to the gpiodev interface.
+
 config LEDS_WRAP
  tristate "LED Support for the WRAP series LEDs"
  depends on LEDS_CLASS && SCx200_GPIO
Index: drivers/leds/Makefile
===================================================================
RCS file: /cvs/linux/kernel26/drivers/leds/Makefile,v
retrieving revision 1.16
diff -u -r1.16 Makefile
--- drivers/leds/Makefile 11 Jun 2007 16:44:46 -0000 1.16
+++ drivers/leds/Makefile 30 Jun 2007 14:45:03 -0000
@@ -23,6 +23,7 @@
 obj-$(CONFIG_LEDS_SAMCOP) += leds-samcop.o
 obj-$(CONFIG_LEDS_HAMCOP) += leds-hamcop.o
 obj-$(CONFIG_LEDS_GHI270) += leds-ghi270.o
+obj-$(CONFIG_LEDS_GPIODEV) += leds-gpiodev.o
 
 # LED Triggers
 obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o

_______________________________________________
Kernel-discuss mailing list
Kernel-discuss@...
https://handhelds.org/mailman/listinfo/kernel-discuss
LightInTheBox - Buy quality products at wholesale price!