mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-28 02:35:28 +00:00
Most systems don't have a lightbar. Those that do need a way to detect that one exists. That's easily done by just sending a EC_CMD_LIGHTBAR_CMD command to the EC and checking the result. If the response is EC_RES_INVALID_COMMAND, there isn't a lightbar. But what .cmd value should we use in struct ec_params_lightbar? Future lightbar implementations (if any), could remove existing functions or add new ones, so there isn't a safe choice. This change adds a LIGHTBAR_CMD_VERSION operation to determine if any new implementation exists. Future systems should return some useful information in response to this command. Existing systems will return EC_RES_INVALID_PARAM, which is enough to distinguish them. BUG=chromium:239205 BRANCH=none TEST=manual make BOARD=link make BOARD=link runtests There are no user-visible changes in functionality to anything. Change-Id: Ibe37f74a4dcbf68dd6bfd1963530aec907e67534 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/167549 Reviewed-by: Randall Spangler <rspangler@chromium.org>
199 lines
4.3 KiB
C
199 lines
4.3 KiB
C
/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/io.h>
|
|
#include <unistd.h>
|
|
|
|
#include "comm-host.h"
|
|
#include "compile_time_macros.h"
|
|
#include "lightbar.h"
|
|
#include "lock/gec_lock.h"
|
|
|
|
#define LB_SIZES(SUBCMD) { \
|
|
sizeof(((struct ec_params_lightbar *)0)->SUBCMD) \
|
|
+ sizeof(((struct ec_params_lightbar *)0)->cmd), \
|
|
sizeof(((struct ec_response_lightbar *)0)->SUBCMD) }
|
|
static const struct {
|
|
uint8_t insize;
|
|
uint8_t outsize;
|
|
} lb_command_paramcount[] = {
|
|
LB_SIZES(dump),
|
|
LB_SIZES(off),
|
|
LB_SIZES(on),
|
|
LB_SIZES(init),
|
|
LB_SIZES(brightness),
|
|
LB_SIZES(seq),
|
|
LB_SIZES(reg),
|
|
LB_SIZES(rgb),
|
|
LB_SIZES(get_seq),
|
|
LB_SIZES(demo),
|
|
LB_SIZES(get_params),
|
|
LB_SIZES(set_params),
|
|
LB_SIZES(version)
|
|
};
|
|
#undef LB_SIZES
|
|
|
|
|
|
#define GEC_LOCK_TIMEOUT_SECS 30 /* 30 secs */
|
|
#define LOCK do { \
|
|
if (acquire_gec_lock(GEC_LOCK_TIMEOUT_SECS) < 0) { \
|
|
fprintf(stderr, "Could not acquire GEC lock.\n"); \
|
|
exit(1); \
|
|
} } while (0)
|
|
|
|
#define UNLOCK do { release_gec_lock(); } while (0)
|
|
|
|
|
|
static void lb_cmd_noargs(enum lightbar_command cmd)
|
|
{
|
|
struct ec_params_lightbar param;
|
|
struct ec_response_lightbar resp;
|
|
param.cmd = cmd;
|
|
ec_command(EC_CMD_LIGHTBAR_CMD, 0,
|
|
¶m, lb_command_paramcount[param.cmd].insize,
|
|
&resp, lb_command_paramcount[param.cmd].outsize);
|
|
}
|
|
|
|
inline void lightbar_off(void)
|
|
{
|
|
lb_cmd_noargs(LIGHTBAR_CMD_OFF);
|
|
}
|
|
|
|
inline void lightbar_on(void)
|
|
{
|
|
lb_cmd_noargs(LIGHTBAR_CMD_ON);
|
|
}
|
|
|
|
inline void lightbar_init_vals(void)
|
|
{
|
|
lb_cmd_noargs(LIGHTBAR_CMD_INIT);
|
|
}
|
|
|
|
void lightbar_brightness(int newval)
|
|
{
|
|
struct ec_params_lightbar param;
|
|
struct ec_response_lightbar resp;
|
|
param.cmd = LIGHTBAR_CMD_BRIGHTNESS;
|
|
param.brightness.num = newval;
|
|
ec_command(EC_CMD_LIGHTBAR_CMD, 0,
|
|
¶m, lb_command_paramcount[param.cmd].insize,
|
|
&resp, lb_command_paramcount[param.cmd].outsize);
|
|
}
|
|
|
|
void lightbar_sequence(enum lightbar_sequence num)
|
|
{
|
|
struct ec_params_lightbar param;
|
|
struct ec_response_lightbar resp;
|
|
param.cmd = LIGHTBAR_CMD_SEQ;
|
|
param.seq.num = num;
|
|
ec_command(EC_CMD_LIGHTBAR_CMD, 0,
|
|
¶m, lb_command_paramcount[param.cmd].insize,
|
|
&resp, lb_command_paramcount[param.cmd].outsize);
|
|
}
|
|
|
|
void lightbar_reg(uint8_t ctrl, uint8_t reg, uint8_t val)
|
|
{
|
|
struct ec_params_lightbar param;
|
|
struct ec_response_lightbar resp;
|
|
param.cmd = LIGHTBAR_CMD_REG;
|
|
param.reg.ctrl = ctrl;
|
|
param.reg.reg = reg;
|
|
param.reg.value = val;
|
|
ec_command(EC_CMD_LIGHTBAR_CMD, 0,
|
|
¶m, lb_command_paramcount[param.cmd].insize,
|
|
&resp, lb_command_paramcount[param.cmd].outsize);
|
|
}
|
|
|
|
void lightbar_rgb(int led, int red, int green, int blue)
|
|
{
|
|
struct ec_params_lightbar param;
|
|
struct ec_response_lightbar resp;
|
|
param.cmd = LIGHTBAR_CMD_RGB;
|
|
param.rgb.led = led;
|
|
param.rgb.red = red;
|
|
param.rgb.green = green;
|
|
param.rgb.blue = blue;
|
|
ec_command(EC_CMD_LIGHTBAR_CMD, 0,
|
|
¶m, lb_command_paramcount[param.cmd].insize,
|
|
&resp, lb_command_paramcount[param.cmd].outsize);
|
|
}
|
|
|
|
void wait_for_ec_to_stop(void)
|
|
{
|
|
int r;
|
|
struct ec_params_lightbar param;
|
|
struct ec_response_lightbar resp;
|
|
int count = 0;
|
|
|
|
do {
|
|
usleep(100000);
|
|
param.cmd = LIGHTBAR_CMD_GET_SEQ;
|
|
r = ec_command(EC_CMD_LIGHTBAR_CMD, 0,
|
|
¶m,
|
|
lb_command_paramcount[param.cmd].insize,
|
|
&resp,
|
|
lb_command_paramcount[param.cmd].outsize);
|
|
if (count++ > 10) {
|
|
fprintf(stderr, "EC isn't responding\n");
|
|
UNLOCK;
|
|
exit(1);
|
|
}
|
|
} while (r < 0 && resp.get_seq.num != LIGHTBAR_STOP);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int i;
|
|
|
|
BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS);
|
|
|
|
LOCK;
|
|
|
|
if (comm_init() < 0) {
|
|
fprintf(stderr, "comm_init() failed\n");
|
|
UNLOCK;
|
|
return 2;
|
|
}
|
|
|
|
/* Tell the EC to let us drive. */
|
|
lightbar_sequence(LIGHTBAR_STOP);
|
|
|
|
/* Wait until it's listening (or die trying) */
|
|
wait_for_ec_to_stop();
|
|
|
|
/* Initialize it */
|
|
lightbar_off();
|
|
lightbar_init_vals();
|
|
lightbar_brightness(0xff);
|
|
lightbar_on();
|
|
|
|
UNLOCK;
|
|
|
|
/* Play a bit */
|
|
for (i = 0; i <= 255; i += 4) {
|
|
LOCK;
|
|
lightbar_rgb(4, 0, i, 0);
|
|
UNLOCK;
|
|
usleep(100000);
|
|
}
|
|
|
|
for (; i >= 0; i -= 4) {
|
|
LOCK;
|
|
lightbar_rgb(4, i, 0, 0);
|
|
UNLOCK;
|
|
usleep(100000);
|
|
}
|
|
|
|
/* Let the EC drive again */
|
|
LOCK;
|
|
lightbar_sequence(LIGHTBAR_RUN);
|
|
UNLOCK;
|
|
return 0;
|
|
}
|