summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/keyboard.c24
-rw-r--r--common/lightbar.c302
-rw-r--r--include/lightbar.h10
3 files changed, 262 insertions, 74 deletions
diff --git a/common/keyboard.c b/common/keyboard.c
index 183cae329b..56fc8fd8c3 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -10,6 +10,7 @@
#include "console.h"
#include "keyboard.h"
#include "i8042.h"
+#include "lightbar.h"
#include "lpc.h"
#include "lpc_commands.h"
#include "registers.h"
@@ -44,6 +45,7 @@ static uint8_t controller_ram[0x20] = {
/* 0x01 - 0x1f are controller RAM */
};
static int power_button_pressed = 0;
+static void keyboard_special(uint16_t k);
/*
* Scancode settings
@@ -145,6 +147,9 @@ static enum ec_error_list matrix_callback(
return EC_ERROR_INVAL;
}
+ if (pressed)
+ keyboard_special(scancode_set1[row][col]);
+
*len = 0;
code_set = acting_code_set(code_set);
@@ -601,6 +606,25 @@ int handle_keyboard_command(uint8_t command, uint8_t *output) {
return out_len;
}
+/* U U D D L R L R b a */
+static void keyboard_special(uint16_t k)
+{
+ static uint8_t s = 0;
+ static const uint16_t a[] = {0xe048, 0xe048, 0xe050, 0xe050, 0xe04b,
+ 0xe04d, 0xe04b, 0xe04d, 0x0030, 0x001e};
+ if (k == a[s])
+ s++;
+ else if (k != 0xe048)
+ s = 0;
+ else if (s != 2)
+ s = 1;
+ if (s == ARRAY_SIZE(a)) {
+ s = 0;
+#ifdef CONFIG_TASK_LIGHTBAR
+ lightbar_sequence(LIGHTBAR_KONAMI);
+#endif
+ }
+}
void keyboard_set_power_button(int pressed)
{
diff --git a/common/lightbar.c b/common/lightbar.c
index 965c4f8261..f2e95e3a74 100644
--- a/common/lightbar.c
+++ b/common/lightbar.c
@@ -53,7 +53,7 @@ static inline uint8_t controller_read(int ctrl_num, uint8_t reg)
#define MAX_GREEN 0x38
#define MAX_BLUE 0x67
-/* How many LEDs do we have? Right now, only four. */
+/* How many LEDs do we have? */
#define NUM_LEDS 4
/* How we'd like to see the driver chips initialized. The controllers have some
@@ -119,6 +119,22 @@ static inline uint8_t scale(int val, int max)
return scale_abs((val * brightness)/255, max);
}
+
+/* Helper function. */
+static void setrgb(int led, int red, int green, int blue)
+{
+ int ctrl, bank;
+ current[led][0] = red;
+ current[led][1] = green;
+ current[led][2] = blue;
+ ctrl = led_to_ctrl[led];
+ bank = led_to_isc[led];
+ controller_write(ctrl, bank, scale(blue, MAX_BLUE));
+ controller_write(ctrl, bank+1, scale(red, MAX_RED));
+ controller_write(ctrl, bank+2, scale(green, MAX_GREEN));
+}
+
+
/******************************************************************************/
/* Basic LED control functions. */
/******************************************************************************/
@@ -139,18 +155,17 @@ static void lightbar_on(void)
controller_write(1, 0x01, 0x20);
}
-/* LEDs are numbered 0-3, RGB values should be in 0-255. */
-static void lightbar_setcolor(int led, int red, int green, int blue)
+
+/* LEDs are numbered 0-3, RGB values should be in 0-255.
+ * If you specify too large an LED, it sets them all. */
+static void lightbar_setrgb(int led, int red, int green, int blue)
{
- int ctrl, bank;
- current[led][0] = red;
- current[led][1] = green;
- current[led][2] = blue;
- ctrl = led_to_ctrl[led];
- bank = led_to_isc[led];
- controller_write(ctrl, bank, scale(blue, MAX_BLUE));
- controller_write(ctrl, bank+1, scale(red, MAX_RED));
- controller_write(ctrl, bank+2, scale(green, MAX_GREEN));
+ int i;
+ if (led >= NUM_LEDS)
+ for (i = 0; i < NUM_LEDS; i++)
+ setrgb(i, red, green, blue);
+ else
+ setrgb(led, red, green, blue);
}
static inline void lightbar_brightness(int newval)
@@ -159,7 +174,7 @@ static inline void lightbar_brightness(int newval)
uart_printf("%s[(%d)]\n", __func__, newval);
brightness = newval;
for (i = 0; i < NUM_LEDS; i++)
- lightbar_setcolor(i, current[i][0],
+ lightbar_setrgb(i, current[i][0],
current[i][1], current[i][2]);
}
@@ -198,7 +213,7 @@ static uint32_t sequence_s5(void)
/* For now, do something to indicate S5. We might see it. */
lightbar_on();
for (i = 0; i < NUM_LEDS; i++)
- lightbar_setcolor(i, 255, 0, 0);
+ lightbar_setrgb(i, 255, 0, 0);
/* The lightbar loses power in S5, so just wait forever. */
WAIT_OR_RET(-1);
@@ -221,7 +236,7 @@ static uint32_t sequence_s5s3(void)
* We might see it. */
lightbar_on();
for (i = 0; i < NUM_LEDS; i++)
- lightbar_setcolor(i, 255, 255, 255);
+ lightbar_setrgb(i, 255, 255, 255);
WAIT_OR_RET(500000);
return 0;
@@ -240,9 +255,9 @@ static uint32_t sequence_s0(void)
l = l % NUM_LEDS;
n = n % 5;
if (n == 4)
- lightbar_setcolor(l, 0, 0, 0);
+ lightbar_setrgb(l, 0, 0, 0);
else
- lightbar_setcolor(l, testy[n].r,
+ lightbar_setrgb(l, testy[n].r,
testy[n].g, testy[n].b);
l++;
n++;
@@ -257,18 +272,18 @@ static uint32_t sequence_s0s3(void)
{
uart_printf("[%s()]\n", __func__);
lightbar_on();
- lightbar_setcolor(0, 0, 0, 255);
- lightbar_setcolor(1, 255, 0, 0);
- lightbar_setcolor(2, 255, 255, 0);
- lightbar_setcolor(3, 0, 255, 0);
+ lightbar_setrgb(0, 0, 0, 255);
+ lightbar_setrgb(1, 255, 0, 0);
+ lightbar_setrgb(2, 255, 255, 0);
+ lightbar_setrgb(3, 0, 255, 0);
WAIT_OR_RET(200000);
- lightbar_setcolor(0, 0, 0, 0);
+ lightbar_setrgb(0, 0, 0, 0);
WAIT_OR_RET(200000);
- lightbar_setcolor(1, 0, 0, 0);
+ lightbar_setrgb(1, 0, 0, 0);
WAIT_OR_RET(200000);
- lightbar_setcolor(2, 0, 0, 0);
+ lightbar_setrgb(2, 0, 0, 0);
WAIT_OR_RET(200000);
- lightbar_setcolor(3, 0, 0, 0);
+ lightbar_setrgb(3, 0, 0, 0);
return 0;
}
@@ -279,18 +294,18 @@ static uint32_t sequence_s3(void)
uart_printf("[%s()]\n", __func__);
lightbar_off();
lightbar_init_vals();
- lightbar_setcolor(0, 0, 0, 0);
- lightbar_setcolor(1, 0, 0, 0);
- lightbar_setcolor(2, 0, 0, 0);
- lightbar_setcolor(3, 0, 0, 0);
+ lightbar_setrgb(0, 0, 0, 0);
+ lightbar_setrgb(1, 0, 0, 0);
+ lightbar_setrgb(2, 0, 0, 0);
+ lightbar_setrgb(3, 0, 0, 0);
while (1) {
WAIT_OR_RET(3000000);
lightbar_on();
i = i % NUM_LEDS;
/* FIXME: indicate battery level? */
- lightbar_setcolor(i, testy[i].r, testy[i].g, testy[i].b);
+ lightbar_setrgb(i, testy[i].r, testy[i].g, testy[i].b);
WAIT_OR_RET(100000);
- lightbar_setcolor(i, 0, 0, 0);
+ lightbar_setrgb(i, 0, 0, 0);
i++;
lightbar_off();
}
@@ -304,13 +319,13 @@ static uint32_t sequence_s3s0(void)
uart_printf("[%s()]\n", __func__);
lightbar_init_vals();
lightbar_on();
- lightbar_setcolor(0, 0, 0, 255);
+ lightbar_setrgb(0, 0, 0, 255);
WAIT_OR_RET(200000);
- lightbar_setcolor(1, 255, 0, 0);
+ lightbar_setrgb(1, 255, 0, 0);
WAIT_OR_RET(200000);
- lightbar_setcolor(2, 255, 255, 0);
+ lightbar_setrgb(2, 255, 255, 0);
WAIT_OR_RET(200000);
- lightbar_setcolor(3, 0, 255, 0);
+ lightbar_setrgb(3, 0, 255, 0);
WAIT_OR_RET(200000);
return 0;
}
@@ -326,7 +341,7 @@ static uint32_t sequence_s3s5(void)
* We might see it. */
lightbar_on();
for (i = 0; i < NUM_LEDS; i++)
- lightbar_setcolor(i, 0, 0, 255);
+ lightbar_setrgb(i, 0, 0, 255);
WAIT_OR_RET(500000);
return 0;
@@ -349,7 +364,7 @@ static uint32_t sequence_test(void)
r = testy[i].r ? k : 0;
g = testy[i].g ? k : 0;
b = testy[i].b ? k : 0;
- lightbar_setcolor(j, r, g, b);
+ lightbar_setrgb(j, r, g, b);
}
WAIT_OR_RET(10000);
}
@@ -358,7 +373,7 @@ static uint32_t sequence_test(void)
r = testy[i].r ? k : 0;
g = testy[i].g ? k : 0;
b = testy[i].b ? k : 0;
- lightbar_setcolor(j, r, g, b);
+ lightbar_setrgb(j, r, g, b);
}
WAIT_OR_RET(10000);
}
@@ -373,38 +388,28 @@ static uint32_t sequence_test(void)
static uint32_t sequence_pulse(void)
{
uint32_t msg;
- int r, g, b;
+ int r = scale(255, MAX_RED);
+ int g = scale(255, MAX_BLUE);
+ int b = scale(255, MAX_GREEN);
+ struct initdata_s pulse_vals[] = {
+ {0x11, 0xce},
+ {0x12, 0x67},
+ {0x13, 0xef},
+ {0x15, b},
+ {0x16, r},
+ {0x17, g},
+ {0x18, b},
+ {0x19, r},
+ {0x1a, g},
+ };
uart_printf("[%s()]\n", __func__);
- r = scale(255, MAX_RED);
- g = scale(255, MAX_BLUE);
- b = scale(255, MAX_GREEN);
-
lightbar_init_vals();
lightbar_on();
- controller_write(0, 0x11, 0xce);
- controller_write(0, 0x12, 0x67);
- controller_write(0, 0x13, 0xef);
-
- controller_write(0, 0x15, b);
- controller_write(0, 0x16, r);
- controller_write(0, 0x17, g);
- controller_write(0, 0x18, b);
- controller_write(0, 0x19, r);
- controller_write(0, 0x1a, g);
-
- controller_write(1, 0x11, 0xce);
- controller_write(1, 0x12, 0x67);
- controller_write(1, 0x13, 0xcd);
-
- controller_write(1, 0x15, b);
- controller_write(1, 0x16, r);
- controller_write(1, 0x17, g);
- controller_write(1, 0x18, b);
- controller_write(1, 0x19, r);
- controller_write(1, 0x1a, g);
+ set_from_array(pulse_vals, ARRAY_SIZE(pulse_vals));
+ controller_write(1, 0x13, 0xcd); /* this one's different */
/* Not using WAIT_OR_RET() here, because we want to clean up when we're
* done. The only way out is to get a message. */
@@ -413,13 +418,155 @@ static uint32_t sequence_pulse(void)
return TASK_EVENT_CUSTOM(msg);
}
+
+
+/* The host CPU (or someone) is going to poke at the lightbar directly, so we
+ * don't want the EC messing with it. We'll just sit here and ignore all
+ * other messages until we're told to continue. */
+static uint32_t sequence_ec_stop(void)
+{
+ uint32_t msg;
+
+ uart_printf("[%s()]\n", __func__);
+
+ do {
+ msg = TASK_EVENT_CUSTOM(task_wait_event(-1));
+ uart_printf("[%s - got msg %x]\n", __func__, msg);
+ } while (msg != LIGHTBAR_EC_RUN);
+ /* FIXME: What should we do if the host shuts down? */
+
+ uart_printf("[%s() - leaving]\n", __func__);
+
+ return 0;
+}
+
+/* We shouldn't come here, but if we do it shouldn't hurt anything */
+static uint32_t sequence_error(void)
+{
+ uart_printf("[%s()]\n", __func__);
+
+ lightbar_init_vals();
+ lightbar_on();
+
+ lightbar_setrgb(0, 255, 255, 255);
+ lightbar_setrgb(1, 255, 0, 255);
+ lightbar_setrgb(2, 0, 255, 255);
+ lightbar_setrgb(3, 255, 255, 255);
+
+ WAIT_OR_RET(10000000);
+
+ return 0;
+}
+
+
+static const struct {
+ uint8_t led;
+ uint8_t r, g, b;
+ unsigned int delay;
+} konami[] = {
+
+ {1, 0xff, 0xff, 0x00, 0},
+ {2, 0xff, 0xff, 0x00, 100000},
+ {1, 0x00, 0x00, 0x00, 0},
+ {2, 0x00, 0x00, 0x00, 100000},
+
+ {1, 0xff, 0xff, 0x00, 0},
+ {2, 0xff, 0xff, 0x00, 100000},
+ {1, 0x00, 0x00, 0x00, 0},
+ {2, 0x00, 0x00, 0x00, 100000},
+
+ {0, 0x00, 0x00, 0xff, 0},
+ {3, 0x00, 0x00, 0xff, 100000},
+ {0, 0x00, 0x00, 0x00, 0},
+ {3, 0x00, 0x00, 0x00, 100000},
+
+ {0, 0x00, 0x00, 0xff, 0},
+ {3, 0x00, 0x00, 0xff, 100000},
+ {0, 0x00, 0x00, 0x00, 0},
+ {3, 0x00, 0x00, 0x00, 100000},
+
+ {0, 0xff, 0x00, 0x00, 0},
+ {1, 0xff, 0x00, 0x00, 100000},
+ {0, 0x00, 0x00, 0x00, 0},
+ {1, 0x00, 0x00, 0x00, 100000},
+
+ {2, 0x00, 0xff, 0x00, 0},
+ {3, 0x00, 0xff, 0x00, 100000},
+ {2, 0x00, 0x00, 0x00, 0},
+ {3, 0x00, 0x00, 0x00, 100000},
+
+ {0, 0xff, 0x00, 0x00, 0},
+ {1, 0xff, 0x00, 0x00, 100000},
+ {0, 0x00, 0x00, 0x00, 0},
+ {1, 0x00, 0x00, 0x00, 100000},
+
+ {2, 0x00, 0xff, 0x00, 0},
+ {3, 0x00, 0xff, 0x00, 100000},
+ {2, 0x00, 0x00, 0x00, 0},
+ {3, 0x00, 0x00, 0x00, 100000},
+
+ {0, 0x00, 0xff, 0xff, 0},
+ {2, 0x00, 0xff, 0xff, 100000},
+ {0, 0x00, 0x00, 0x00, 0},
+ {2, 0x00, 0x00, 0x00, 150000},
+
+ {1, 0xff, 0x00, 0xff, 0},
+ {3, 0xff, 0x00, 0xff, 100000},
+ {1, 0x00, 0x00, 0x00, 0},
+ {3, 0x00, 0x00, 0x00, 250000},
+
+ {4, 0xff, 0xff, 0xff, 100000},
+ {4, 0x00, 0x00, 0x00, 100000},
+
+ {4, 0xff, 0xff, 0xff, 100000},
+ {4, 0x00, 0x00, 0x00, 100000},
+
+ {4, 0xff, 0xff, 0xff, 100000},
+ {4, 0x00, 0x00, 0x00, 100000},
+
+ {4, 0xff, 0xff, 0xff, 100000},
+ {4, 0x00, 0x00, 0x00, 100000},
+
+ {4, 0xff, 0xff, 0xff, 100000},
+ {4, 0x00, 0x00, 0x00, 100000},
+
+ {4, 0xff, 0xff, 0xff, 100000},
+ {4, 0x00, 0x00, 0x00, 100000},
+
+};
+
+static uint32_t sequence_konami(void)
+{
+ int i;
+ int tmp;
+
+ uart_printf("[%s()]\n", __func__);
+ lightbar_init_vals();
+ lightbar_on();
+
+ tmp = brightness;
+ brightness = 255;
+
+ for (i = 0; i < ARRAY_SIZE(konami); i++) {
+ lightbar_setrgb(konami[i].led,
+ konami[i].r, konami[i].g, konami[i].b);
+ if (konami[i].delay)
+ usleep(konami[i].delay);
+ }
+
+ brightness = tmp;
+
+ return 0;
+}
+
/****************************************************************************/
-/* Lightbar task. It just cycles between various pretty patterns. */
+/* The main lightbar task. It just cycles between various pretty patterns. */
/****************************************************************************/
-/* IMPORTANT: The order here must match the enum lightbar_sequence values. */
+/* IMPORTANT: The order here must match the enum lightbar_sequence order.
+ * FIXME: Use some preprocessor tricks to ensure that's always true. */
static uint32_t (*sequence[])(void) = {
- 0,
+ sequence_error, /* idle - not used */
sequence_s5,
sequence_s3,
sequence_s0,
@@ -427,8 +574,11 @@ static uint32_t (*sequence[])(void) = {
sequence_s3s0,
sequence_s0s3,
sequence_s3s5,
- sequence_test,
+ sequence_ec_stop,
+ sequence_error, /* unexpected ec run */
sequence_pulse,
+ sequence_test,
+ sequence_konami,
};
void lightbar_task(void)
@@ -469,6 +619,10 @@ void lightbar_task(void)
state = LIGHTBAR_S5;
break;
case LIGHTBAR_TEST:
+ case LIGHTBAR_EC_STOP:
+ case LIGHTBAR_EC_RUN:
+ case LIGHTBAR_NULL:
+ case LIGHTBAR_KONAMI:
state = previous_state;
default:
break;
@@ -478,7 +632,7 @@ void lightbar_task(void)
}
-/* Request a preset sequence from the lightbar task. */
+/* Function to request a preset sequence from the lightbar task. */
void lightbar_sequence(enum lightbar_sequence num)
{
uart_printf("[%s(%d)]\n", __func__, num);
@@ -516,8 +670,8 @@ DECLARE_HOST_COMMAND(EC_LPC_COMMAND_LIGHTBAR_TEST, lpc_cmd_test);
static int help(const char *cmd)
{
uart_printf("Usage: %s\n", cmd);
- uart_printf(" %s reset\n", cmd);
uart_printf(" %s off\n", cmd);
+ uart_printf(" %s init\n", cmd);
uart_printf(" %s on\n", cmd);
uart_printf(" %s msg NUM\n", cmd);
uart_printf(" %s brightness NUM\n", cmd);
@@ -543,6 +697,8 @@ static void dump_regs(void)
static int command_lightbar(int argc, char **argv)
{
+ int i;
+
if (1 == argc) { /* no args = dump 'em all */
dump_regs();
return EC_SUCCESS;
@@ -592,7 +748,11 @@ static int command_lightbar(int argc, char **argv)
int red = strtoi(argv[2], &e, 16);
int green = strtoi(argv[3], &e, 16);
int blue = strtoi(argv[4], &e, 16);
- lightbar_setcolor(led, red, green, blue);
+ if (led >= NUM_LEDS)
+ for (i = 0; i < NUM_LEDS; i++)
+ lightbar_setrgb(i, red, green, blue);
+ else
+ lightbar_setrgb(led, red, green, blue);
return EC_SUCCESS;
}
diff --git a/include/lightbar.h b/include/lightbar.h
index 37f8980a34..58e4053765 100644
--- a/include/lightbar.h
+++ b/include/lightbar.h
@@ -19,9 +19,13 @@ enum lightbar_sequence {
LIGHTBAR_S3S0, /* 5 */
LIGHTBAR_S0S3, /* 6 */
LIGHTBAR_S3S5, /* 7 */
- /* extra patterns */
- LIGHTBAR_TEST, /* 8 */
- LIGHTBAR_PULSE, /* 9 */
+ /* Who's in charge? */
+ LIGHTBAR_EC_STOP, /* 8 - EC ignore LEDs */
+ LIGHTBAR_EC_RUN, /* 9 - EC drive LEDs */
+ /* Extra patterns */
+ LIGHTBAR_PULSE, /* a */
+ LIGHTBAR_TEST, /* b */
+ LIGHTBAR_KONAMI, /* c */
/* that's all */
LIGHTBAR_NUM_SEQUENCES
};