Merge "Tweaks to lightbar code, detect konami sequence"

This commit is contained in:
Gerrit
2012-04-19 14:03:42 -07:00
committed by Gerrit Code Review
3 changed files with 262 additions and 74 deletions

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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
};