diff --git a/blink1raw/Makefile b/blink1raw/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e3fddc560ab2b0f689dd87e49ef584c561705631
--- /dev/null
+++ b/blink1raw/Makefile
@@ -0,0 +1,8 @@
+
+
+CC=gcc
+
+blink1raw: 
+	$(CC) -o blink1raw blink1raw.c
+
+all: blink1raw
diff --git a/blink1raw/README.txt b/blink1raw/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a4c648f49bd5f504978e007bd3dea400d46fd543
--- /dev/null
+++ b/blink1raw/README.txt
@@ -0,0 +1,53 @@
+
+
+blink1raw -- use HIDRAW to talk to blink(1)
+--------------------------------------------
+2012 - Frederick Roeber 
+
+This tiny program is great for restricted environments like during machine installs
+
+
+Some sample command lines:
+% blink1 /dev/hidraw* % _ @1:255,0,0,1 @2:255,0,0,50 @3:255,100,0,1
+@4:255,100,0,50 +1
+
+Arguments, in order:
+ /dev/hidraw* -- this gets shell-expanded into a list of devices.
+       The program will open each in turn, check if it's a blink(1), and
+       if so, it becomes the new target.  If you have one such device,
+       this is an easy way of finding it.  If you have multiple, whichever
+       is last will be the device.
+
+ % -- clear all steps
+ @1: set step 1 to be "fade to red in 1 cs"  1/100 of a second is
+short, so it flips to red.
+ @2: set step 2 to be "fade to red in 50 cs" which, since it's
+already red, is "hold red for 50 cs"
+ @3: set step 3 to be "fade to yellow in 1 cs" i.e. flip to yellow
+ @4: set step 4 to be "fade to yellow in 50 cs" i.e. hold yellow for
+another half second.
+ +1 -- begin playing at step 1
+
+This is the pattern used when a machine need its key inserted.  (I
+haven't assigned others yet, but I'm imagining that every problem will
+have its own pattern, so I can tell at a glance what's going on.)
+
+
+% blink1 /dev/hidraw* =255,0,255,50
+
+This just sets the found device to be green.  It does this when the
+boot key has been detected and accepted.
+
+
+% blink1 /dev/hidraw* _ % @1:0,255,0,100 @2:0,0,0,100 @3:0,255,0,100
+@4:0,0,0,100 @5:0,255,0,100 @6:0,0,0,100 @7:0,0,0,1000 +1
+
+This throbs its green three times (100 cs, i.e. 1 second, per fade-up
+or -down), then holds black for 10 seconds.  This happens when the
+machine is happy and the key can be removed.  The driver script waits
+six seconds, then issues a
+
+% blink1 /dev/hidraw* _100 %
+
+which fades it off over 1 second, and clears the program.
+
diff --git a/blink1raw/blink1raw.c b/blink1raw/blink1raw.c
new file mode 100644
index 0000000000000000000000000000000000000000..07a40d4e307183f78b6922d7d7b0fd7d1ee0e15f
--- /dev/null
+++ b/blink1raw/blink1raw.c
@@ -0,0 +1,214 @@
+/* 
+ * blinkraw.c
+ *
+ * fgmr 2012-09-22
+ *
+ * playing with the hidraw interface to blink(1)
+ * 
+ * Thank you Alan Ott for
+ * http://lxr.free-electrons.com/source/samples/hidraw/hid-example.c
+ */
+
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/hidraw.h>
+
+#ifndef HIDIOCSFEATURE
+#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
+#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
+#endif /* HIDIOCSFEATURE */
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+static void
+usage(const char* hunh) {
+  if (NULL != hunh) {
+    fprintf(stderr, "Can't understand %s\n", hunh);
+  }
+
+  fprintf(stderr,
+          "Usage: blinkraw {arg, ...}\n"
+          "  /dev/whatever  -- open device\n"
+          "  ./whatever     -- open device\n"
+          "  =R,G,B,t       -- fade to color\n"
+          "  :R,G,B         -- set color (now)\n"
+          "  @step:R,G,B,t  -- set step\n"
+          "  +step          -- start playing at step\n"
+          "  -[step]        -- stop playing at step (default zero)\n"
+          "  %%              -- clear all steps\n"
+          "  _              -- turn off\n"
+          "  _t             -- fade off\n"
+          "\n"
+          "       step is on [0,15]\n",
+          "       R, G, B are on [0, 255]\n"
+          "       t is time in centiseconds\n"
+          "\n"
+          "    Arguments are applied in order.  A new device, which is\n"
+          "    a valid blink(1) device, will become the new target.\n"
+          "\n"
+          "    Example:\n"
+          "    # blinkraw /dev/hidraw* % =255,0,0,100\n"
+          );
+  exit(1);
+}
+
+static void
+color(int fd, char action, int R, int G, int B, int T, int step) {
+  char buf[16];
+  int rc;
+
+  if (-1 == fd) return;
+
+  memset(buf, 0, sizeof(buf));
+
+  if (R<0) R=0;
+  if (G<0) G=0;
+  if (B<0) B=0;
+  if (T<0) T=0;
+  if (step<0) step=0;
+
+  if (R>255) R=255;
+  if (G>255) G=255;
+  if (B>255) B=255;
+  if (T>65535) T=65535;
+  if (step>15) step=15;
+  
+  buf[0] = 1;
+  buf[1] = action;
+  buf[2] = R; /* R */
+  buf[3] = G; /* G */
+  buf[4] = B; /* B */
+  buf[5] = (T >>8);    /* time/cs high */
+  buf[6] = (T & 0xff); /* time/cs low */
+  buf[7] = step;
+  buf[8] = 0;
+
+  rc = ioctl(fd, HIDIOCSFEATURE(9), buf);
+  if (rc < 0) perror("HIDIOCSFEATURE");
+}
+
+static void
+play(int fd, char action, int play, int step) {
+  char buf[16];
+  int rc;
+
+  if (-1 == fd) return;
+
+  memset(buf, 0, sizeof(buf));
+
+  buf[0] = 1;
+  buf[1] = action;
+  buf[2] = play;
+  buf[3] = step;
+
+  rc = ioctl(fd, HIDIOCSFEATURE(9), buf);
+  if (rc < 0) perror("HIDIOCSFEATURE");
+}
+
+static int
+isblink1(int fd) {
+  int rc;
+  struct hidraw_devinfo info;
+  memset(&info, 0, sizeof(info));
+
+  rc = ioctl(fd, HIDIOCGRAWINFO, &info);
+  if (rc < 0) {
+    perror("HIDIOCGRAWINFO");
+    return 0;
+  }
+
+  if ((info.vendor == 0x27b8) && (info.product == 0x01ed)) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+int
+main(int argc, char *argv[]) {
+  int fd = -1;
+
+  if (argc < 2) usage(NULL);
+
+  while(++argv, --argc) {
+    int rc = -1;
+    int step = 0;
+    int R = 0;
+    int G = 0;
+    int B = 0;
+    int T = 0;
+    char buf[16];
+
+    memset(buf, 0, sizeof(buf));
+
+    switch(**argv) {
+    case '/': case '.':
+      rc = open(*argv, O_RDWR|O_NONBLOCK);
+      if (rc < 0) {
+        perror(*argv);
+        continue;
+      }
+
+      if (isblink1(rc)) {
+        if (fd >= 0) close(fd);
+        fd = rc;
+      }
+
+      break;
+    case '=':
+      rc = sscanf(*argv, "=%d,%d,%d,%d", &R, &G, &B, &T);
+      if (rc != 4) usage(*argv);
+      color(fd, 'c', R, G, B, T, 0);
+      break;
+    case ':':
+      rc = sscanf(*argv, ":%d,%d,%d", &R, &G, &B);
+      if (rc != 3) usage(*argv);
+      color(fd, 'n', R, G, B, 0, 0);
+      break;
+    case '@':
+      rc = sscanf(*argv, "@%d:%d,%d,%d,%d", &step, &R, &G, &B, &T);
+      if (rc != 5) usage(*argv);
+      if ((step < 0) || step > 15) usage(*argv);
+      color(fd, 'P', R, G, B, T, step);
+      break;
+    case '_':
+      rc = sscanf(*argv, "_%d", &T);
+      if (rc == 1) color(fd, 'c', 0, 0, 0, T, 0);
+      else color(fd, 'n', 0, 0, 0, 0, 0);
+      break;
+    case '+':
+      rc = sscanf(*argv, "+%d", &step);
+      if (rc != 1) usage(*argv);
+      if ((step < 0) || step > 15) usage(*argv);
+      play(fd, 'p', 1, step);
+      break;
+    case '-':
+      rc = sscanf(*argv, "-%d", &step);
+      if (rc != 1) step = 0;
+      if ((step < 0) || step > 15) step = 0;
+      play(fd, 'p', 0, step);
+      break;
+    case '%':
+      for(step = 0; step < 16; ++step) {
+        color(fd, 'P', 0, 0, 0, 0, step);
+      }
+      break;
+    default:
+      usage(*argv);
+    }
+  }
+
+  close(fd);
+  return 0;
+}