diff --git a/src/Makefile b/src/Makefile
index 4e1b7dd..ed5c1a3 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -670,6 +670,7 @@ hostmot2-objs :=                          \
     hal/drivers/mesa-hostmot2/stepgen.o   \
     hal/drivers/mesa-hostmot2/watchdog.o  \
     hal/drivers/mesa-hostmot2/pins.o      \
+	hal/drivers/mesa-hostmot2/led.o       \
     hal/drivers/mesa-hostmot2/tram.o      \
     hal/drivers/mesa-hostmot2/raw.o       \
     hal/drivers/mesa-hostmot2/bitfile.o   \
diff --git a/src/hal/drivers/mesa-hostmot2/hostmot2.c b/src/hal/drivers/mesa-hostmot2/hostmot2.c
index ea48248..4d1bf40 100644
--- a/src/hal/drivers/mesa-hostmot2/hostmot2.c
+++ b/src/hal/drivers/mesa-hostmot2/hostmot2.c
@@ -114,6 +114,7 @@ static void hm2_write(void *void_hm2, long period) {
 	hm2_tp_pwmgen_write(hm2); // update Three Phase PWM registers if needed
     hm2_stepgen_write(hm2);   // update stepgen registers if needed
     hm2_encoder_write(hm2);   // update ctrl register if needed
+	hm2_led_write(hm2);		  // Update on-board LEDs
     hm2_raw_write(hm2);
 }
 
@@ -174,6 +175,7 @@ const char *hm2_get_general_function_name(int gtag) {
         case HM2_GTAG_PWMGEN:          return "PWMGen";
         case HM2_GTAG_TRANSLATIONRAM:  return "TranslationRAM";
 		case HM2_GTAG_3PPWM:		   return "ThreePhasePWM";
+		case HM2_GTAG_LED:			   return "LED";
         default: {
             static char unknown[100];
             rtapi_snprintf(unknown, 100, "(unknown-gtag-%d)", gtag);
@@ -633,6 +635,10 @@ static int hm2_parse_module_descriptors(hostmot2_t *hm2) {
 			case HM2_GTAG_3PPWM:
 				md_accepted = hm2_tp_pwmgen_parse_md(hm2, md_index);
 				break;
+			
+			case HM2_GTAG_LED:
+				md_accepted = hm2_led_parse_md(hm2, md_index);
+				break;
 
             default:
                 HM2_WARN(
diff --git a/src/hal/drivers/mesa-hostmot2/hostmot2.h b/src/hal/drivers/mesa-hostmot2/hostmot2.h
index d53456e..06b9c13 100644
--- a/src/hal/drivers/mesa-hostmot2/hostmot2.h
+++ b/src/hal/drivers/mesa-hostmot2/hostmot2.h
@@ -101,6 +101,7 @@ char **argv_split(gfp_t gfp, const char *str, int *argcp);
 #define HM2_GTAG_PWMGEN           (6)
 #define HM2_GTAG_TRANSLATIONRAM  (11)
 #define HM2_GTAG_3PPWM			 (19)
+#define HM2_GTAG_LED			(128)
 
 
 
@@ -640,6 +641,30 @@ typedef struct {
     u32 *reset_reg;
 } hm2_watchdog_t;
 
+//
+// On-board LEDs
+//
+
+typedef struct {
+	struct {
+		struct {
+			hal_bit_t *cr8;
+			hal_bit_t *cr7;
+			hal_bit_t *cr6;
+			hal_bit_t *cr5;
+			hal_bit_t *cr4;
+			hal_bit_t *cr3;
+			hal_bit_t *cr2;
+			hal_bit_t *cr1;
+		} pin ;
+	} hal ;
+		
+	u32 written_byte ;
+	
+	u32 led_addr;
+    u32 *led_reg;
+	
+} hm2_led_t ;
 	
 
 // 
@@ -721,6 +746,7 @@ typedef struct {
     hm2_stepgen_t stepgen;
     hm2_ioport_t ioport;
     hm2_watchdog_t watchdog;
+	hm2_led_t *led;
     hm2_raw_t *raw;
 
     struct list_head list;
@@ -878,6 +904,13 @@ void hm2_watchdog_cleanup(hostmot2_t *hm2);
 void hm2_watchdog_write(hostmot2_t *hm2);
 void hm2_watchdog_force_write(hostmot2_t *hm2);
 
+//
+// LED functions
+//
+
+int hm2_led_parse_md(hostmot2_t *hm2, int md_index);
+void hm2_led_write(hostmot2_t *hm2);
+
 // 
 // the raw interface lets you peek and poke the hostmot2 instance from HAL
 //
diff --git a/src/hal/drivers/mesa-hostmot2/led.c b/src/hal/drivers/mesa-hostmot2/led.c
new file mode 100755
index 0000000..c69ce57
--- /dev/null
+++ b/src/hal/drivers/mesa-hostmot2/led.c
@@ -0,0 +1,171 @@
+
+//
+//    Copyright (C) 2010 Andy Pugh
+
+//    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; either version 2 of the License, or
+//    (at your option) any later version.
+//
+//    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
+//
+
+// Onboard LED driver for the Mesa FPGA cards
+
+
+#include <linux/slab.h>
+
+#include "rtapi.h"
+#include "rtapi_app.h"
+#include "rtapi_string.h"
+#include "rtapi_math.h"
+
+#include "hal.h"
+
+#include "hal/drivers/mesa-hostmot2/hostmot2.h"
+
+int hm2_led_parse_md(hostmot2_t *hm2, int md_index) {
+
+    hm2_module_descriptor_t *md = &hm2->md[md_index];
+    int r;
+	
+	
+    // 
+    // some standard sanity checks
+    //
+	
+    if (!hm2_md_is_consistent_or_complain(hm2, md_index, 0, 1, 4, 0x0000)) {
+        HM2_ERR("inconsistent Module Descriptor!\n");
+        return -EINVAL;
+    }
+	
+    if (md->instances != 1) {
+        HM2_ERR(
+				"There should be one and only one instance of an LED, not loading driver\n");
+        return -EINVAL;
+    }
+
+	
+    // 
+    // looks good, start initializing
+    // 
+	
+	
+    // allocate the module-global HAL shared memory
+    hm2->led = (hm2_led_t *)hal_malloc(sizeof(hm2_led_t));
+    if (hm2->led == NULL) {
+        HM2_ERR("out of memory!\n");
+        r = -ENOMEM;
+        goto fail0;
+    }
+	hm2->led->led_reg = (u32 *)kmalloc( sizeof(u32), GFP_KERNEL);
+    if (hm2->led->led_reg == NULL) {
+        HM2_ERR("out of memory!\n");
+        r = -ENOMEM;
+        goto fail0;
+    }
+
+    hm2->led->led_addr = md->base_address;
+	
+    // export to HAL
+    // FIXME: r hides the r in enclosing function, and it returns the wrong thing
+    {
+        int r;
+        char name[HAL_NAME_LEN + 2];
+		
+		rtapi_snprintf(name, HAL_NAME_LEN, "%s.led.CR1", hm2->llio->name);
+		r = hal_pin_bit_new(name, HAL_IN, &(hm2->led->hal.pin.cr1), hm2->llio->comp_id);
+		if (r < 0) {
+			HM2_ERR("error adding pin '%s', aborting\n", name);
+			goto fail1;
+		}
+		
+		rtapi_snprintf(name, HAL_NAME_LEN, "%s.led.CR2", hm2->llio->name);
+		r = hal_pin_bit_new(name, HAL_IN, &(hm2->led->hal.pin.cr2), hm2->llio->comp_id);
+		if (r < 0) {
+			HM2_ERR("error adding pin '%s', aborting\n", name);
+			goto fail1;
+		}
+		
+		rtapi_snprintf(name, HAL_NAME_LEN, "%s.led.CR3", hm2->llio->name);
+		r = hal_pin_bit_new(name, HAL_IN, &(hm2->led->hal.pin.cr3), hm2->llio->comp_id);
+		if (r < 0) {
+			HM2_ERR("error adding pin '%s', aborting\n", name);
+			goto fail1;
+		}
+		
+		rtapi_snprintf(name, HAL_NAME_LEN, "%s.led.CR4", hm2->llio->name);
+		r = hal_pin_bit_new(name, HAL_IN, &(hm2->led->hal.pin.cr4), hm2->llio->comp_id);
+		if (r < 0) {
+			HM2_ERR("error adding pin '%s', aborting\n", name);
+			goto fail1;
+		}
+		
+		rtapi_snprintf(name, HAL_NAME_LEN, "%s.led.CR5", hm2->llio->name);
+		r = hal_pin_bit_new(name, HAL_IN, &(hm2->led->hal.pin.cr5), hm2->llio->comp_id);
+		if (r < 0) {
+			HM2_ERR("error adding pin '%s', aborting\n", name);
+			goto fail1;
+		}
+		
+		rtapi_snprintf(name, HAL_NAME_LEN, "%s.led.CR6", hm2->llio->name);
+		r = hal_pin_bit_new(name, HAL_IN, &(hm2->led->hal.pin.cr6), hm2->llio->comp_id);
+		if (r < 0) {
+			HM2_ERR("error adding pin '%s', aborting\n", name);
+			goto fail1;
+		}
+		
+		rtapi_snprintf(name, HAL_NAME_LEN, "%s.led.CR7", hm2->llio->name);
+		r = hal_pin_bit_new(name, HAL_IN, &(hm2->led->hal.pin.cr7), hm2->llio->comp_id);
+		if (r < 0) {
+			HM2_ERR("error adding pin '%s', aborting\n", name);
+			goto fail1;
+		}
+		
+		rtapi_snprintf(name, HAL_NAME_LEN, "%s.led.CR8", hm2->llio->name);
+		r = hal_pin_bit_new(name, HAL_IN, &(hm2->led->hal.pin.cr8), hm2->llio->comp_id);
+		if (r < 0) {
+			HM2_ERR("error adding pin '%s', aborting\n", name);
+			goto fail1;
+		}
+
+    }
+	
+    return 1;
+	
+fail1:
+	
+	kfree(hm2->led->led_reg);
+	
+fail0:
+    return r;
+	
+}
+
+void hm2_led_write(hostmot2_t *hm2) {
+	u32 regval;
+	regval = (
+			   (*hm2->led->hal.pin.cr1 << 31)
+			 + (*hm2->led->hal.pin.cr2 << 30)
+			 + (*hm2->led->hal.pin.cr3 << 29)
+			 + (*hm2->led->hal.pin.cr4 << 28)
+			 + (*hm2->led->hal.pin.cr5 << 27)
+			 + (*hm2->led->hal.pin.cr6 << 26)
+			 + (*hm2->led->hal.pin.cr7 << 25)
+			 + (*hm2->led->hal.pin.cr8 << 24)
+			  );
+	if (regval != hm2->led->written_byte) {
+		*hm2->led->led_reg = regval;
+		hm2->led->written_byte = regval;
+		hm2->llio->write(hm2->llio, hm2->led->led_addr, hm2->led->led_reg, sizeof(u32));
+	}
+}
+
+
