All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marian Balakowicz <m8@semihalf.com>
To: linuxppc-dev@ozlabs.org
Subject: [PATCH 11/15] [POWERPC] Motion-PRO: Add LED support.
Date: Sun, 07 Oct 2007 13:31:12 +0200	[thread overview]
Message-ID: <4708C380.3070707@semihalf.com> (raw)
In-Reply-To: <47075FA7.3030108@semihalf.com>


Add LED driver for Promess Motion-PRO board.

Signed-off-by: Jan Wrobel <wrr@semihalf.com>
---

 arch/powerpc/configs/motionpro_defconfig |    3 
 arch/powerpc/platforms/52xx/motionpro.c  |   38 +++++
 drivers/leds/Kconfig                     |    7 
 drivers/leds/Makefile                    |    1 
 drivers/leds/leds-motionpro.c            |  221 +++++++++++++++++++++++++++++++
 include/asm-powerpc/mpc52xx.h            |    5 
 6 files changed, 274 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/configs/motionpro_defconfig b/arch/powerpc/configs/motionpro_defconfig
index fcce47e..ce62123 100644
--- a/arch/powerpc/configs/motionpro_defconfig
+++ b/arch/powerpc/configs/motionpro_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.23-rc9
-# Fri Oct  5 12:54:17 2007
+# Fri Oct  5 15:18:42 2007
 #
 # CONFIG_PPC64 is not set
 
@@ -610,6 +610,7 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+CONFIG_LEDS_MOTIONPRO=y
 
 #
 # LED Triggers
diff --git a/arch/powerpc/platforms/52xx/motionpro.c b/arch/powerpc/platforms/52xx/motionpro.c
index 2cf8a47..c1bcfd2 100644
--- a/arch/powerpc/platforms/52xx/motionpro.c
+++ b/arch/powerpc/platforms/52xx/motionpro.c
@@ -86,10 +86,48 @@ error:
 	iounmap(gpio);
 }
 
+
+#ifdef CONFIG_LEDS_MOTIONPRO
+
+/* Initialize GPT register connected to LED. Turn off LED. */
+static void motionpro_setup_led(const char *reg_path)
+{
+	void __iomem *reg_addr;
+	u32 reg;
+
+	reg_addr = mpc52xx_find_and_map_path(reg_path);
+	if (!reg_addr){
+		printk(KERN_ERR __FILE__ ": "
+		       "LED setup error: can't map GPIO register %s\n",
+		       reg_path);
+		return;
+	}
+
+	reg = in_be32(reg_addr);
+	reg |= MPC52xx_GPT_ENABLE_OUTPUT;
+	reg &= ~MPC52xx_GPT_OUTPUT_1;
+	out_be32(reg_addr, reg);
+
+	iounmap(reg_addr);
+}
+
+/* Initialize Motionpro status and ready LEDs */
+static void motionpro_setup_leds(void)
+{
+	motionpro_setup_led("/soc5200@f0000000/gpt@660");
+	motionpro_setup_led("/soc5200@f0000000/gpt@670");
+}
+
+#endif
+
 static void __init motionpro_setup_arch(void)
 {
 	struct device_node *np;
 
+#ifdef CONFIG_LEDS_MOTIONPRO
+	motionpro_setup_leds();
+#endif
+
 	if (ppc_md.progress)
 		ppc_md.progress("motionpro_setup_arch()", 0);
 
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 4468cb3..f027009 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -55,6 +55,13 @@ config LEDS_TOSA
 	  This option enables support for the LEDs on Sharp Zaurus
 	  SL-6000 series.
 
+config LEDS_MOTIONPRO
+	tristate "Motionpro LEDs Support"
+	depends on LEDS_CLASS
+	help
+	  This option enables support for status and ready LEDs connected
+	  to GPIO lines on Motionpro board.
+
 config LEDS_S3C24XX
 	tristate "LED Support for Samsung S3C24XX GPIO LEDs"
 	depends on LEDS_CLASS && ARCH_S3C2410
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index f8995c9..6b45be1 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_LEDS_NET48XX)		+= leds-net48xx.o
 obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o
 obj-$(CONFIG_LEDS_H1940)		+= leds-h1940.o
 obj-$(CONFIG_LEDS_COBALT)		+= leds-cobalt.o
+obj-$(CONFIG_LEDS_MOTIONPRO)		+= leds-motionpro.o
 obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o
 
 # LED Triggers
diff --git a/drivers/leds/leds-motionpro.c b/drivers/leds/leds-motionpro.c
new file mode 100644
index 0000000..273e375
--- /dev/null
+++ b/drivers/leds/leds-motionpro.c
@@ -0,0 +1,221 @@
+/*
+ * LEDs driver for the Motionpro board.
+ * 
+ * Copyright (C) 2007 Semihalf
+ *
+ * Author: Jan Wrobel <wrr@semihalf.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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., 51
+ * Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ * This driver enables control over Motionpro's status and ready LEDs through
+ * sysfs. LEDs can be controlled by writing to sysfs files:
+ * class/leds/motionpro-(ready|status)led/(brightness|delay_off|delay_on).
+ * See Documentation/leds-class.txt for more details
+ *
+ * Before user issues first control command via sysfs, LED blinking is
+ * controlled by the kernel. By default status LED is blinking fast and ready
+ * LED is turned off.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+
+#include <asm/mpc52xx.h>
+#include <asm/io.h>
+
+/* Led status */
+#define LED_NOT_REGISTERED	0
+#define LED_KERNEL_CONTROLLED	1
+#define LED_USER_CONTROLLED	2
+
+
+/* Led control bits */
+#define LED_ON	MPC52xx_GPT_OUTPUT_1
+
+static void mpled_set(struct led_classdev *led_cdev,
+		      enum led_brightness brightness);
+
+static struct motionpro_led{
+	/* Protects the led data */
+	spinlock_t led_lock;
+
+	/* Path to led's control register DTS node */
+	char *reg_path;
+
+	/* Address to access led's register */
+	void __iomem *reg_addr;
+
+	int status;
+
+	/* Blinking timer used when led is controlled by the kernel */
+	struct timer_list kernel_mode_timer;
+
+	/*
+	 * Delay between blinks when led is controlled by the kernel.
+	 * If set to 0 led blinking is off.
+	 */
+	int kernel_mode_delay;
+
+	struct led_classdev classdev;
+}led[] = {
+	{
+		.reg_path = "/soc5200@f0000000/gpt@660",
+		.reg_addr = 0,
+		.led_lock = SPIN_LOCK_UNLOCKED,
+		.status = LED_NOT_REGISTERED,
+		.kernel_mode_delay = HZ / 10,
+		.classdev = {
+			.name = "motionpro-statusled",
+			.brightness_set = mpled_set,
+			.default_trigger = "timer",
+		},
+	},
+	{
+		.reg_path = "/soc5200@f0000000/gpt@670",
+		.reg_addr = 0,
+		.led_lock = SPIN_LOCK_UNLOCKED,
+		.status = LED_NOT_REGISTERED,
+		.kernel_mode_delay = 0,
+		.classdev = {
+			.name = "motionpro-readyled",
+			.brightness_set = mpled_set,
+			.default_trigger = "timer",
+		}
+	}
+};
+
+/* Timer event - blinks led before user takes control over it */
+static void mpled_timer_toggle(unsigned long ptr)
+{
+	struct motionpro_led *mled = (struct motionpro_led *) ptr;
+
+	spin_lock_bh(&mled->led_lock);
+	if (mled->status == LED_KERNEL_CONTROLLED){
+		u32 reg = in_be32(mled->reg_addr);
+		reg ^= LED_ON;
+		out_be32(mled->reg_addr, reg);
+		led->kernel_mode_timer.expires = jiffies +
+			led->kernel_mode_delay;
+		add_timer(&led->kernel_mode_timer);
+	}
+	spin_unlock_bh(&mled->led_lock);
+}
+
+
+/*
+ * Turn on/off led according to user settings in sysfs.
+ * First call to this function disables kernel blinking.
+ */
+static void mpled_set(struct led_classdev *led_cdev,
+		      enum led_brightness brightness)
+{
+	struct motionpro_led *mled;
+	u32 reg;
+
+	mled = container_of(led_cdev, struct motionpro_led, classdev);
+
+	spin_lock_bh(&mled->led_lock);
+	mled->status = LED_USER_CONTROLLED;
+
+	reg = in_be32(mled->reg_addr);
+	if (brightness)
+		reg |= LED_ON;
+	else
+		reg &= ~LED_ON;
+	out_be32(mled->reg_addr, reg);
+
+	spin_unlock_bh(&mled->led_lock);
+}
+
+static void mpled_init_led(void __iomem *reg_addr)
+{
+	u32 reg = in_be32(reg_addr);
+	reg |= MPC52xx_GPT_ENABLE_OUTPUT;
+	reg &= ~LED_ON;
+	out_be32(reg_addr, reg);
+}
+
+static void mpled_clean(void)
+{
+	int i;
+	for (i = 0; i < sizeof(led) / sizeof(struct motionpro_led); i++){
+		if (led[i].status != LED_NOT_REGISTERED){
+			spin_lock_bh(&led[i].led_lock);
+			led[i].status = LED_NOT_REGISTERED;
+			spin_unlock_bh(&led[i].led_lock);
+			led_classdev_unregister(&led[i].classdev);
+		}
+		if (led[i].reg_addr){
+			iounmap(led[i].reg_addr);
+			led[i].reg_addr = 0;
+		}
+	}
+}
+
+static int __init mpled_init(void)
+{
+	int i, error;
+
+	for (i = 0; i < sizeof(led) / sizeof(struct motionpro_led); i++){
+		led[i].reg_addr = mpc52xx_find_and_map_path(led[i].reg_path);
+		if (!led[i].reg_addr){
+			printk(KERN_ERR __FILE__ ": "
+			       "Error while mapping GPIO register for LED %s\n",
+			       led[i].classdev.name);
+			error = -EIO;
+			goto err;
+		}
+
+		mpled_init_led(led[i].reg_addr);
+		led[i].status = LED_KERNEL_CONTROLLED;
+		if (led[i].kernel_mode_delay){
+			init_timer(&led[i].kernel_mode_timer);
+			led[i].kernel_mode_timer.function = mpled_timer_toggle;
+			led[i].kernel_mode_timer.data = (unsigned long)&led[i];
+			led[i].kernel_mode_timer.expires =
+				jiffies + led[i].kernel_mode_delay;
+			add_timer(&led[i].kernel_mode_timer);
+		}
+
+		if ((error = led_classdev_register(NULL, &led[i].classdev)) < 0){
+			printk(KERN_ERR __FILE__ ": "
+			       "Error while registering class device for LED "
+			       "%s\n",
+			       led[i].classdev.name);
+			goto err;
+		}
+	}
+
+	printk("Motionpro LEDs driver initialized\n");
+	return 0;
+err:
+	mpled_clean();
+	return error;
+}
+
+static void __exit mpled_exit(void)
+{
+	mpled_clean();
+}
+
+module_init(mpled_init);
+module_exit(mpled_exit);
+
+MODULE_LICENSE("GPL")
+MODULE_DESCRIPTION("LEDs support for Motionpro");
+MODULE_AUTHOR("Jan Wrobel <wrr@semihalf.com>");
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
index 4707de6..a431798 100644
--- a/include/asm-powerpc/mpc52xx.h
+++ b/include/asm-powerpc/mpc52xx.h
@@ -140,6 +140,11 @@ struct mpc52xx_gpio {
 #define MPC52xx_GPIO_PSC_CONFIG_UART_WITH_CD	5
 #define MPC52xx_GPIO_PCI_DIS			(1<<15)
 
+/* Enables GPT register to operate as simple GPIO output register */
+#define MPC52xx_GPT_ENABLE_OUTPUT	0x00000024
+/* Puts 1 on GPT output pin */
+#define MPC52xx_GPT_OUTPUT_1		0x00000010
+
 /* GPIO with WakeUp*/
 struct mpc52xx_gpio_wkup {
 	u8 wkup_gpioe;		/* GPIO_WKUP + 0x00 */

  parent reply	other threads:[~2007-10-07 11:31 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-06 10:12 [PATCH 00/15] [POWERPC] TQM5200, CM5200 and Motion-PRO support Marian Balakowicz
2007-10-07 11:15 ` [PATCH 01/15] [POWERPC] TQM5200 DTS Marian Balakowicz
2007-10-07 17:36   ` Grant Likely
2007-10-07 20:30     ` Wolfgang Denk
2007-10-17 11:10     ` Marian Balakowicz
2007-10-17 14:57       ` Grant Likely
2007-10-08  6:27   ` Grant Likely
2007-10-08 13:52     ` Kumar Gala
2007-10-07 11:18 ` [PATCH 02/15] [POWERPC] TQM5200 defconfig Marian Balakowicz
2007-10-07 11:19 ` [POWERPC 03/15] [POWERPC] TQM5200 board support Marian Balakowicz
2007-10-07 12:21   ` Stephen Rothwell
2007-10-08  6:21   ` Grant Likely
2007-10-08  7:44     ` Wolfgang Denk
2007-10-08  7:54       ` Grant Likely
2007-10-08 20:48         ` Grant Likely
2007-10-08 22:32           ` Wolfgang Denk
2007-10-08 22:37             ` Grant Likely
2007-10-17 11:24     ` Marian Balakowicz
2007-10-08 15:04   ` Scott Wood
2007-10-17 11:42     ` Marian Balakowicz
2007-10-17 15:33       ` Scott Wood
2007-10-07 11:20 ` [PATCH 04/15] [POWERPC] CM5200 DTS Marian Balakowicz
2007-10-08  1:50   ` David Gibson
2007-10-17 12:22     ` Marian Balakowicz
2007-10-17 14:59       ` Grant Likely
2007-10-18  0:22       ` David Gibson
2007-10-19 11:06         ` Marian Balakowicz
2007-10-07 11:22 ` [PATCH 05/15] [POWERPC] CM5200 defconfig Marian Balakowicz
2007-10-07 11:24 ` [PATCH 06/15] [POWERPC] CM5200 board support Marian Balakowicz
2007-10-07 12:29   ` Stephen Rothwell
2007-10-08  6:28     ` Grant Likely
2007-10-07 11:25 ` [PATCH 07/15] [POWERPC] Promess Motion-PRO DTS Marian Balakowicz
2007-10-08  1:53   ` David Gibson
2007-10-08  6:44   ` Grant Likely
2007-10-08 14:58   ` Scott Wood
2007-10-08 15:16     ` Grant Likely
2007-10-18 12:50   ` Wolfgang Grandegger
2007-10-18 12:54     ` David Gibson
2007-10-18 13:16     ` Grant Likely
2007-10-07 11:26 ` [PATCH 08/15] [POWERPC] Promess Motion-PRO defconfig Marian Balakowicz
2007-10-07 11:28 ` [PATCH 09/15] [POWERPC] Promess Motion-PRO board support Marian Balakowicz
2007-10-07 12:32   ` Stephen Rothwell
2007-10-08  6:45     ` Grant Likely
2007-10-07 11:30 ` [PATCH 10/15] [POWERPC] Add mpc52xx_find_and_map_path(), refactor utility functions Marian Balakowicz
2007-10-08  6:47   ` Grant Likely
2007-10-07 11:31 ` Marian Balakowicz [this message]
2007-10-08  7:10   ` [PATCH 11/15] [POWERPC] Motion-PRO: Add LED support Grant Likely
2007-10-07 11:32 ` [PATCH 12/15] [POWERPC] Add mpc52xx_restart(), mpc52xx_halt(), mpc52xx_power_off() Marian Balakowicz
2007-10-08  7:15   ` Grant Likely
2007-10-08 13:56   ` Kumar Gala
2007-10-07 11:32 ` [PATCH 13/15] [POWERPC] Init restart/halt/power_off machine hooks for TQM5200 Marian Balakowicz
2007-10-07 11:35 ` [PATCH 14/15] [POWERPC] Init restart/halt/power_off machine hooks for CM5200 Marian Balakowicz
2007-10-07 11:36 ` [PATCH 15/15] [POWERPC] Init restart/halt/power_off machine hooks for Motion-PRO Marian Balakowicz
2007-10-08  7:16 ` [PATCH 00/15] [POWERPC] TQM5200, CM5200 and Motion-PRO support Grant Likely
2007-10-08 13:57 ` Kumar Gala
2007-10-09  9:08 ` Marian Balakowicz
2007-10-09 14:38   ` Grant Likely
2007-10-09 15:57     ` Kumar Gala

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4708C380.3070707@semihalf.com \
    --to=m8@semihalf.com \
    --cc=linuxppc-dev@ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.