Patchwork [Maverick,SRU,2/6] UBUNTU - ARM: igepv2: Fix and improve LED handling

login
register
mail settings
Submitter Mathieu Poirier
Date Oct. 11, 2010, 4:36 p.m.
Message ID <1286814985.3125.33.camel@black>
Download mbox | patch
Permalink /patch/67438/
State Accepted
Delegated to: Brad Figg
Headers show

Comments

Mathieu Poirier - Oct. 11, 2010, 4:36 p.m.
SRU Justification:

Impact: This patch is part of a series of fix for the IGEPv2. The board
features 4 LED that must be declared and linked to GPIOs.

Fix: The LEDs are initialized and controlled via the LED class if
CONFIG_LEDS_GPIO is selected or using the General Purpose Input/Output
(GPIO) interface if CONFIG_LEDS_GPIO is not selected. This patch depends
on [PATCH 1/6] of the same patch set, applied to BugLink:
https://bugs.launchpad.net/bugs/651589 .

Testcase: Without this patch LEDs are simply not working.


>From 557aff0985055d4d3cc05b414fdeca407056dbe1 Mon Sep 17 00:00:00 2001
From: Enric Balletbo i Serra <eballetbo@gmail.com>
Date: Mon, 11 Oct 2010 10:10:52 -0600
Subject: [PATCH 2/6] UBUNTU - ARM: igepv2: Fix and improve LED handling

The IGEP v2 board has four leds, this patch allows control all
of these LEDs using the LED class if CONFIG_LEDS_GPIO is selected
or using the General Purpose Input/Output (GPIO) interface if
CONFIG_LEDS_GPIO is not selected.

This work was tested by the community and also been submitted here:
http://marc.info/?l=linux-omap&m=128628835719191&w=2

BugLink: https://bugs.launchpad.net/bugs/654582

Signed-off-by: Enric Balletbo i Serra <eballetbo@gmail.com>
Signed-off-by: Mathieu J Poirier <mathieu.poirier@canonical.com>
---
 arch/arm/mach-omap2/board-igep0020.c |  156 +++++++++++++++++++---------------
 1 files changed, 87 insertions(+), 69 deletions(-)
Lee Jones - Oct. 12, 2010, 8:20 a.m.
On 11/10/10 17:36, Mathieu Poirier wrote:
> 
> SRU Justification:
> 
> Impact: This patch is part of a series of fix for the IGEPv2. The board
> features 4 LED that must be declared and linked to GPIOs.
> 
> Fix: The LEDs are initialized and controlled via the LED class if
> CONFIG_LEDS_GPIO is selected or using the General Purpose Input/Output
> (GPIO) interface if CONFIG_LEDS_GPIO is not selected. This patch depends
> on [PATCH 1/6] of the same patch set, applied to BugLink:
> https://bugs.launchpad.net/bugs/651589 .
> 
> Testcase: Without this patch LEDs are simply not working.
> 
> 
>>From 557aff0985055d4d3cc05b414fdeca407056dbe1 Mon Sep 17 00:00:00 2001
> From: Enric Balletbo i Serra <eballetbo@gmail.com>
> Date: Mon, 11 Oct 2010 10:10:52 -0600
> Subject: [PATCH 2/6] UBUNTU - ARM: igepv2: Fix and improve LED handling
> 
> The IGEP v2 board has four leds, this patch allows control all
> of these LEDs using the LED class if CONFIG_LEDS_GPIO is selected
> or using the General Purpose Input/Output (GPIO) interface if
> CONFIG_LEDS_GPIO is not selected.
> 
> This work was tested by the community and also been submitted here:
> http://marc.info/?l=linux-omap&m=128628835719191&w=2
> 
> BugLink: https://bugs.launchpad.net/bugs/654582
> 
> Signed-off-by: Enric Balletbo i Serra <eballetbo@gmail.com>
> Signed-off-by: Mathieu J Poirier <mathieu.poirier@canonical.com>
> ---
>  arch/arm/mach-omap2/board-igep0020.c |  156 +++++++++++++++++++---------------
>  1 files changed, 87 insertions(+), 69 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
> index 0b999f8..29a1e24 100644
> --- a/arch/arm/mach-omap2/board-igep0020.c
> +++ b/arch/arm/mach-omap2/board-igep0020.c
> @@ -261,6 +261,77 @@ static struct omap2_hsmmc_info mmc[] = {
>  	{}      /* Terminator */
>  };
>  
> +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
> +#include <linux/leds.h>
> +
> +static struct gpio_led igep2_gpio_leds[] = {
> +	[0] = {
> +		.name			= "gpio-led:red:d0",
> +		.gpio			= IGEP2_GPIO_LED0_RED,
> +		.default_trigger	= "default-off"
> +	},
> +	[1] = {
> +		.name			= "gpio-led:green:d0",
> +		.gpio			= IGEP2_GPIO_LED0_GREEN,
> +		.default_trigger	= "default-off",
> +	},
> +	[2] = {
> +		.name			= "gpio-led:red:d1",
> +		.gpio			= IGEP2_GPIO_LED1_RED,
> +		.default_trigger	= "default-off",
> +	},
> +	[3] = {
> +		.name			= "gpio-led:green:d1",
> +		.default_trigger	= "heartbeat",
> +		.gpio			= -EINVAL, /* gets replaced */
> +	},
> +};
> +
> +static struct gpio_led_platform_data igep2_led_pdata = {
> +	.leds           = igep2_gpio_leds,
> +	.num_leds       = ARRAY_SIZE(igep2_gpio_leds),
> +};
> +
> +static struct platform_device igep2_led_device = {
> +	 .name   = "leds-gpio",
> +	 .id     = -1,
> +	 .dev    = {
> +		 .platform_data  =  &igep2_led_pdata,
> +	},
> +};
> +
> +static void __init igep2_leds_init(void)
> +{
> +	platform_device_register(&igep2_led_device);
> +}
> +
> +#else
> +static inline void igep2_leds_init(void)
> +{
> +	if ((gpio_request(IGEP2_GPIO_LED0_RED, "gpio-led:red:d0") == 0) &&
> +	    (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
> +		gpio_export(IGEP2_GPIO_LED0_RED, 0);
> +		gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
> +	} else
> +		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
> +
> +	if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) &&
> +	    (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
> +		gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
> +		gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
> +	} else
> +		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
> +
> +	if ((gpio_request(IGEP2_GPIO_LED1_RED, "gpio-led:red:d1") == 0) &&
> +	    (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
> +		gpio_export(IGEP2_GPIO_LED1_RED, 0);
> +		gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
> +	} else
> +		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
> +
> +}
> +#endif
> +
>  static int igep2_twl_gpio_setup(struct device *dev,
>  		unsigned gpio, unsigned ngpio)
>  {
> @@ -290,14 +361,26 @@ static int igep2_twl_gpio_setup(struct device *dev,
>  	    (gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0) < 0))
>  		pr_err("IGEP2: Could not obtain gpio for USBH_CPEN");
>  
> +	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
> +#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
> +	if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0)
> +	    && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) {
> +		gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
> +		gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0);
> +	} else
> +		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_GREEN\n");
> +#else
> +	igep2_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
> +#endif
> +
>  	return 0;
>  };
>  
> -static struct twl4030_gpio_platform_data igep2_gpio_data = {
> +static struct twl4030_gpio_platform_data igep2_twl4030_gpio_pdata = {
>  	.gpio_base	= OMAP_MAX_GPIO_LINES,
>  	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>  	.irq_end	= TWL4030_GPIO_IRQ_END,
> -	.use_leds	= false,
> +	.use_leds	= true,
>  	.setup		= igep2_twl_gpio_setup,
>  };
>  
> @@ -371,47 +454,6 @@ static void __init igep2_display_init(void)
>  		pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
>  }
>  
> -#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
> -#include <linux/leds.h>
> -
> -static struct gpio_led igep2_gpio_leds[] = {
> -	{
> -		.name = "led0:red",
> -		.gpio = IGEP2_GPIO_LED0_RED,
> -	},
> -	{
> -		.name = "led0:green",
> -		.default_trigger = "heartbeat",
> -		.gpio = IGEP2_GPIO_LED0_GREEN,
> -	},
> -	{
> -		.name = "led1:red",
> -		.gpio = IGEP2_GPIO_LED1_RED,
> -	},
> -};
> -
> -static struct gpio_led_platform_data igep2_led_pdata = {
> -	.leds           = igep2_gpio_leds,
> -	.num_leds       = ARRAY_SIZE(igep2_gpio_leds),
> -};
> -
> -static struct platform_device igep2_led_device = {
> -	 .name   = "leds-gpio",
> -	 .id     = -1,
> -	 .dev    = {
> -		 .platform_data  =  &igep2_led_pdata,
> -	},
> -};
> -
> -static void __init igep2_init_led(void)
> -{
> -	platform_device_register(&igep2_led_device);
> -}
> -
> -#else
> -static inline void igep2_init_led(void) {}
> -#endif
> -
>  static struct platform_device *igep2_devices[] __initdata = {
>  	&igep2_dss_device,
>  };
> @@ -441,7 +483,7 @@ static struct twl4030_platform_data igep2_twldata = {
>  	/* platform_data for children goes here */
>  	.usb		= &igep2_usb_data,
>  	.codec		= &igep2_codec_data,
> -	.gpio		= &igep2_gpio_data,
> +	.gpio		= &igep2_twl4030_gpio_pdata,
>  	.vmmc1          = &igep2_vmmc1,
>  	.vmmc2		= &igep2_vmmc2,
>  	.vpll2		= &igep2_vpll2,
> @@ -502,34 +544,10 @@ static void __init igep2_init(void)
>  	usb_ehci_init(&ehci_pdata);
>  
>  	igep2_flash_init();
> -	igep2_init_led();
> +	igep2_leds_init();
>  	igep2_display_init();
>  	igep2_init_smsc911x();
>  
> -	/* GPIO userspace leds */
> -#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
> -	if ((gpio_request(IGEP2_GPIO_LED0_RED, "led0:red") == 0) &&
> -	    (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
> -		gpio_export(IGEP2_GPIO_LED0_RED, 0);
> -		gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
> -	} else
> -		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
> -
> -	if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "led0:green") == 0) &&
> -	    (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
> -		gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
> -		gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
> -	} else
> -		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
> -
> -	if ((gpio_request(IGEP2_GPIO_LED1_RED, "led1:red") == 0) &&
> -	    (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
> -		gpio_export(IGEP2_GPIO_LED1_RED, 0);
> -		gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
> -	} else
> -		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
> -#endif
> -
>  	/* GPIO W-LAN + Bluetooth combo module */
>  	if ((gpio_request(IGEP2_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) &&
>  	    (gpio_direction_output(IGEP2_GPIO_WIFI_NPD, 1) == 0)) {

Signed-off-by: Lee Jones <lee.jones@canonical.com>

Patch

diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 0b999f8..29a1e24 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -261,6 +261,77 @@  static struct omap2_hsmmc_info mmc[] = {
 	{}      /* Terminator */
 };
 
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led igep2_gpio_leds[] = {
+	[0] = {
+		.name			= "gpio-led:red:d0",
+		.gpio			= IGEP2_GPIO_LED0_RED,
+		.default_trigger	= "default-off"
+	},
+	[1] = {
+		.name			= "gpio-led:green:d0",
+		.gpio			= IGEP2_GPIO_LED0_GREEN,
+		.default_trigger	= "default-off",
+	},
+	[2] = {
+		.name			= "gpio-led:red:d1",
+		.gpio			= IGEP2_GPIO_LED1_RED,
+		.default_trigger	= "default-off",
+	},
+	[3] = {
+		.name			= "gpio-led:green:d1",
+		.default_trigger	= "heartbeat",
+		.gpio			= -EINVAL, /* gets replaced */
+	},
+};
+
+static struct gpio_led_platform_data igep2_led_pdata = {
+	.leds           = igep2_gpio_leds,
+	.num_leds       = ARRAY_SIZE(igep2_gpio_leds),
+};
+
+static struct platform_device igep2_led_device = {
+	 .name   = "leds-gpio",
+	 .id     = -1,
+	 .dev    = {
+		 .platform_data  =  &igep2_led_pdata,
+	},
+};
+
+static void __init igep2_leds_init(void)
+{
+	platform_device_register(&igep2_led_device);
+}
+
+#else
+static inline void igep2_leds_init(void)
+{
+	if ((gpio_request(IGEP2_GPIO_LED0_RED, "gpio-led:red:d0") == 0) &&
+	    (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
+		gpio_export(IGEP2_GPIO_LED0_RED, 0);
+		gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
+	} else
+		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
+
+	if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) &&
+	    (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
+		gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
+		gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
+	} else
+		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
+
+	if ((gpio_request(IGEP2_GPIO_LED1_RED, "gpio-led:red:d1") == 0) &&
+	    (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
+		gpio_export(IGEP2_GPIO_LED1_RED, 0);
+		gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
+	} else
+		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
+
+}
+#endif
+
 static int igep2_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
@@ -290,14 +361,26 @@  static int igep2_twl_gpio_setup(struct device *dev,
 	    (gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0) < 0))
 		pr_err("IGEP2: Could not obtain gpio for USBH_CPEN");
 
+	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
+	if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0)
+	    && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) {
+		gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
+		gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0);
+	} else
+		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_GREEN\n");
+#else
+	igep2_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
+#endif
+
 	return 0;
 };
 
-static struct twl4030_gpio_platform_data igep2_gpio_data = {
+static struct twl4030_gpio_platform_data igep2_twl4030_gpio_pdata = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
-	.use_leds	= false,
+	.use_leds	= true,
 	.setup		= igep2_twl_gpio_setup,
 };
 
@@ -371,47 +454,6 @@  static void __init igep2_display_init(void)
 		pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
 }
 
-#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-#include <linux/leds.h>
-
-static struct gpio_led igep2_gpio_leds[] = {
-	{
-		.name = "led0:red",
-		.gpio = IGEP2_GPIO_LED0_RED,
-	},
-	{
-		.name = "led0:green",
-		.default_trigger = "heartbeat",
-		.gpio = IGEP2_GPIO_LED0_GREEN,
-	},
-	{
-		.name = "led1:red",
-		.gpio = IGEP2_GPIO_LED1_RED,
-	},
-};
-
-static struct gpio_led_platform_data igep2_led_pdata = {
-	.leds           = igep2_gpio_leds,
-	.num_leds       = ARRAY_SIZE(igep2_gpio_leds),
-};
-
-static struct platform_device igep2_led_device = {
-	 .name   = "leds-gpio",
-	 .id     = -1,
-	 .dev    = {
-		 .platform_data  =  &igep2_led_pdata,
-	},
-};
-
-static void __init igep2_init_led(void)
-{
-	platform_device_register(&igep2_led_device);
-}
-
-#else
-static inline void igep2_init_led(void) {}
-#endif
-
 static struct platform_device *igep2_devices[] __initdata = {
 	&igep2_dss_device,
 };
@@ -441,7 +483,7 @@  static struct twl4030_platform_data igep2_twldata = {
 	/* platform_data for children goes here */
 	.usb		= &igep2_usb_data,
 	.codec		= &igep2_codec_data,
-	.gpio		= &igep2_gpio_data,
+	.gpio		= &igep2_twl4030_gpio_pdata,
 	.vmmc1          = &igep2_vmmc1,
 	.vmmc2		= &igep2_vmmc2,
 	.vpll2		= &igep2_vpll2,
@@ -502,34 +544,10 @@  static void __init igep2_init(void)
 	usb_ehci_init(&ehci_pdata);
 
 	igep2_flash_init();
-	igep2_init_led();
+	igep2_leds_init();
 	igep2_display_init();
 	igep2_init_smsc911x();
 
-	/* GPIO userspace leds */
-#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
-	if ((gpio_request(IGEP2_GPIO_LED0_RED, "led0:red") == 0) &&
-	    (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
-		gpio_export(IGEP2_GPIO_LED0_RED, 0);
-		gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
-	} else
-		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
-
-	if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "led0:green") == 0) &&
-	    (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
-		gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
-		gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
-	} else
-		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
-
-	if ((gpio_request(IGEP2_GPIO_LED1_RED, "led1:red") == 0) &&
-	    (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
-		gpio_export(IGEP2_GPIO_LED1_RED, 0);
-		gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
-	} else
-		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
-#endif
-
 	/* GPIO W-LAN + Bluetooth combo module */
 	if ((gpio_request(IGEP2_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) &&
 	    (gpio_direction_output(IGEP2_GPIO_WIFI_NPD, 1) == 0)) {