summaryrefslogtreecommitdiff
path: root/util/ectool.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/ectool.c')
-rw-r--r--util/ectool.c10964
1 files changed, 0 insertions, 10964 deletions
diff --git a/util/ectool.c b/util/ectool.c
deleted file mode 100644
index c4a3401d59..0000000000
--- a/util/ectool.c
+++ /dev/null
@@ -1,10964 +0,0 @@
-/* Copyright 2013 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 <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <signal.h>
-#include <stdbool.h>
-
-#include "battery.h"
-#include "comm-host.h"
-#include "chipset.h"
-#include "compile_time_macros.h"
-#include "crc.h"
-#include "cros_ec_dev.h"
-#include "ec_panicinfo.h"
-#include "ec_flash.h"
-#include "ec_version.h"
-#include "ectool.h"
-#include "i2c.h"
-#include "lightbar.h"
-#include "lock/gec_lock.h"
-#include "misc_util.h"
-#include "panic.h"
-#include "usb_pd.h"
-
-/* Maximum flash size (16 MB, conservative) */
-#define MAX_FLASH_SIZE 0x1000000
-
-/*
- * Calculate the expected response for a hello ec command.
- */
-#define HELLO_RESP(in_data) ((in_data) + 0x01020304)
-
-/* Command line options */
-enum {
- OPT_DEV = 1000,
- OPT_INTERFACE,
- OPT_NAME,
- OPT_ASCII,
- OPT_I2C_BUS,
-};
-
-static struct option long_opts[] = {
- {"dev", 1, 0, OPT_DEV},
- {"interface", 1, 0, OPT_INTERFACE},
- {"name", 1, 0, OPT_NAME},
- {"ascii", 0, 0, OPT_ASCII},
- {"i2c_bus", 1, 0, OPT_I2C_BUS},
- {NULL, 0, 0, 0}
-};
-
-#define GEC_LOCK_TIMEOUT_SECS 30 /* 30 secs */
-
-const char help_str[] =
- "Commands:\n"
- " adcread <channel>\n"
- " Read an ADC channel.\n"
- " addentropy [reset]\n"
- " Add entropy to device secret\n"
- " apreset\n"
- " Issue AP reset\n"
- " autofanctrl <on>\n"
- " Turn on automatic fan speed control.\n"
- " backlight <enabled>\n"
- " Enable/disable LCD backlight\n"
- " basestate [attach | detach | reset]\n"
- " Manually force base state to attached, detached or reset.\n"
- " battery\n"
- " Prints battery info\n"
- " batterycutoff [at-shutdown]\n"
- " Cut off battery output power\n"
- " batteryparam\n"
- " Read or write board-specific battery parameter\n"
- " boardversion\n"
- " Prints the board version\n"
- " button [vup|vdown|rec] <Delay-ms>\n"
- " Simulates button press.\n"
- " cbi\n"
- " Get/Set/Remove Cros Board Info\n"
- " chargecurrentlimit\n"
- " Set the maximum battery charging current\n"
- " chargecontrol\n"
- " Force the battery to stop charging or discharge\n"
- " chargeoverride\n"
- " Overrides charge port selection logic\n"
- " chargestate\n"
- " Handle commands related to charge state v2 (and later)\n"
- " chipinfo\n"
- " Prints chip info\n"
- " cmdversions <cmd>\n"
- " Prints supported version mask for a command number\n"
- " console\n"
- " Prints the last output to the EC debug console\n"
- " cec\n"
- " Read or write CEC messages and settings\n"
- " echash [CMDS]\n"
- " Various EC hash commands\n"
- " eventclear <mask>\n"
- " Clears EC host events flags where mask has bits set\n"
- " eventclearb <mask>\n"
- " Clears EC host events flags copy B where mask has bits set\n"
- " eventget\n"
- " Prints raw EC host event flags\n"
- " eventgetb\n"
- " Prints raw EC host event flags copy B\n"
- " eventgetscimask\n"
- " Prints SCI mask for EC host events\n"
- " eventgetsmimask\n"
- " Prints SMI mask for EC host events\n"
- " eventgetwakemask\n"
- " Prints wake mask for EC host events\n"
- " eventsetscimask <mask>\n"
- " Sets the SCI mask for EC host events\n"
- " eventsetsmimask <mask>\n"
- " Sets the SMI mask for EC host events\n"
- " eventsetwakemask <mask>\n"
- " Sets the wake mask for EC host events\n"
- " extpwrlimit\n"
- " Set the maximum external power limit\n"
- " fanduty <percent>\n"
- " Forces the fan PWM to a constant duty cycle\n"
- " flasherase <offset> <size>\n"
- " Erases EC flash\n"
- " flasheraseasync <offset> <size>\n"
- " Erases EC flash asynchronously\n"
- " flashinfo\n"
- " Prints information on the EC flash\n"
- " flashspiinfo\n"
- " Prints information on EC SPI flash, if present\n"
- " flashpd <dev_id> <port> <filename>\n"
- " Flash commands over PD\n"
- " flashprotect [now] [enable | disable]\n"
- " Prints or sets EC flash protection state\n"
- " flashread <offset> <size> <outfile>\n"
- " Reads from EC flash to a file\n"
- " flashwrite <offset> <infile>\n"
- " Writes to EC flash from a file\n"
- " forcelidopen <enable>\n"
- " Forces the lid switch to open position\n"
- " fpcontext\n"
- " Sets the fingerprint sensor context\n"
- " fpencstatus\n"
- " Prints status of Fingerprint sensor encryption engine\n"
- " fpframe\n"
- " Retrieve the finger image as a PGM image\n"
- " fpinfo\n"
- " Prints information about the Fingerprint sensor\n"
- " fpmode [mode... [capture_type]]\n"
- " Configure/Read the fingerprint sensor current mode\n"
- " mode: capture|deepsleep|fingerdown|fingerup|enroll|match|\n"
- " reset|reset_sensor|maintenance\n"
- " capture_type: vendor|pattern0|pattern1|qual|test_reset\n"
- " fpseed\n"
- " Sets the value of the TPM seed.\n"
- " fpstats\n"
- " Prints timing statisitcs relating to capture and matching\n"
- " fptemplate [<infile>|<index 0..2>]\n"
- " Add a template if <infile> is provided, else dump it\n"
- " gpioget <GPIO name>\n"
- " Get the value of GPIO signal\n"
- " gpioset <GPIO name>\n"
- " Set the value of GPIO signal\n"
- " hangdetect <flags> <event_msec> <reboot_msec> | stop | start\n"
- " Configure or start/stop the hang detect timer\n"
- " hello\n"
- " Checks for basic communication with EC\n"
- " hibdelay [sec]\n"
- " Set the delay before going into hibernation\n"
- " hostsleepstate\n"
- " Report host sleep state to the EC\n"
- " hostevent\n"
- " Get & set host event masks.\n"
- " i2cprotect <port> [status]\n"
- " Protect EC's I2C bus\n"
- " i2cread\n"
- " Read I2C bus\n"
- " i2cwrite\n"
- " Write I2C bus\n"
- " i2cxfer <port> <peripheral_addr> <read_count> [write bytes...]\n"
- " Perform I2C transfer on EC's I2C bus\n"
- " infopddev <port>\n"
- " Get info about USB type-C accessory attached to port\n"
- " inventory\n"
- " Return the list of supported features\n"
- " kbfactorytest\n"
- " Scan out keyboard if any pins are shorted\n"
- " kbid\n"
- " Get keyboard ID of supported keyboards\n"
- " kbinfo\n"
- " Dump keyboard matrix dimensions\n"
- " kbpress\n"
- " Simulate key press\n"
- " keyscan <beat_us> <filename>\n"
- " Test low-level key scanning\n"
- " led <name> <query | auto | off | <color> | <color>=<value>...>\n"
- " Set the color of an LED or query brightness range\n"
- " lightbar [CMDS]\n"
- " Various lightbar control commands\n"
- " mkbpget <buttons|switches>\n"
- " Get MKBP buttons/switches supported mask and current state\n"
- " mkbpwakemask <get|set> <event|hostevent> [mask]\n"
- " Get or Set the MKBP event wake mask, or host event wake mask\n"
- " motionsense [CMDS]\n"
- " Various motion sense control commands\n"
- " panicinfo\n"
- " Prints saved panic info\n"
- " pause_in_s5 [on|off]\n"
- " Whether or not the AP should pause in S5 on shutdown\n"
- " pchg [<port>]\n"
- " Get peripheral charge port count and status\n"
- " pdcontrol [suspend|resume|reset|disable|on]\n"
- " Controls the PD chip\n"
- " pdchipinfo <port>\n"
- " Get PD chip information\n"
- " pdlog\n"
- " Prints the PD event log entries\n"
- " pdwritelog <type> <port>\n"
- " Writes a PD event log of the given <type>\n"
- " pdgetmode <port>\n"
- " Get All USB-PD alternate SVIDs and modes on <port>\n"
- " pdsetmode <port> <svid> <opos>\n"
- " Set USB-PD alternate SVID and mode on <port>\n"
- " port80flood\n"
- " Rapidly write bytes to port 80\n"
- " port80read\n"
- " Print history of port 80 write\n"
- " powerinfo\n"
- " Prints power-related information\n"
- " protoinfo\n"
- " Prints EC host protocol information\n"
- " pse\n"
- " Get and set PoE PSE port power status\n"
- " pstoreinfo\n"
- " Prints information on the EC host persistent storage\n"
- " pstoreread <offset> <size> <outfile>\n"
- " Reads from EC host persistent storage to a file\n"
- " pstorewrite <offset> <infile>\n"
- " Writes to EC host persistent storage from a file\n"
- " pwmgetfanrpm [<index> | all]\n"
- " Prints current fan RPM\n"
- " pwmgetkblight\n"
- " Prints current keyboard backlight percent\n"
- " pwmgetnumfans\n"
- " Prints the number of fans present\n"
- " pwmgetduty\n"
- " Prints the current 16 bit duty cycle for given PWM\n"
- " pwmsetfanrpm <targetrpm>\n"
- " Set target fan RPM\n"
- " pwmsetkblight <percent>\n"
- " Set keyboard backlight in percent\n"
- " pwmsetduty\n"
- " Set 16 bit duty cycle of given PWM\n"
- " rand <num_bytes>\n"
- " generate <num_bytes> of random numbers\n"
- " readtest <patternoffset> <size>\n"
- " Reads a pattern from the EC via LPC\n"
- " reboot_ec <RO|RW|cold|hibernate|hibernate-clear-ap-off|disable-jump|cold-ap-off>"
- " [at-shutdown|switch-slot]\n"
- " Reboot EC to RO or RW\n"
- " reboot_ap_on_g3 [<delay>]\n"
- " Requests that the EC will automatically reboot the AP after a\n"
- " configurable number of seconds the next time we enter the G3\n"
- " power state.\n"
- " rollbackinfo\n"
- " Print rollback block information\n"
- " rtcget\n"
- " Print real-time clock\n"
- " rtcgetalarm\n"
- " Print # of seconds before real-time clock alarm goes off.\n"
- " rtcset <time>\n"
- " Set real-time clock\n"
- " rtcsetalarm <sec>\n"
- " Set real-time clock alarm to go off in <sec> seconds\n"
- " rwhashpd <dev_id> <HASH[0] ... <HASH[4]>\n"
- " Set entry in PD MCU's device rw_hash table.\n"
- " rwsig <info|dump|action|status> ...\n"
- " info: get all info about rwsig\n"
- " dump: show individual rwsig field\n"
- " action: Control the behavior of RWSIG task.\n"
- " status: Run RW signature verification and get status.\n{"
- " rwsigaction (DEPRECATED; use \"rwsig action\")\n"
- " Control the behavior of RWSIG task.\n"
- " rwsigstatus (DEPRECATED; use \"rwsig status\"\n"
- " Run RW signature verification and get status.\n"
- " sertest\n"
- " Serial output test for COM2\n"
- " smartdischarge\n"
- " Set/Get smart discharge parameters\n"
- " stress [reboot] [help]\n"
- " Stress test the ec host command interface.\n"
- " sysinfo [flags|reset_flags|firmware_copy]\n"
- " Display system info.\n"
- " switches\n"
- " Prints current EC switch positions\n"
- " temps <sensorid>\n"
- " Print temperature.\n"
- " tempsinfo <sensorid>\n"
- " Print temperature sensor info.\n"
- " thermalget <platform-specific args>\n"
- " Get the threshold temperature values from the thermal engine.\n"
- " thermalset <platform-specific args>\n"
- " Set the threshold temperature values for the thermal engine.\n"
- " tpselftest\n"
- " Run touchpad self test.\n"
- " tpframeget\n"
- " Get touchpad frame data.\n"
- " tmp006cal <tmp006_index> [params...]\n"
- " Get/set TMP006 calibration\n"
- " tmp006raw <tmp006_index>\n"
- " Get raw TMP006 data\n"
- " typeccontrol <port> <command>\n"
- " Control USB PD policy\n"
- " typecdiscovery <port> <type>\n"
- " Get discovery information for port and type\n"
- " typecstatus <port>\n"
- " Get status information for port\n"
- " uptimeinfo\n"
- " Get info about how long the EC has been running and the most\n"
- " recent AP resets\n"
- " usbchargemode <port> <mode> [<inhibit_charge>]\n"
- " Set USB charging mode\n"
- " usbmux <mux>\n"
- " Set USB mux switch state\n"
- " usbpd <port> <auto | "
- "[toggle|toggle-off|sink|source] [none|usb|dp|dock] "
- "[dr_swap|pr_swap|vconn_swap]>\n"
- " Control USB PD/type-C [deprecated]\n"
- " usbpdmuxinfo\n"
- " Get USB-C SS mux info\n"
- " usbpdpower [port]\n"
- " Get USB PD power information\n"
- " version\n"
- " Prints EC version\n"
- " waitevent <type> [<timeout>]\n"
- " Wait for the MKBP event of type and display it\n"
- " wireless <flags> [<mask> [<suspend_flags> <suspend_mask>]]\n"
- " Enable/disable WLAN/Bluetooth radio\n"
- "";
-
-/* Note: depends on enum ec_image */
-static const char * const image_names[] = {"unknown", "RO", "RW"};
-
-/* Note: depends on enum ec_led_colors */
-static const char * const led_color_names[] = {
- "red", "green", "blue", "yellow", "white", "amber"};
-BUILD_ASSERT(ARRAY_SIZE(led_color_names) == EC_LED_COLOR_COUNT);
-
-/* Note: depends on enum ec_led_id */
-static const char * const led_names[] = {
- "battery", "power", "adapter", "left", "right", "recovery_hwreinit",
- "sysrq debug" };
-BUILD_ASSERT(ARRAY_SIZE(led_names) == EC_LED_ID_COUNT);
-
-/* ASCII mode for printing, default off */
-static int ascii_mode = 0;
-
-/* Check SBS numerical value range */
-int is_battery_range(int val)
-{
- return (val >= 0 && val <= 65535) ? 1 : 0;
-}
-
-int parse_bool(const char *s, int *dest)
-{
- if (!strcasecmp(s, "off") || !strncasecmp(s, "dis", 3) ||
- tolower(*s) == 'f' || tolower(*s) == 'n') {
- *dest = 0;
- return 1;
- } else if (!strcasecmp(s, "on") || !strncasecmp(s, "ena", 3) ||
- tolower(*s) == 't' || tolower(*s) == 'y') {
- *dest = 1;
- return 1;
- } else {
- return 0;
- }
-}
-
-void print_help(const char *prog, int print_cmds)
-{
- printf("Usage: %s [--dev=n] [--interface=dev|i2c|lpc] [--i2c_bus=n]",
- prog);
- printf("[--name=cros_ec|cros_fp|cros_pd|cros_scp|cros_ish] [--ascii] ");
- printf("<command> [params]\n\n");
- printf(" --i2c_bus=n Specifies the number of an I2C bus to use. For\n"
- " example, to use /dev/i2c-7, pass --i2c_bus=7.\n"
- " Implies --interface=i2c.\n\n");
- if (print_cmds)
- puts(help_str);
- else
- printf("Use '%s help' to print a list of commands.\n", prog);
-}
-
-static uint8_t read_mapped_mem8(uint8_t offset)
-{
- int ret;
- uint8_t val;
-
- ret = ec_readmem(offset, sizeof(val), &val);
- if (ret <= 0) {
- fprintf(stderr, "failure in %s(): %d\n", __func__, ret);
- exit(1);
- }
- return val;
-}
-
-static uint16_t read_mapped_mem16(uint8_t offset)
-{
- int ret;
- uint16_t val;
-
- ret = ec_readmem(offset, sizeof(val), &val);
- if (ret <= 0) {
- fprintf(stderr, "failure in %s(): %d\n", __func__, ret);
- exit(1);
- }
- return val;
-}
-
-static uint32_t read_mapped_mem32(uint8_t offset)
-{
- int ret;
- uint32_t val;
-
- ret = ec_readmem(offset, sizeof(val), &val);
- if (ret <= 0) {
- fprintf(stderr, "failure in %s(): %d\n", __func__, ret);
- exit(1);
- }
- return val;
-}
-
-static int read_mapped_string(uint8_t offset, char *buffer, int max_size)
-{
- int ret;
-
- ret = ec_readmem(offset, max_size, buffer);
- if (ret <= 0) {
- fprintf(stderr, "failure in %s(): %d\n", __func__, ret);
- exit(1);
- }
- return ret;
-}
-
-static int wait_event(long event_type,
- struct ec_response_get_next_event_v1 *buffer,
- size_t buffer_size, long timeout)
-{
- int rv;
-
- rv = ec_pollevent(1 << event_type, buffer, buffer_size, timeout);
- if (rv == 0) {
- fprintf(stderr, "Timeout waiting for MKBP event\n");
- return -ETIMEDOUT;
- } else if (rv < 0) {
- perror("Error polling for MKBP event\n");
- return -EIO;
- }
-
- return rv;
-}
-
-int cmd_adc_read(int argc, char *argv[])
-{
- char *e;
- struct ec_params_adc_read p;
- struct ec_response_adc_read r;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <adc channel>\n", argv[0]);
- return -1;
- }
-
- p.adc_channel = (uint8_t)strtoull(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "\"%s\": invalid channel!\n", argv[1]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_ADC_READ, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv > 0) {
- printf("%s: %d\n", argv[1], r.adc_value);
- return 0;
- }
-
- return rv;
-}
-
-int cmd_add_entropy(int argc, char *argv[])
-{
- struct ec_params_rollback_add_entropy p;
- int rv;
- int tries = 100; /* Wait for 10 seconds at most */
-
- if (argc >= 2 && !strcmp(argv[1], "reset"))
- p.action = ADD_ENTROPY_RESET_ASYNC;
- else
- p.action = ADD_ENTROPY_ASYNC;
-
- rv = ec_command(EC_CMD_ADD_ENTROPY, 0, &p, sizeof(p), NULL, 0);
-
- if (rv != EC_RES_SUCCESS)
- goto out;
-
- while (tries--) {
- usleep(100000);
-
- p.action = ADD_ENTROPY_GET_RESULT;
- rv = ec_command(EC_CMD_ADD_ENTROPY, 0, &p, sizeof(p), NULL, 0);
-
- if (rv == EC_RES_SUCCESS) {
- printf("Entropy added successfully\n");
- return EC_RES_SUCCESS;
- }
-
- /* Abort if EC returns an error other than EC_RES_BUSY. */
- if (rv <= -EECRESULT && rv != -EECRESULT-EC_RES_BUSY)
- goto out;
- }
-
- rv = -EECRESULT-EC_RES_TIMEOUT;
-out:
- fprintf(stderr, "Failed to add entropy: %d\n", rv);
- return rv;
-}
-
-int cmd_hello(int argc, char *argv[])
-{
- struct ec_params_hello p;
- struct ec_response_hello r;
- int rv;
-
- p.in_data = 0xa0b0c0d0;
-
- rv = ec_command(EC_CMD_HELLO, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- if (r.out_data != 0xa1b2c3d4) {
- fprintf(stderr, "Expected response 0x%08x, got 0x%08x\n",
- 0xa1b2c3d4, r.out_data);
- return -1;
- }
-
- printf("EC says hello!\n");
- return 0;
-}
-
-int cmd_hibdelay(int argc, char *argv[])
-{
- struct ec_params_hibernation_delay p;
- struct ec_response_hibernation_delay r;
- char *e;
- int rv;
-
- if (argc < 2) {
- p.seconds = 0; /* Just read the current settings. */
- } else {
- p.seconds = strtoull(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid number\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_HIBERNATION_DELAY, 0, &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "err: rv=%d\n", rv);
- return -1;
- }
-
- printf("Hibernation delay: %u s\n", r.hibernate_delay);
- printf("Time G3: %u s\n", r.time_g3);
- printf("Time left: %u s\n", r.time_remaining);
- return 0;
-}
-
-static void cmd_hostevent_help(char *cmd)
-{
- fprintf(stderr,
- " Usage: %s get <type>\n"
- " Usage: %s set <type> <value>\n"
- " <type> is one of:\n"
- " 1: EC_HOST_EVENT_B\n"
- " 2: EC_HOST_EVENT_SCI_MASK\n"
- " 3: EC_HOST_EVENT_SMI_MASK\n"
- " 4: EC_HOST_EVENT_ALWAYS_REPORT_MASK\n"
- " 5: EC_HOST_EVENT_ACTIVE_WAKE_MASK\n"
- " 6: EC_HOST_EVENT_LAZY_WAKE_MASK_S0IX\n"
- " 7: EC_HOST_EVENT_LAZY_WAKE_MASK_S3\n"
- " 8: EC_HOST_EVENT_LAZY_WAKE_MASK_S5\n"
- , cmd, cmd);
-}
-
-static int cmd_hostevent(int argc, char *argv[])
-{
- struct ec_params_host_event p;
- struct ec_response_host_event r;
- char *e;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_hostevent_help(argv[0]);
- return -1;
- }
-
- if (!strcasecmp(argv[1], "get")) {
- if (argc != 3) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_hostevent_help(argv[0]);
- return -1;
- }
- p.action = EC_HOST_EVENT_GET;
- } else if (!strcasecmp(argv[1], "set")) {
- if (argc != 4) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_hostevent_help(argv[0]);
- return -1;
- }
- p.action = EC_HOST_EVENT_SET;
- p.value = strtoull(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value\n");
- return -1;
- }
- } else {
- fprintf(stderr, "Bad subcommand: %s\n", argv[1]);
- return -1;
- }
-
- p.mask_type = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad type\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv == -EC_RES_ACCESS_DENIED - EECRESULT) {
- fprintf(stderr, "%s isn't permitted for mask %d.\n",
- p.action == EC_HOST_EVENT_SET ? "Set" : "Get",
- p.mask_type);
- return rv;
- } else if (rv < 0) {
- return rv;
- }
-
- if (p.action == EC_HOST_EVENT_GET)
- printf("0x%" PRIx64 "\n", r.value);
-
- return 0;
-}
-
-static int get_latest_cmd_version(uint8_t cmd, int *version)
-{
- struct ec_params_get_cmd_versions p;
- struct ec_response_get_cmd_versions r;
- int rv;
-
- *version = 0;
- /* Figure out the latest version of the given command the EC supports */
- p.cmd = cmd;
- rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0) {
- if (rv == -EC_RES_INVALID_PARAM)
- printf("Command 0x%02x not supported by EC.\n",
- EC_CMD_GET_CMD_VERSIONS);
- return rv;
- }
-
- if (r.version_mask)
- *version = __fls(r.version_mask);
-
- return rv;
-}
-
-int cmd_hostsleepstate(int argc, char *argv[])
-{
- struct ec_params_host_sleep_event p;
- struct ec_params_host_sleep_event_v1 p1;
- struct ec_response_host_sleep_event_v1 r;
- void *pp = &p;
- size_t psize = sizeof(p), rsize = 0;
- char *afterscan;
- int rv;
- int version = 0, max_version = 0;
- uint32_t timeout, transitions;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s "
- "[suspend|wsuspend|resume|freeze|thaw] [timeout]\n",
- argv[0]);
- return -1;
- }
-
- rv = get_latest_cmd_version(EC_CMD_HOST_SLEEP_EVENT, &max_version);
- if (rv < 0)
- return rv;
-
- if (!strcmp(argv[1], "suspend"))
- p.sleep_event = HOST_SLEEP_EVENT_S3_SUSPEND;
- else if (!strcmp(argv[1], "wsuspend"))
- p.sleep_event = HOST_SLEEP_EVENT_S3_WAKEABLE_SUSPEND;
- else if (!strcmp(argv[1], "resume"))
- p.sleep_event = HOST_SLEEP_EVENT_S3_RESUME;
- else if (!strcmp(argv[1], "freeze")) {
- p.sleep_event = HOST_SLEEP_EVENT_S0IX_SUSPEND;
- if (max_version >= 1) {
- p1.sleep_event = p.sleep_event;
- p1.reserved = 0;
- p1.suspend_params.sleep_timeout_ms =
- EC_HOST_SLEEP_TIMEOUT_DEFAULT;
-
- if (argc > 2) {
- p1.suspend_params.sleep_timeout_ms =
- strtoull(argv[2], &afterscan, 0);
-
- if ((*afterscan != '\0') ||
- (afterscan == argv[2])) {
- fprintf(stderr,
- "Invalid value: %s\n",
- argv[2]);
-
- return -1;
- }
- }
-
- pp = &p1;
- psize = sizeof(p1);
- version = 1;
- }
-
- } else if (!strcmp(argv[1], "thaw")) {
- p.sleep_event = HOST_SLEEP_EVENT_S0IX_RESUME;
- if (max_version >= 1) {
- version = 1;
- rsize = sizeof(r);
- }
- } else {
- fprintf(stderr, "Unknown command: %s\n", argv[1]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_SLEEP_EVENT, version, pp, psize, &r, rsize);
- if (rv < 0) {
- fprintf(stderr, "EC host sleep command failed: %d\n", rv);
- return rv;
- }
-
- if (rsize) {
- timeout = r.resume_response.sleep_transitions &
- EC_HOST_RESUME_SLEEP_TIMEOUT;
-
- transitions = r.resume_response.sleep_transitions &
- EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK;
-
- printf("%s%d sleep line transitions.\n",
- timeout ? "Timeout: " : "",
- transitions);
- }
-
- return 0;
-}
-
-int cmd_test(int argc, char *argv[])
-{
- struct ec_params_test_protocol p = {
- .buf = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }
- };
- struct ec_response_test_protocol r;
- int rv, version = 0;
- char *e;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s result length [version]\n",
- argv[0]);
- return -1;
- }
-
- p.ec_result = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid param (result)\n");
- return -1;
- }
- p.ret_len = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid param (length)\n");
- return -1;
- }
-
- if (argc > 3) {
- version = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid param (version)\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_TEST_PROTOCOL, version,
- &p, sizeof(p), &r, sizeof(r));
- printf("rv = %d\n", rv);
-
- return rv;
-}
-
-int cmd_s5(int argc, char *argv[])
-{
- struct ec_params_get_set_value p;
- struct ec_params_get_set_value r;
- int rv, param;
-
- p.flags = 0;
-
- if (argc > 1) {
- p.flags |= EC_GSV_SET;
- if (!parse_bool(argv[1], &param)) {
- fprintf(stderr, "invalid arg \"%s\"\n", argv[1]);
- return -1;
- }
- p.value = param;
- }
-
- rv = ec_command(EC_CMD_GSV_PAUSE_IN_S5, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv > 0)
- printf("%s\n", r.value ? "on" : "off");
-
- return rv < 0;
-}
-
-static const char * const ec_feature_names[] = {
- [EC_FEATURE_LIMITED] = "Limited image, load RW for more",
- [EC_FEATURE_FLASH] = "Flash",
- [EC_FEATURE_PWM_FAN] = "Direct Fan power management",
- [EC_FEATURE_PWM_KEYB] = "Keyboard backlight",
- [EC_FEATURE_LIGHTBAR] = "Lightbar",
- [EC_FEATURE_LED] = "LED",
- [EC_FEATURE_MOTION_SENSE] = "Motion Sensors",
- [EC_FEATURE_KEYB] = "Keyboard",
- [EC_FEATURE_PSTORE] = "Host Permanent Storage",
- [EC_FEATURE_PORT80] = "BIOS Port 80h access",
- [EC_FEATURE_THERMAL] = "Thermal management",
- [EC_FEATURE_BKLIGHT_SWITCH] = "Switch backlight on/off",
- [EC_FEATURE_WIFI_SWITCH] = "Switch wifi on/off",
- [EC_FEATURE_HOST_EVENTS] = "Host event",
- [EC_FEATURE_GPIO] = "GPIO",
- [EC_FEATURE_I2C] = "I2C controller",
- [EC_FEATURE_CHARGER] = "Charger",
- [EC_FEATURE_BATTERY] = "Simple Battery",
- [EC_FEATURE_SMART_BATTERY] = "Smart Battery",
- [EC_FEATURE_HANG_DETECT] = "Host hang detection",
- [EC_FEATURE_PMU] = "Power Management",
- [EC_FEATURE_SUB_MCU] = "Control downstream MCU",
- [EC_FEATURE_USB_PD] = "USB Cros Power Delivery",
- [EC_FEATURE_USB_MUX] = "USB Multiplexer",
- [EC_FEATURE_MOTION_SENSE_FIFO] = "FIFO for Motion Sensors events",
- [EC_FEATURE_VSTORE] = "Temporary secure vstore",
- [EC_FEATURE_USBC_SS_MUX_VIRTUAL] = "Host-controlled USB-C SS mux",
- [EC_FEATURE_RTC] = "Real-time clock",
- [EC_FEATURE_FINGERPRINT] = "Fingerprint",
- [EC_FEATURE_TOUCHPAD] = "Touchpad",
- [EC_FEATURE_RWSIG] = "RWSIG task",
- [EC_FEATURE_DEVICE_EVENT] = "Device events reporting",
- [EC_FEATURE_UNIFIED_WAKE_MASKS] = "Unified wake masks for LPC/eSPI",
- [EC_FEATURE_HOST_EVENT64] = "64-bit host events",
- [EC_FEATURE_EXEC_IN_RAM] = "Execute code in RAM",
- [EC_FEATURE_CEC] = "Consumer Electronics Control",
- [EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS] =
- "Tight timestamp for sensors events",
- [EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS] =
- "Refined tablet mode hysteresis",
- [EC_FEATURE_EFS2] = "Early Firmware Selection v2",
- [EC_FEATURE_ISH] = "Intel Integrated Sensor Hub",
- [EC_FEATURE_TYPEC_CMD] = "TCPMv2 Type-C commands",
- [EC_FEATURE_TYPEC_REQUIRE_AP_MODE_ENTRY] =
- "Host-controlled Type-C mode entry",
- [EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK] =
- "AP ack for Type-C mux configuration",
-};
-
-int cmd_inventory(int argc, char *argv[])
-{
- struct ec_response_get_features r;
- int rv, i, j, idx;
-
- rv = ec_command(EC_CMD_GET_FEATURES, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("EC supported features:\n");
- for (i = 0, idx = 0; i < 2; i++) {
- for (j = 0; j < 32; j++, idx++) {
- if (r.flags[i] & BIT(j)) {
- if (idx >= ARRAY_SIZE(ec_feature_names) ||
- !ec_feature_names[idx] ||
- strlen(ec_feature_names[idx]) == 0)
- printf("%-4d: Unknown feature\n", idx);
- else
- printf("%-4d: %s support\n",
- idx, ec_feature_names[idx]);
- }
- }
- }
- return 0;
-}
-
-
-int cmd_cmdversions(int argc, char *argv[])
-{
- struct ec_params_get_cmd_versions p;
- struct ec_response_get_cmd_versions r;
- char *e;
- int cmd;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <cmd>\n", argv[0]);
- return -1;
- }
- cmd = strtol(argv[1], &e, 0);
- if ((e && *e) || cmd < 0 || cmd > 0xff) {
- fprintf(stderr, "Bad command number.\n");
- return -1;
- }
-
- p.cmd = cmd;
- rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0) {
- if (rv == -EC_RES_INVALID_PARAM)
- printf("Command 0x%02x not supported by EC.\n", cmd);
-
- return rv;
- }
-
- printf("Command 0x%02x supports version mask 0x%08x\n",
- cmd, r.version_mask);
- return 0;
-}
-
-/*
- * Convert a reset cause ID to human-readable string, providing total coverage
- * of the 'cause' space. The returned string points to static storage and must
- * not be free()ed.
- */
-static const char *reset_cause_to_str(uint16_t cause)
-{
- static const char * const reset_causes[] = {
- "(reset unknown)",
- "reset: board custom",
- "reset: ap hang detected",
- "reset: console command",
- "reset: host command",
- "reset: keyboard sysreset",
- "reset: keyboard warm reboot",
- "reset: debug warm reboot",
- "reset: at AP's request",
- "reset: during EC initialization",
- "reset: AP watchdog",
- };
- BUILD_ASSERT(ARRAY_SIZE(reset_causes) == CHIPSET_RESET_COUNT);
-
- static const char * const shutdown_causes[] = {
- "shutdown: power failure",
- "shutdown: during EC initialization",
- "shutdown: board custom",
- "shutdown: battery voltage startup inhibit",
- "shutdown: power wait asserted",
- "shutdown: critical battery",
- "shutdown: by console command",
- "shutdown: entering G3",
- "shutdown: thermal",
- "shutdown: power button",
- };
- BUILD_ASSERT(ARRAY_SIZE(shutdown_causes) ==
- CHIPSET_SHUTDOWN_COUNT - CHIPSET_SHUTDOWN_BEGIN);
-
- if (cause < CHIPSET_RESET_COUNT)
- return reset_causes[cause];
-
- if (cause < CHIPSET_SHUTDOWN_BEGIN)
- return "(reset unknown)";
-
- if (cause < CHIPSET_SHUTDOWN_COUNT)
- return shutdown_causes[cause - CHIPSET_SHUTDOWN_BEGIN];
-
- return "(shutdown unknown)";
-}
-
-int cmd_uptimeinfo(int argc, char *argv[])
-{
- struct ec_response_uptime_info r;
- int rv;
- int i;
- int flag_count;
- uint32_t flag;
- static const char * const reset_flag_descs[] = {
- #include "reset_flag_desc.inc"
- };
-
- if (argc != 1) {
- fprintf(stderr, "uptimeinfo takes no arguments");
- return -1;
- }
-
- rv = ec_command(EC_CMD_GET_UPTIME_INFO, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "ERROR: EC_CMD_GET_UPTIME_INFO failed; %d\n",
- rv);
- return rv;
- }
-
- printf("EC uptime: %d.%03d seconds\n",
- r.time_since_ec_boot_ms / 1000,
- r.time_since_ec_boot_ms % 1000);
-
- printf("AP resets since EC boot: %d\n", r.ap_resets_since_ec_boot);
-
- printf("Most recent AP reset causes:\n");
- for (i = 0; i != ARRAY_SIZE(r.recent_ap_reset); ++i) {
- if (r.recent_ap_reset[i].reset_time_ms == 0)
- continue;
-
- printf("\t%d.%03d: %s\n",
- r.recent_ap_reset[i].reset_time_ms / 1000,
- r.recent_ap_reset[i].reset_time_ms % 1000,
- reset_cause_to_str(r.recent_ap_reset[i].reset_cause));
- }
-
- printf("EC reset flags at last EC boot: ");
-
- if (!r.ec_reset_flags) {
- printf("unknown\n");
- return 0;
- }
-
- flag_count = 0;
- for (flag = 0; flag < ARRAY_SIZE(reset_flag_descs); ++flag) {
- if ((r.ec_reset_flags & BIT(flag)) != 0) {
- if (flag_count)
- printf(" | ");
- printf(reset_flag_descs[flag]);
- flag_count++;
- }
- }
-
- if (r.ec_reset_flags >= BIT(flag)) {
- if (flag_count)
- printf(" | ");
- printf("no-desc");
- }
- printf("\n");
- return 0;
-}
-
-int cmd_version(int argc, char *argv[])
-{
- struct ec_response_get_version_v1 r;
- char *build_string = (char *)ec_inbuf;
- int rv;
-
- if (ec_cmd_version_supported(EC_CMD_GET_VERSION, 1)) {
- rv = ec_command(EC_CMD_GET_VERSION, 1, NULL, 0, &r,
- sizeof(struct ec_response_get_version_v1));
- } else {
- /* Fall-back to version 0 if version 1 is not supported */
- rv = ec_command(EC_CMD_GET_VERSION, 0, NULL, 0, &r,
- sizeof(struct ec_response_get_version));
- /* These fields are not supported in version 0, ensure empty */
- r.cros_fwid_ro[0] = '\0';
- r.cros_fwid_rw[0] = '\0';
- }
- if (rv < 0) {
- fprintf(stderr, "ERROR: EC_CMD_GET_VERSION failed: %d\n", rv);
- goto exit;
- }
-
- rv = ec_command(EC_CMD_GET_BUILD_INFO, 0,
- NULL, 0, ec_inbuf, ec_max_insize);
- if (rv < 0) {
- fprintf(stderr, "ERROR: EC_CMD_GET_BUILD_INFO failed: %d\n",
- rv);
- goto exit;
- }
-
- rv = 0;
-
- /* Ensure versions are null-terminated before we print them */
- r.version_string_ro[sizeof(r.version_string_ro) - 1] = '\0';
- r.version_string_rw[sizeof(r.version_string_rw) - 1] = '\0';
- build_string[ec_max_insize - 1] = '\0';
- r.cros_fwid_ro[sizeof(r.cros_fwid_ro) - 1] = '\0';
- r.cros_fwid_rw[sizeof(r.cros_fwid_rw) - 1] = '\0';
- /* Print versions */
- printf("RO version: %s\n", r.version_string_ro);
- if (strlen(r.cros_fwid_ro))
- printf("RO cros fwid: %s\n", r.cros_fwid_ro);
- printf("RW version: %s\n", r.version_string_rw);
- if (strlen(r.cros_fwid_rw))
- printf("RW cros fwid: %s\n", r.cros_fwid_rw);
- printf("Firmware copy: %s\n",
- (r.current_image < ARRAY_SIZE(image_names) ?
- image_names[r.current_image] : "?"));
- printf("Build info: %s\n", build_string);
-exit:
- printf("Tool version: %s %s %s\n", CROS_ECTOOL_VERSION, DATE, BUILDER);
-
- return rv;
-}
-
-
-int cmd_read_test(int argc, char *argv[])
-{
- struct ec_params_read_test p;
- struct ec_response_read_test r;
- int offset, size;
- int errors = 0;
- int rv;
- int i;
- char *e;
- char *buf;
- uint32_t *b;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <pattern_offset> <size>\n", argv[0]);
- return -1;
- }
- offset = strtol(argv[1], &e, 0);
- size = strtol(argv[2], &e, 0);
- if ((e && *e) || size <= 0 || size > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
- printf("Reading %d bytes with pattern offset 0x%x...\n", size, offset);
-
- buf = (char *)malloc(size);
- if (!buf) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- return -1;
- }
-
- /* Read data in chunks */
- for (i = 0; i < size; i += sizeof(r.data)) {
- p.offset = offset + i / sizeof(uint32_t);
- p.size = MIN(size - i, sizeof(r.data));
- rv = ec_command(EC_CMD_READ_TEST, 0, &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "Read error at offset %d\n", i);
- free(buf);
- return rv;
- }
- memcpy(buf + i, r.data, p.size);
- }
-
- /* Check data */
- for (i = 0, b = (uint32_t *)buf; i < size / 4; i++, b++) {
- if (*b != i + offset) {
- printf("Mismatch at byte offset 0x%x: "
- "expected 0x%08x, got 0x%08x\n",
- (int)(i * sizeof(uint32_t)), i + offset, *b);
- errors++;
- }
- }
-
- free(buf);
- if (errors) {
- printf("Found %d errors\n", errors);
- return -1;
- }
-
- printf("done.\n");
- return 0;
-}
-
-
-int cmd_reboot_ec(int argc, char *argv[])
-{
- struct ec_params_reboot_ec p;
- int rv, i;
-
- if (argc < 2) {
- /*
- * No params specified so tell the EC to reboot immediately.
- * That reboots the AP as well, so unlikely we'll be around
- * to see a return code from this...
- */
- rv = ec_command(EC_CMD_REBOOT, 0, NULL, 0, NULL, 0);
- return (rv < 0 ? rv : 0);
- }
-
- /* Parse command */
- if (!strcmp(argv[1], "cancel"))
- p.cmd = EC_REBOOT_CANCEL;
- else if (!strcmp(argv[1], "RO"))
- p.cmd = EC_REBOOT_JUMP_RO;
- else if (!strcmp(argv[1], "RW"))
- p.cmd = EC_REBOOT_JUMP_RW;
- else if (!strcmp(argv[1], "cold"))
- p.cmd = EC_REBOOT_COLD;
- else if (!strcmp(argv[1], "disable-jump"))
- p.cmd = EC_REBOOT_DISABLE_JUMP;
- else if (!strcmp(argv[1], "hibernate"))
- p.cmd = EC_REBOOT_HIBERNATE;
- else if (!strcmp(argv[1], "hibernate-clear-ap-off"))
- p.cmd = EC_REBOOT_HIBERNATE_CLEAR_AP_OFF;
- else if (!strcmp(argv[1], "cold-ap-off"))
- p.cmd = EC_REBOOT_COLD_AP_OFF;
- else {
- fprintf(stderr, "Unknown command: %s\n", argv[1]);
- return -1;
- }
-
- /* Parse flags, if any */
- p.flags = 0;
- for (i = 2; i < argc; i++) {
- if (!strcmp(argv[i], "at-shutdown")) {
- p.flags |= EC_REBOOT_FLAG_ON_AP_SHUTDOWN;
- } else if (!strcmp(argv[i], "switch-slot")) {
- p.flags |= EC_REBOOT_FLAG_SWITCH_RW_SLOT;
- } else {
- fprintf(stderr, "Unknown flag: %s\n", argv[i]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_REBOOT_EC, 0, &p, sizeof(p), NULL, 0);
- return (rv < 0 ? rv : 0);
-}
-
-int cmd_reboot_ap_on_g3(int argc, char *argv[])
-{
- struct ec_params_reboot_ap_on_g3_v1 p;
- int rv;
- char *e;
- int cmdver;
-
- if (argc < 2) {
- p.reboot_ap_at_g3_delay = 0;
- } else {
- p.reboot_ap_at_g3_delay = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid number\n");
- return -1;
- }
- }
- if (ec_cmd_version_supported(EC_CMD_REBOOT_AP_ON_G3, 1))
- cmdver = 1;
- else
- cmdver = 0;
-
- rv = ec_command(EC_CMD_REBOOT_AP_ON_G3, cmdver, &p, sizeof(p), NULL, 0);
- return (rv < 0 ? rv : 0);
-}
-
-int cmd_button(int argc, char *argv[])
-{
- struct ec_params_button p;
- char *e;
- int argv_idx;
- int button = KEYBOARD_BUTTON_COUNT;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Invalid num param %d.\n", argc);
- return -1;
- }
-
- p.press_ms = 50;
- p.btn_mask = 0;
-
- for (argv_idx = 1; argv_idx < argc; argv_idx++) {
- if (!strcasecmp(argv[argv_idx], "vup"))
- button = KEYBOARD_BUTTON_VOLUME_UP;
- else if (!strcasecmp(argv[argv_idx], "vdown"))
- button = KEYBOARD_BUTTON_VOLUME_DOWN;
- else if (!strcasecmp(argv[argv_idx], "rec"))
- button = KEYBOARD_BUTTON_RECOVERY;
- else {
- /* If last parameter check if it is an integer. */
- if (argv_idx == argc - 1) {
- p.press_ms = strtol(argv[argv_idx], &e, 0);
- /* If integer, break out of the loop. */
- if (!*e)
- break;
- }
- button = KEYBOARD_BUTTON_COUNT;
- }
-
- if (button == KEYBOARD_BUTTON_COUNT) {
- fprintf(stderr, "Invalid button input.\n");
- return -1;
- }
-
- p.btn_mask |= (1 << button);
- }
- if (!p.btn_mask)
- return 0;
-
- rv = ec_command(EC_CMD_BUTTON, 0, &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Button(s) %d set to %d ms\n", p.btn_mask, p.press_ms);
- return 0;
-}
-
-int cmd_flash_info(int argc, char *argv[])
-{
- struct ec_response_flash_info_1 r;
- int cmdver = 1;
- int rsize = sizeof(r);
- int rv;
-
- memset(&r, 0, sizeof(r));
-
- if (!ec_cmd_version_supported(EC_CMD_FLASH_INFO, cmdver)) {
- /* Fall back to version 0 command */
- cmdver = 0;
- rsize = sizeof(struct ec_response_flash_info);
- }
-
- rv = ec_command(EC_CMD_FLASH_INFO, cmdver, NULL, 0, &r, rsize);
- if (rv < 0)
- return rv;
-
- printf("FlashSize %d\nWriteSize %d\nEraseSize %d\nProtectSize %d\n",
- r.flash_size, r.write_block_size, r.erase_block_size,
- r.protect_block_size);
-
- if (cmdver >= 1) {
- /* Fields added in ver.1 available */
- printf("WriteIdealSize %d\nFlags 0x%x\n",
- r.write_ideal_size, r.flags);
- }
-
- return 0;
-}
-
-int cmd_rand(int argc, char *argv[])
-{
- struct ec_params_rand_num p;
- struct ec_response_rand_num *r;
- size_t r_size;
- int64_t num_bytes;
- int64_t i;
- char *e;
- int rv = 0;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <num_bytes>\n", argv[0]);
- return -1;
- }
-
- num_bytes = strtol(argv[1], &e, 0);
- if ((e && *e) || (errno == ERANGE)) {
- fprintf(stderr, "Invalid num_bytes argument\n");
- return -1;
- }
-
- r = (struct ec_response_rand_num *)(ec_inbuf);
-
- for (i = 0; i < num_bytes; i += ec_max_insize) {
- p.num_rand_bytes = ec_max_insize;
- if (num_bytes - i < p.num_rand_bytes)
- p.num_rand_bytes = num_bytes - i;
-
- r_size = p.num_rand_bytes;
-
- rv = ec_command(EC_CMD_RAND_NUM, EC_VER_RAND_NUM, &p, sizeof(p),
- r, r_size);
- if (rv < 0) {
- fprintf(stderr, "Random number command failed\n");
- return -1;
- }
-
- rv = write(STDOUT_FILENO, r->rand, r_size);
- if (rv != r_size) {
- fprintf(stderr, "Failed to write stdout\n");
- return -1;
- }
- }
-
- return 0;
-}
-
-int cmd_flash_spi_info(int argc, char *argv[])
-{
- struct ec_response_flash_spi_info r;
- int rv;
-
- memset(&r, 0, sizeof(r));
-
- /* Print SPI flash info if available */
- if (!ec_cmd_version_supported(EC_CMD_FLASH_SPI_INFO, 0)) {
- printf("EC has no info (does not use SPI flash?)\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_FLASH_SPI_INFO, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("JEDECManufacturerID 0x%02x\n", r.jedec[0]);
- printf("JEDECDeviceID 0x%02x 0x%02x\n", r.jedec[1], r.jedec[2]);
- printf("JEDECCapacity %d\n", 1 << r.jedec[2]);
- printf("ManufacturerID 0x%02x\n", r.mfr_dev_id[0]);
- printf("DeviceID 0x%02x\n", r.mfr_dev_id[1]);
- printf("StatusRegister1 0x%02x\n", r.sr1);
- printf("StatusRegister2 0x%02x\n", r.sr2);
- return 0;
-}
-
-int cmd_flash_read(int argc, char *argv[])
-{
- int offset, size;
- int rv;
- char *e;
- uint8_t *buf;
-
- if (argc < 4) {
- fprintf(stderr,
- "Usage: %s <offset> <size> <filename>\n", argv[0]);
- return -1;
- }
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
- size = strtol(argv[2], &e, 0);
- if ((e && *e) || size <= 0 || size > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
- printf("Reading %d bytes at offset %d...\n", size, offset);
-
- buf = (uint8_t *)malloc(size);
- if (!buf) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- return -1;
- }
-
- /* Read data in chunks */
- rv = ec_flash_read(buf, offset, size);
- if (rv < 0) {
- free(buf);
- return rv;
- }
-
- rv = write_file(argv[3], (const char *)(buf), size);
- free(buf);
- if (rv)
- return rv;
-
- printf("done.\n");
- return 0;
-}
-
-int cmd_flash_write(int argc, char *argv[])
-{
- int offset, size;
- int rv;
- char *e;
- char *buf;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <offset> <filename>\n", argv[0]);
- return -1;
- }
-
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
-
- /* Read the input file */
- buf = read_file(argv[2], &size);
- if (!buf)
- return -1;
-
- printf("Writing to offset %d...\n", offset);
-
- /* Write data in chunks */
- rv = ec_flash_write((const uint8_t *)(buf), offset,
- size);
-
- free(buf);
-
- if (rv < 0)
- return rv;
-
- printf("done.\n");
- return 0;
-}
-
-int cmd_flash_erase(int argc, char *argv[])
-{
- int offset, size;
- char *e;
- int rv;
- bool async = false;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <offset> <size>\n", argv[0]);
- return -1;
- }
-
- if (strcmp(argv[0], "flasheraseasync") == 0)
- async = true;
-
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
-
- size = strtol(argv[2], &e, 0);
- if ((e && *e) || size <= 0 || size > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
-
- printf("Erasing %d bytes at offset %d...\n", size, offset);
- if (async)
- rv = ec_flash_erase_async(offset, size);
- else
- rv = ec_flash_erase(offset, size);
- if (rv < 0)
- return rv;
-
- printf("done.\n");
- return 0;
-}
-
-
-static void print_flash_protect_flags(const char *desc, uint32_t flags)
-{
- printf("%s 0x%08x", desc, flags);
- if (flags & EC_FLASH_PROTECT_GPIO_ASSERTED)
- printf(" wp_gpio_asserted");
- if (flags & EC_FLASH_PROTECT_RO_AT_BOOT)
- printf(" ro_at_boot");
- if (flags & EC_FLASH_PROTECT_RW_AT_BOOT)
- printf(" rw_at_boot");
- if (flags & EC_FLASH_PROTECT_ROLLBACK_AT_BOOT)
- printf(" rollback_at_boot");
- if (flags & EC_FLASH_PROTECT_ALL_AT_BOOT)
- printf(" all_at_boot");
- if (flags & EC_FLASH_PROTECT_RO_NOW)
- printf(" ro_now");
- if (flags & EC_FLASH_PROTECT_RW_NOW)
- printf(" rw_now");
- if (flags & EC_FLASH_PROTECT_ROLLBACK_NOW)
- printf(" rollback_now");
- if (flags & EC_FLASH_PROTECT_ALL_NOW)
- printf(" all_now");
- if (flags & EC_FLASH_PROTECT_ERROR_STUCK)
- printf(" STUCK");
- if (flags & EC_FLASH_PROTECT_ERROR_INCONSISTENT)
- printf(" INCONSISTENT");
- printf("\n");
-}
-
-
-int cmd_flash_protect(int argc, char *argv[])
-{
- struct ec_params_flash_protect p;
- struct ec_response_flash_protect r;
- int rv, i;
-
- /*
- * Set up requested flags. If no flags were specified, p.mask will
- * be 0 and nothing will change.
- */
- p.mask = p.flags = 0;
- for (i = 1; i < argc; i++) {
- if (!strcasecmp(argv[i], "now")) {
- p.mask |= EC_FLASH_PROTECT_ALL_NOW;
- p.flags |= EC_FLASH_PROTECT_ALL_NOW;
- } else if (!strcasecmp(argv[i], "enable")) {
- p.mask |= EC_FLASH_PROTECT_RO_AT_BOOT;
- p.flags |= EC_FLASH_PROTECT_RO_AT_BOOT;
- } else if (!strcasecmp(argv[i], "disable"))
- p.mask |= EC_FLASH_PROTECT_RO_AT_BOOT;
- }
-
- rv = ec_command(EC_CMD_FLASH_PROTECT, EC_VER_FLASH_PROTECT,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
- if (rv < sizeof(r)) {
- fprintf(stderr, "Too little data returned.\n");
- return -1;
- }
-
- /* Print returned flags */
- print_flash_protect_flags("Flash protect flags:", r.flags);
- print_flash_protect_flags("Valid flags: ", r.valid_flags);
- print_flash_protect_flags("Writable flags: ", r.writable_flags);
-
- /* Check if we got all the flags we asked for */
- if ((r.flags & p.mask) != (p.flags & p.mask)) {
- fprintf(stderr, "Unable to set requested flags "
- "(wanted mask 0x%08x flags 0x%08x)\n",
- p.mask, p.flags);
- if (p.mask & ~r.writable_flags)
- fprintf(stderr, "Which is expected, because writable "
- "mask is 0x%08x.\n", r.writable_flags);
-
- return -1;
- }
-
- return 0;
-}
-
-int cmd_rw_hash_pd(int argc, char *argv[])
-{
- struct ec_params_usb_pd_rw_hash_entry *p =
- (struct ec_params_usb_pd_rw_hash_entry *)ec_outbuf;
- int i, rv;
- char *e;
- uint32_t val;
- uint8_t *rwp;
-
- if (argc < 7) {
- fprintf(stderr, "Usage: %s <dev_id> <HASH[0]> ... <HASH[4]>\n",
- argv[0]);
- return -1;
- }
-
- p->dev_id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad device ID\n");
- return -1;
- }
-
- rwp = p->dev_rw_hash;
- for (i = 2; i < 7; i++) {
- val = strtol(argv[i], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad RW hash\n");
- return -1;
- }
- rwp[0] = (uint8_t) (val >> 0) & 0xff;
- rwp[1] = (uint8_t) (val >> 8) & 0xff;
- rwp[2] = (uint8_t) (val >> 16) & 0xff;
- rwp[3] = (uint8_t) (val >> 24) & 0xff;
- rwp += 4;
- }
- rv = ec_command(EC_CMD_USB_PD_RW_HASH_ENTRY, 0, p, sizeof(*p), NULL, 0);
-
- return rv;
-}
-
-int cmd_rwsig_status(int argc, char *argv[])
-{
- int rv;
- struct ec_response_rwsig_check_status resp;
-
- rv = ec_command(EC_CMD_RWSIG_CHECK_STATUS, 0, NULL, 0,
- &resp, sizeof(resp));
- if (rv < 0)
- return rv;
-
- printf("RW signature check: %s\n", resp.status ? "OK" : "FAILED");
-
- return 0;
-}
-
-static int rwsig_action(const char *command)
-{
- struct ec_params_rwsig_action req;
-
- if (!strcasecmp(command, "abort"))
- req.action = RWSIG_ACTION_ABORT;
- else if (!strcasecmp(command, "continue"))
- req.action = RWSIG_ACTION_CONTINUE;
- else
- return -1;
-
- return ec_command(EC_CMD_RWSIG_ACTION, 0, &req, sizeof(req), NULL, 0);
-}
-
-int cmd_rwsig_action_legacy(int argc, char *argv[])
-{
- if (argc < 2) {
- fprintf(stderr, "Usage: %s [abort | continue]\n", argv[0]);
- return -1;
- }
-
- return rwsig_action(argv[1]);
-}
-
-int cmd_rwsig_action(int argc, char *argv[])
-{
- if (argc < 2) {
- fprintf(stderr, "Usage: ectool rwsig action [abort | "
- "continue]\n");
- return -1;
- }
-
- return rwsig_action(argv[1]);
-}
-
-enum rwsig_info_fields {
- RWSIG_INFO_FIELD_SIG_ALG = BIT(0),
- RWSIG_INFO_FIELD_KEY_VERSION = BIT(1),
- RWSIG_INFO_FIELD_HASH_ALG = BIT(2),
- RWSIG_INFO_FIELD_KEY_IS_VALID = BIT(3),
- RWSIG_INFO_FIELD_KEY_ID = BIT(4),
- RWSIG_INFO_FIELD_ALL = RWSIG_INFO_FIELD_SIG_ALG |
- RWSIG_INFO_FIELD_KEY_VERSION | RWSIG_INFO_FIELD_HASH_ALG |
- RWSIG_INFO_FIELD_KEY_IS_VALID | RWSIG_INFO_FIELD_KEY_ID
-};
-
-static int rwsig_info(enum rwsig_info_fields fields)
-{
- int i;
- int rv;
- struct ec_response_rwsig_info r;
- bool print_prefix = false;
-
- rv = ec_command(EC_CMD_RWSIG_INFO, EC_VER_RWSIG_INFO, NULL, 0, &r,
- sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "rwsig info command failed\n");
- return -1;
- }
-
- if ((fields & RWSIG_INFO_FIELD_ALL) == RWSIG_INFO_FIELD_ALL)
- print_prefix = true;
-
- if (fields & RWSIG_INFO_FIELD_SIG_ALG) {
- if (print_prefix)
- printf("sig_alg: ");
-
- printf("%d\n", r.sig_alg);
- }
- if (fields & RWSIG_INFO_FIELD_KEY_VERSION) {
- if (print_prefix)
- printf("key_version: ");
-
- printf("%d\n", r.key_version);
- }
- if (fields & RWSIG_INFO_FIELD_HASH_ALG) {
- if (print_prefix)
- printf("hash_alg: ");
-
- printf("%d\n", r.hash_alg);
- }
- if (fields & RWSIG_INFO_FIELD_KEY_IS_VALID) {
- if (print_prefix)
- printf("key_is_valid: ");
-
- printf("%d\n", r.key_is_valid);
- }
- if (fields & RWSIG_INFO_FIELD_KEY_ID) {
- if (print_prefix)
- printf("key_id: ");
-
- for (i = 0; i < sizeof(r.key_id); i++)
- printf("%02x", r.key_id[i]);
- printf("\n");
- }
-
- return 0;
-}
-
-static int cmd_rwsig_info(int argc, char *argv[])
-{
- int i;
-
- struct rwsig_dump_cmds {
- const char *cmd;
- enum rwsig_info_fields field;
- };
-
- struct rwsig_dump_cmds cmd_map[] = {
- { "sig_alg", RWSIG_INFO_FIELD_SIG_ALG },
- { "key_version", RWSIG_INFO_FIELD_KEY_VERSION },
- { "hash_alg", RWSIG_INFO_FIELD_HASH_ALG },
- { "key_valid", RWSIG_INFO_FIELD_KEY_IS_VALID },
- { "key_id", RWSIG_INFO_FIELD_KEY_ID },
- };
-
- if (argc == 0)
- return -1;
-
- if (strcmp(argv[0], "info") == 0)
- return rwsig_info(RWSIG_INFO_FIELD_ALL);
-
- if (strcmp(argv[0], "dump") == 0) {
- if (argc != 2) {
- fprintf(stderr,
- "Usage: rwsig dump "
- "[sig_alg|key_version|hash_alg|key_valid|key_id]\n");
- return -1;
- }
- for (i = 0; i < ARRAY_SIZE(cmd_map); i++)
- if (strcmp(argv[1], cmd_map[i].cmd) == 0)
- return rwsig_info(cmd_map[i].field);
-
- return -1;
- }
-
- return -1;
-}
-
-int cmd_rwsig(int argc, char **argv)
-{
- struct rwsig_subcommand {
- const char *subcommand;
- int (*handler)(int argc, char *argv[]);
- };
-
- const struct rwsig_subcommand rwsig_subcommands[] = {
- { "info", cmd_rwsig_info },
- { "dump", cmd_rwsig_info },
- { "action", cmd_rwsig_action },
- { "status", cmd_rwsig_status }
- };
-
- int i;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <info|dump|action|status>\n",
- argv[0]);
- return -1;
- }
-
- for (i = 0; i < ARRAY_SIZE(rwsig_subcommands); i++)
- if (strcmp(argv[1], rwsig_subcommands[i].subcommand) == 0)
- return rwsig_subcommands[i].handler(--argc, &argv[1]);
-
- return -1;
-}
-
-enum sysinfo_fields {
- SYSINFO_FIELD_NONE = 0,
- SYSINFO_FIELD_RESET_FLAGS = BIT(0),
- SYSINFO_FIELD_CURRENT_IMAGE = BIT(1),
- SYSINFO_FIELD_FLAGS = BIT(2),
- SYSINFO_INFO_FIELD_ALL = SYSINFO_FIELD_RESET_FLAGS |
- SYSINFO_FIELD_CURRENT_IMAGE |
- SYSINFO_FIELD_FLAGS
-};
-
-static int sysinfo(struct ec_response_sysinfo *info)
-{
- int rv;
-
- rv = ec_command(EC_CMD_SYSINFO, 0, NULL, 0, info, sizeof(*info));
- if (rv < 0) {
- fprintf(stderr, "ERROR: EC_CMD_SYSINFO failed: %d\n", rv);
- return rv;
- }
-
- return 0;
-}
-
-int cmd_sysinfo(int argc, char **argv)
-{
- struct ec_response_sysinfo r;
- enum sysinfo_fields fields = SYSINFO_FIELD_NONE;
- bool print_prefix = false;
-
- if (argc != 1 && argc != 2)
- goto sysinfo_error_usage;
-
- if (argc == 1) {
- fields = SYSINFO_INFO_FIELD_ALL;
- print_prefix = true;
- } else if (argc == 2) {
- if (strcmp(argv[1], "flags") == 0)
- fields = SYSINFO_FIELD_FLAGS;
- else if (strcmp(argv[1], "reset_flags") == 0)
- fields = SYSINFO_FIELD_RESET_FLAGS;
- else if (strcmp(argv[1], "firmware_copy") == 0)
- fields = SYSINFO_FIELD_CURRENT_IMAGE;
- else
- goto sysinfo_error_usage;
- }
-
- memset(&r, '\0', sizeof(r));
- if (sysinfo(&r) != 0)
- return -1;
-
- if (fields & SYSINFO_FIELD_RESET_FLAGS) {
- if (print_prefix)
- printf("Reset flags: ");
- printf("0x%08x\n", r.reset_flags);
- }
-
- if (fields & SYSINFO_FIELD_FLAGS) {
- if (print_prefix)
- printf("Flags: ");
- printf("0x%08x\n", r.flags);
-
- }
-
- if (fields & SYSINFO_FIELD_CURRENT_IMAGE) {
- if (print_prefix)
- printf("Firmware copy: ");
- printf("%d\n", r.current_image);
- }
-
- return 0;
-
-sysinfo_error_usage:
- fprintf(stderr, "Usage: %s "
- "[flags|reset_flags|firmware_copy]\n",
- argv[0]);
- return -1;
-}
-
-int cmd_rollback_info(int argc, char *argv[])
-{
- struct ec_response_rollback_info r;
- int rv;
-
- rv = ec_command(EC_CMD_ROLLBACK_INFO, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "ERROR: EC_CMD_ROLLBACK_INFO failed: %d\n", rv);
- return rv;
- }
-
- /* Print versions */
- printf("Rollback block id: %d\n", r.id);
- printf("Rollback min version: %d\n", r.rollback_min_version);
- printf("RW rollback version: %d\n", r.rw_rollback_version);
-
- return 0;
-}
-
-int cmd_apreset(int argc, char *argv[])
-{
- return ec_command(EC_CMD_AP_RESET, 0, NULL, 0, NULL, 0);
-}
-
-#define FP_FRAME_INDEX_SIMPLE_IMAGE -1
-
-/*
- * Download a frame buffer from the FPMCU.
- *
- * Might be either the finger image or a finger template depending on 'index'.
- *
- * @param info a pointer to store the struct ec_response_fp_info retrieved by
- * this command.
- * @param index the specific frame to retrieve, might be:
- * -1 (aka FP_FRAME_INDEX_SIMPLE_IMAGE) for the a single grayscale image.
- * 0 (aka FP_FRAME_INDEX_RAW_IMAGE) for the full vendor raw finger image.
- * 1..n for a finger template.
- *
- * @returns a pointer to the buffer allocated to contain the frame or NULL
- * if case of error. The caller must call free() once it no longer needs the
- * buffer.
- */
-static void *fp_download_frame(struct ec_response_fp_info *info, int index)
-{
- struct ec_params_fp_frame p;
- int rv = 0;
- size_t stride, size;
- void *buffer;
- uint8_t *ptr;
- int cmdver = ec_cmd_version_supported(EC_CMD_FP_INFO, 1) ? 1 : 0;
- int rsize = cmdver == 1 ? sizeof(*info)
- : sizeof(struct ec_response_fp_info_v0);
- const int max_attempts = 3;
- int num_attempts;
-
- /* templates not supported in command v0 */
- if (index > 0 && cmdver == 0)
- return NULL;
-
- rv = ec_command(EC_CMD_FP_INFO, cmdver, NULL, 0, info, rsize);
- if (rv < 0)
- return NULL;
-
- if (index == FP_FRAME_INDEX_SIMPLE_IMAGE) {
- size = (size_t)info->width * info->bpp/8 * info->height;
- index = FP_FRAME_INDEX_RAW_IMAGE;
- } else if (index == FP_FRAME_INDEX_RAW_IMAGE) {
- size = info->frame_size;
- } else {
- size = info->template_size;
- }
-
- buffer = malloc(size);
- if (!buffer) {
- fprintf(stderr, "Cannot allocate memory for the image\n");
- return NULL;
- }
-
- ptr = (uint8_t *)(buffer);
- p.offset = index << FP_FRAME_INDEX_SHIFT;
- while (size) {
- stride = MIN(ec_max_insize, size);
- p.size = stride;
- num_attempts = 0;
- while (num_attempts < max_attempts) {
- num_attempts++;
- rv = ec_command(EC_CMD_FP_FRAME, 0, &p, sizeof(p),
- ptr, stride);
- if (rv >= 0)
- break;
- if (rv == -EECRESULT - EC_RES_ACCESS_DENIED)
- break;
- usleep(100000);
- }
- if (rv < 0) {
- free(buffer);
- return NULL;
- }
- p.offset += stride;
- size -= stride;
- ptr += stride;
- }
-
- return buffer;
-}
-
-int cmd_fp_mode(int argc, char *argv[])
-{
- struct ec_params_fp_mode p;
- struct ec_response_fp_mode r;
- uint32_t mode = 0;
- uint32_t capture_type = FP_CAPTURE_SIMPLE_IMAGE;
- int i, rv;
-
- if (argc == 1)
- mode = FP_MODE_DONT_CHANGE;
- for (i = 1; i < argc; i++) {
- /* modes */
- if (!strncmp(argv[i], "deepsleep", 9))
- mode |= FP_MODE_DEEPSLEEP;
- else if (!strncmp(argv[i], "fingerdown", 10))
- mode |= FP_MODE_FINGER_DOWN;
- else if (!strncmp(argv[i], "fingerup", 8))
- mode |= FP_MODE_FINGER_UP;
- else if (!strncmp(argv[i], "enroll", 6))
- mode |= FP_MODE_ENROLL_IMAGE | FP_MODE_ENROLL_SESSION;
- else if (!strncmp(argv[i], "match", 5))
- mode |= FP_MODE_MATCH;
- else if (!strncmp(argv[i], "reset_sensor", 12))
- mode = FP_MODE_RESET_SENSOR;
- else if (!strncmp(argv[i], "reset", 5))
- mode = 0;
- else if (!strncmp(argv[i], "maintenance", 11))
- mode |= FP_MODE_SENSOR_MAINTENANCE;
- else if (!strncmp(argv[i], "capture", 7))
- mode |= FP_MODE_CAPTURE;
- /* capture types */
- else if (!strncmp(argv[i], "vendor", 6))
- capture_type = FP_CAPTURE_VENDOR_FORMAT;
- else if (!strncmp(argv[i], "pattern0", 8))
- capture_type = FP_CAPTURE_PATTERN0;
- else if (!strncmp(argv[i], "pattern1", 8))
- capture_type = FP_CAPTURE_PATTERN1;
- else if (!strncmp(argv[i], "qual", 4))
- capture_type = FP_CAPTURE_QUALITY_TEST;
- else if (!strncmp(argv[i], "test_reset", 10))
- capture_type = FP_CAPTURE_RESET_TEST;
- }
- if (mode & FP_MODE_CAPTURE)
- mode |= capture_type << FP_MODE_CAPTURE_TYPE_SHIFT;
-
- p.mode = mode;
- rv = ec_command(EC_CMD_FP_MODE, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("FP mode: (0x%x) ", r.mode);
- if (r.mode & FP_MODE_DEEPSLEEP)
- printf("deepsleep ");
- if (r.mode & FP_MODE_FINGER_DOWN)
- printf("finger-down ");
- if (r.mode & FP_MODE_FINGER_UP)
- printf("finger-up ");
- if (r.mode & FP_MODE_ENROLL_SESSION)
- printf("enroll%s ",
- r.mode & FP_MODE_ENROLL_IMAGE ? "+image" : "");
- if (r.mode & FP_MODE_MATCH)
- printf("match ");
- if (r.mode & FP_MODE_CAPTURE)
- printf("capture ");
- printf("\n");
- return 0;
-}
-
-int cmd_fp_seed(int argc, char *argv[])
-{
- struct ec_params_fp_seed p;
- char *seed;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <seed>\n", argv[0]);
- return 1;
- }
- seed = argv[1];
- if (strlen(seed) != FP_CONTEXT_TPM_BYTES) {
- printf("Invalid seed '%s' is %zd bytes long instead of %d.\n",
- seed, strlen(seed), FP_CONTEXT_TPM_BYTES);
- return 1;
- }
- printf("Setting seed '%s'\n", seed);
- p.struct_version = FP_TEMPLATE_FORMAT_VERSION;
- memcpy(p.seed, seed, FP_CONTEXT_TPM_BYTES);
-
- return ec_command(EC_CMD_FP_SEED, 0, &p, sizeof(p), NULL, 0);
-}
-
-int cmd_fp_stats(int argc, char *argv[])
-{
- struct ec_response_fp_stats r;
- int rv;
- unsigned long long ts;
-
- rv = ec_command(EC_CMD_FP_STATS, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- ts = (uint64_t)r.overall_t0.hi << 32 | r.overall_t0.lo;
- printf("FP stats (t0=%llu us):\n", ts);
- printf("Last capture time: ");
- if (r.timestamps_invalid & FPSTATS_CAPTURE_INV)
- printf("Invalid\n");
- else
- printf("%d us\n", r.capture_time_us);
-
- printf("Last matching time: ");
- if (r.timestamps_invalid & FPSTATS_MATCHING_INV)
- printf("Invalid\n");
- else
- printf("%d us (finger: %d)\n", r.matching_time_us,
- r.template_matched);
-
- printf("Last overall time: ");
- if (r.timestamps_invalid)
- printf("Invalid\n");
- else
- printf("%d us\n", r.overall_time_us);
-
- return 0;
-}
-
-int cmd_fp_info(int argc, char *argv[])
-{
- struct ec_response_fp_info r;
- int rv;
- int cmdver = ec_cmd_version_supported(EC_CMD_FP_INFO, 1) ? 1 : 0;
- int rsize = cmdver == 1 ? sizeof(r)
- : sizeof(struct ec_response_fp_info_v0);
- uint16_t dead;
-
- rv = ec_command(EC_CMD_FP_INFO, cmdver, NULL, 0, &r, rsize);
- if (rv < 0)
- return rv;
-
- printf("Fingerprint sensor: vendor %x product %x model %x version %x\n",
- r.vendor_id, r.product_id, r.model_id, r.version);
- printf("Image: size %dx%d %d bpp\n", r.width, r.height, r.bpp);
- printf("Error flags: %s%s%s%s\n",
- r.errors & FP_ERROR_NO_IRQ ? "NO_IRQ " : "",
- r.errors & FP_ERROR_SPI_COMM ? "SPI_COMM " : "",
- r.errors & FP_ERROR_BAD_HWID ? "BAD_HWID " : "",
- r.errors & FP_ERROR_INIT_FAIL ? "INIT_FAIL " : "");
- dead = FP_ERROR_DEAD_PIXELS(r.errors);
- if (dead == FP_ERROR_DEAD_PIXELS_UNKNOWN) {
- printf("Dead pixels: UNKNOWN\n");
- } else {
- printf("Dead pixels: %u\n", dead);
- }
-
- if (cmdver == 1) {
- printf("Templates: version %d size %d count %d/%d"
- " dirty bitmap %x\n",
- r.template_version, r.template_size, r.template_valid,
- r.template_max, r.template_dirty);
- }
-
- return 0;
-}
-
-static void print_fp_enc_flags(const char *desc, uint32_t flags)
-{
- printf("%s 0x%08x", desc, flags);
- if (flags & FP_ENC_STATUS_SEED_SET)
- printf(" FPTPM_seed_set");
- printf("\n");
-}
-
-static int cmd_fp_context(int argc, char *argv[])
-{
- struct ec_params_fp_context_v1 p;
- int rv;
- int tries = 20; /* Wait at most two seconds */
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <context>\n", argv[0]);
- return -1;
- }
-
- /*
- * Note that we treat the resulting "userid" as raw byte array, so we
- * don't want to copy the NUL from the end of the string.
- */
- if (strlen(argv[1]) != sizeof(p.userid)) {
- fprintf(stderr, "Context must be exactly %zu bytes\n",
- sizeof(p.userid));
- return -1;
- }
-
- p.action = FP_CONTEXT_ASYNC;
- memcpy(p.userid, argv[1], sizeof(p.userid));
-
- rv = ec_command(EC_CMD_FP_CONTEXT, 1, &p, sizeof(p), NULL, 0);
-
- if (rv != EC_RES_SUCCESS)
- goto out;
-
- while (tries--) {
- usleep(100000);
-
- p.action = FP_CONTEXT_GET_RESULT;
- rv = ec_command(EC_CMD_FP_CONTEXT, 1, &p, sizeof(p), NULL, 0);
-
- if (rv == EC_RES_SUCCESS) {
- printf("Set context successfully\n");
- return EC_RES_SUCCESS;
- }
-
- /* Abort if EC returns an error other than EC_RES_BUSY. */
- if (rv <= -EECRESULT && rv != -EECRESULT - EC_RES_BUSY)
- goto out;
- }
-
- rv = -EECRESULT - EC_RES_TIMEOUT;
-
-out:
- fprintf(stderr, "Failed to reset context: %d\n", rv);
- return rv;
-}
-
-int cmd_fp_enc_status(int argc, char *argv[])
-{
- int rv;
- struct ec_response_fp_encryption_status resp = { 0 };
-
- rv = ec_command(EC_CMD_FP_ENC_STATUS, 0, NULL, 0, &resp, sizeof(resp));
- if (rv < 0) {
- printf("Get FP sensor encryption status failed.\n");
- } else {
- print_fp_enc_flags("FPMCU encryption status:", resp.status);
- print_fp_enc_flags("Valid flags: ",
- resp.valid_flags);
- rv = 0;
- }
- return rv;
-}
-
-int cmd_fp_frame(int argc, char *argv[])
-{
- struct ec_response_fp_info r;
- int idx = (argc == 2 && !strcasecmp(argv[1], "raw")) ?
- FP_FRAME_INDEX_RAW_IMAGE : FP_FRAME_INDEX_SIMPLE_IMAGE;
- uint8_t *buffer = (uint8_t *)(fp_download_frame(&r, idx));
- uint8_t *ptr = buffer;
- int x, y;
-
- if (!buffer) {
- fprintf(stderr, "Failed to get FP sensor frame\n");
- return -1;
- }
-
- if (idx == FP_FRAME_INDEX_RAW_IMAGE) {
- fwrite(buffer, r.frame_size, 1, stdout);
- goto frame_done;
- }
-
- /* Print 8-bpp PGM ASCII header */
- printf("P2\n%d %d\n%d\n", r.width, r.height, (1 << r.bpp) - 1);
-
- for (y = 0; y < r.height; y++) {
- for (x = 0; x < r.width; x++, ptr++)
- printf("%d ", *ptr);
- printf("\n");
- }
- printf("# END OF FILE\n");
-frame_done:
- free(buffer);
- return 0;
-}
-
-int cmd_fp_template(int argc, char *argv[])
-{
- struct ec_response_fp_info r;
- struct ec_params_fp_template *p =
- (struct ec_params_fp_template *)(ec_outbuf);
- /* TODO(b/78544921): removing 32 bits is a workaround for the MCU bug */
- int max_chunk = ec_max_outsize
- - offsetof(struct ec_params_fp_template, data) - 4;
- int idx = -1;
- char *e;
- int size;
- char *buffer = NULL;
- uint32_t offset = 0;
- int rv = 0;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s [<infile>|<index>]\n", argv[0]);
- return -1;
- }
-
- idx = strtol(argv[1], &e, 0);
- if (!(e && *e)) {
- buffer = (char *)(fp_download_frame(&r, idx + 1));
- if (!buffer) {
- fprintf(stderr, "Failed to get FP template %d\n", idx);
- return -1;
- }
- fwrite(buffer, r.template_size, 1, stdout);
- free(buffer);
- return 0;
- }
- /* not an index, is it a filename ? */
- buffer = read_file(argv[1], &size);
- if (!buffer) {
- fprintf(stderr, "Invalid parameter: %s\n", argv[1]);
- return -1;
- }
- printf("sending template from: %s (%d bytes)\n", argv[1], size);
- while (size) {
- uint32_t tlen = MIN(max_chunk, size);
-
- p->offset = offset;
- p->size = tlen;
- size -= tlen;
- if (!size)
- p->size |= FP_TEMPLATE_COMMIT;
- memcpy(p->data, buffer + offset, tlen);
- rv = ec_command(EC_CMD_FP_TEMPLATE, 0, p, tlen +
- offsetof(struct ec_params_fp_template, data),
- NULL, 0);
- if (rv < 0)
- break;
- offset += tlen;
- }
- if (rv < 0)
- fprintf(stderr, "Failed with %d\n", rv);
- else
- rv = 0;
- free(buffer);
- return rv;
-}
-
-/**
- * determine if in GFU mode or not.
- *
- * NOTE, Sends HOST commands that modify ec_outbuf contents.
- *
- * @opos return value of GFU mode object position or zero if not found
- * @port port number to query
- * @return 1 if in GFU mode, 0 if not, -1 if error
- */
-static int in_gfu_mode(int *opos, int port)
-{
- int i;
- struct ec_params_usb_pd_get_mode_request *p =
- (struct ec_params_usb_pd_get_mode_request *)ec_outbuf;
- struct ec_params_usb_pd_get_mode_response *r =
- (struct ec_params_usb_pd_get_mode_response *)ec_inbuf;
- p->port = port;
- p->svid_idx = 0;
- do {
- ec_command(EC_CMD_USB_PD_GET_AMODE, 0, p, sizeof(*p),
- ec_inbuf, ec_max_insize);
- if (!r->svid || (r->svid == USB_VID_GOOGLE))
- break;
- p->svid_idx++;
- } while (p->svid_idx < SVID_DISCOVERY_MAX);
-
- if (r->svid != USB_VID_GOOGLE) {
- fprintf(stderr, "Google VID not returned\n");
- return -1;
- }
-
- *opos = 0; /* invalid ... must be 1 thru 6 */
- for (i = 0; i < PDO_MODES; i++) {
- if (r->vdo[i] == MODE_GOOGLE_FU) {
- *opos = i + 1;
- break;
- }
- }
-
- return r->opos == *opos;
-}
-
-/**
- * Enter GFU mode.
- *
- * NOTE, Sends HOST commands that modify ec_outbuf contents.
- *
- * @port port number to enter GFU on.
- * @return 1 if entered GFU mode, 0 if not, -1 if error
- */
-static int enter_gfu_mode(int port)
-{
- int opos;
- struct ec_params_usb_pd_set_mode_request *p =
- (struct ec_params_usb_pd_set_mode_request *)ec_outbuf;
- int gfu_mode = in_gfu_mode(&opos, port);
-
- if (gfu_mode < 0) {
- fprintf(stderr, "Failed to query GFU mode support\n");
- return 0;
- } else if (!gfu_mode) {
- if (!opos) {
- fprintf(stderr, "Invalid object position %d\n", opos);
- return 0;
- }
- p->port = port;
- p->svid = USB_VID_GOOGLE;
- p->opos = opos;
- p->cmd = PD_ENTER_MODE;
-
- ec_command(EC_CMD_USB_PD_SET_AMODE, 0, p, sizeof(*p),
- NULL, 0);
- usleep(500000); /* sleep to allow time for set mode */
- gfu_mode = in_gfu_mode(&opos, port);
- }
- return gfu_mode;
-}
-
-int cmd_pd_device_info(int argc, char *argv[])
-{
- int i, rv, port;
- char *e;
- struct ec_params_usb_pd_info_request *p =
- (struct ec_params_usb_pd_info_request *)ec_outbuf;
- struct ec_params_usb_pd_rw_hash_entry *r0 =
- (struct ec_params_usb_pd_rw_hash_entry *)ec_inbuf;
- struct ec_params_usb_pd_discovery_entry *r1;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <port>\n", argv[0]);
- return -1;
- }
-
- port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- p->port = port;
- r1 = (struct ec_params_usb_pd_discovery_entry *)ec_inbuf;
- rv = ec_command(EC_CMD_USB_PD_DISCOVERY, 0, p, sizeof(*p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- if (!r1->vid)
- printf("Port:%d has no discovered device\n", port);
- else {
- printf("Port:%d ptype:%d vid:0x%04x pid:0x%04x\n", port,
- r1->ptype, r1->vid, r1->pid);
- }
-
- if (enter_gfu_mode(port) != 1) {
- fprintf(stderr, "Failed to enter GFU mode\n");
- return -1;
- }
-
- p->port = port;
- rv = ec_command(EC_CMD_USB_PD_DEV_INFO, 0, p, sizeof(*p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- if (!r0->dev_id)
- printf("Port:%d has no valid device\n", port);
- else {
- uint8_t *rwp = r0->dev_rw_hash;
- printf("Port:%d DevId:%d.%d Hash:", port,
- HW_DEV_ID_MAJ(r0->dev_id), HW_DEV_ID_MIN(r0->dev_id));
- for (i = 0; i < 5; i++) {
- printf(" 0x%02x%02x%02x%02x", rwp[3], rwp[2], rwp[1],
- rwp[0]);
- rwp += 4;
- }
- printf(" CurImg:%s\n", image_names[r0->current_image]);
- }
-
- return rv;
-}
-
-int cmd_flash_pd(int argc, char *argv[])
-{
- struct ec_params_usb_pd_fw_update *p =
- (struct ec_params_usb_pd_fw_update *)ec_outbuf;
- int i, dev_id, port;
- int rv, fsize, step = 96;
- char *e;
- char *buf;
- char *data = (char *)p + sizeof(*p);
-
- if (argc < 4) {
- fprintf(stderr, "Usage: %s <dev_id> <port> <filename>\n",
- argv[0]);
- return -1;
- }
-
- dev_id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad device ID\n");
- return -1;
- }
-
- port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- if (enter_gfu_mode(port) != 1) {
- fprintf(stderr, "Failed to enter GFU mode\n");
- return -1;
- }
-
- /* Read the input file */
- buf = read_file(argv[3], &fsize);
- if (!buf)
- return -1;
-
- /* Erase the current RW RSA signature */
- fprintf(stderr, "Erasing expected RW hash\n");
- p->dev_id = dev_id;
- p->port = port;
- p->cmd = USB_PD_FW_ERASE_SIG;
- p->size = 0;
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
-
- if (rv < 0)
- goto pd_flash_error;
-
- /* Reboot */
- fprintf(stderr, "Rebooting\n");
- p->dev_id = dev_id;
- p->port = port;
- p->cmd = USB_PD_FW_REBOOT;
- p->size = 0;
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
-
- if (rv < 0)
- goto pd_flash_error;
-
- usleep(3000000); /* 3sec to reboot and get CC line idle */
-
- /* re-enter GFU after reboot */
- if (enter_gfu_mode(port) != 1) {
- fprintf(stderr, "Failed to enter GFU mode\n");
- goto pd_flash_error;
- }
-
- /* Erase RW flash */
- fprintf(stderr, "Erasing RW flash\n");
- p->dev_id = dev_id;
- p->port = port;
- p->cmd = USB_PD_FW_FLASH_ERASE;
- p->size = 0;
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
-
- /* 3 secs should allow ample time for 2KB page erases at 40ms */
- usleep(3000000);
-
- if (rv < 0)
- goto pd_flash_error;
-
- /* Write RW flash */
- fprintf(stderr, "Writing RW flash\n");
- p->dev_id = dev_id;
- p->port = port;
- p->cmd = USB_PD_FW_FLASH_WRITE;
- p->size = step;
-
- for (i = 0; i < fsize; i += step) {
- p->size = MIN(fsize - i, step);
- memcpy(data, buf + i, p->size);
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
- if (rv < 0)
- goto pd_flash_error;
-
- /*
- * TODO(crosbug.com/p/33905) throttle so EC doesn't watchdog on
- * other tasks. Remove once issue resolved.
- */
- usleep(10000);
- }
-
- /* 100msec to guarantee writes finish */
- usleep(100000);
-
- /* Reboot into new RW */
- fprintf(stderr, "Rebooting PD into new RW\n");
- p->cmd = USB_PD_FW_REBOOT;
- p->size = 0;
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
-
- if (rv < 0)
- goto pd_flash_error;
-
- free(buf);
- fprintf(stderr, "Complete\n");
- return 0;
-
-pd_flash_error:
- free(buf);
- fprintf(stderr, "PD flash error\n");
- return -1;
-}
-
-int cmd_pd_set_amode(int argc, char *argv[])
-{
- char *e;
- struct ec_params_usb_pd_set_mode_request *p =
- (struct ec_params_usb_pd_set_mode_request *)ec_outbuf;
-
- if (argc < 5) {
- fprintf(stderr, "Usage: %s <port> <svid> <opos> <cmd>\n",
- argv[0]);
- return -1;
- }
-
- p->port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- p->svid = strtol(argv[2], &e, 0);
- if ((e && *e) || !p->svid) {
- fprintf(stderr, "Bad svid\n");
- return -1;
- }
-
- p->opos = strtol(argv[3], &e, 0);
- if ((e && *e) || !p->opos) {
- fprintf(stderr, "Bad opos\n");
- return -1;
- }
-
- p->cmd = strtol(argv[4], &e, 0);
- if ((e && *e) || (p->cmd >= PD_MODE_CMD_COUNT)) {
- fprintf(stderr, "Bad cmd\n");
- return -1;
- }
- return ec_command(EC_CMD_USB_PD_SET_AMODE, 0, p, sizeof(*p), NULL, 0);
-}
-
-int cmd_pd_get_amode(int argc, char *argv[])
-{
- int i;
- char *e;
- struct ec_params_usb_pd_get_mode_request *p =
- (struct ec_params_usb_pd_get_mode_request *)ec_outbuf;
- struct ec_params_usb_pd_get_mode_response *r =
- (struct ec_params_usb_pd_get_mode_response *)ec_inbuf;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <port>\n", argv[0]);
- return -1;
- }
-
- p->port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- p->svid_idx = 0;
- do {
- ec_command(EC_CMD_USB_PD_GET_AMODE, 0, p, sizeof(*p),
- ec_inbuf, ec_max_insize);
- if (!r->svid)
- break;
- printf("%cSVID:0x%04x ", (r->opos) ? '*' : ' ',
- r->svid);
- for (i = 0; i < PDO_MODES; i++) {
- printf("%c0x%08x ", (r->opos && (r->opos == i + 1)) ?
- '*' : ' ', r->vdo[i]);
- }
- printf("\n");
- p->svid_idx++;
- } while (p->svid_idx < SVID_DISCOVERY_MAX);
- return -1;
-}
-
-/* The I/O asm funcs exist only on x86. */
-#if defined(__i386__) || defined(__x86_64__)
-#include <sys/io.h>
-
-int cmd_serial_test(int argc, char *argv[])
-{
- const char *c = "COM2 sample serial output from host!\r\n";
-
- printf("Writing sample serial output to COM2\n");
-
- while (*c) {
- /* Wait for space in transmit FIFO */
- while (!(inb(0x2fd) & 0x20))
- ;
-
- /* Put the next character */
- outb(*c++, 0x2f8);
- }
-
- printf("done.\n");
- return 0;
-}
-
-
-int cmd_port_80_flood(int argc, char *argv[])
-{
- int i;
-
- for (i = 0; i < 256; i++)
- outb(i, 0x80);
- return 0;
-}
-#else
-int cmd_serial_test(int argc, char *argv[])
-{
- printf("x86 specific command\n");
- return -1;
-}
-
-int cmd_port_80_flood(int argc, char *argv[])
-{
- printf("x86 specific command\n");
- return -1;
-}
-#endif
-
-static void cmd_smart_discharge_usage(const char *command)
-{
- printf("Usage: %s [hours_to_zero [hibern] [cutoff]]\n", command);
- printf("\n");
- printf("Set/Get smart discharge parameters\n");
- printf("hours_to_zero: Desired hours for state of charge to zero\n");
- printf("hibern: Discharge rate in hibernation (uA)\n");
- printf("cutoff: Discharge rate in battery cutoff (uA)\n");
-}
-
-int cmd_smart_discharge(int argc, char *argv[])
-{
- struct ec_params_smart_discharge *p =
- (struct ec_params_smart_discharge *)(ec_outbuf);
- struct ec_response_smart_discharge *r =
- (struct ec_response_smart_discharge *)(ec_inbuf);
- uint32_t cap;
- char *e;
- int rv;
-
- if (argc > 1) {
- if (strcmp(argv[1], "help") == 0) {
- cmd_smart_discharge_usage(argv[0]);
- return 0;
- }
- p->flags = EC_SMART_DISCHARGE_FLAGS_SET;
- p->hours_to_zero = strtol(argv[1], &e, 0);
- if (p->hours_to_zero < 0 || (e && *e)) {
- perror("Bad value for [hours_to_zero]");
- return -1;
- }
- if (argc == 4) {
- p->drate.hibern = strtol(argv[2], &e, 0);
- if (p->drate.hibern < 0 || (e && *e)) {
- perror("Bad value for [hibern]");
- return -1;
- }
- p->drate.cutoff = strtol(argv[3], &e, 0);
- if (p->drate.cutoff < 0 || (e && *e)) {
- perror("Bad value for [cutoff]");
- return -1;
- }
- } else if (argc != 2) {
- /* If argc != 4, it has to be 2. */
- perror("Invalid number of parameters");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_SMART_DISCHARGE, 0, p, sizeof(*p),
- r, ec_max_insize);
- if (rv < 0) {
- perror("ERROR: EC_CMD_SMART_DISCHARGE failed");
- return rv;
- }
-
- cap = read_mapped_mem32(EC_MEMMAP_BATT_LFCC);
- if (!is_battery_range(cap)) {
- perror("WARN: Failed to read battery capacity");
- cap = 0;
- }
-
- printf("%-27s %5d h\n", "Hours to zero capacity:", r->hours_to_zero);
- printf("%-27s %5d mAh (%d %%)\n", "Stay-up threshold:",
- r->dzone.stayup, cap > 0 ? r->dzone.stayup * 100 / cap : -1);
- printf("%-27s %5d mAh (%d %%)\n", "Cutoff threshold:",
- r->dzone.cutoff, cap > 0 ? r->dzone.cutoff * 100 / cap : -1);
- printf("%-27s %5d uA\n", "Hibernate discharge rate:", r->drate.hibern);
- printf("%-27s %5d uA\n", "Cutoff discharge rate:", r->drate.cutoff);
-
- return 0;
-}
-
-/*
- * This boolean variable and handler are used for
- * catching signals that translate into a quit/shutdown
- * of a runtime loop.
- * This is used in cmd_stress_test.
- */
-static bool sig_quit;
-static void sig_quit_handler(int sig)
-{
- sig_quit = true;
-}
-
-int cmd_stress_test(int argc, char *argv[])
-{
- int i;
- bool reboot = false;
- time_t now;
- time_t start_time, last_update_time;
- unsigned int rand_seed = 0;
- uint64_t round = 1, attempt = 1;
- uint64_t failures = 0;
-
- const int max_sleep_usec = 1000; /* 1ms */
- const int loop_update_interval = 10000;
-
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "help") == 0) {
- printf("Usage: %s [reboot] [help]\n", argv[0]);
- printf("Stress tests the host command interface by"
- " repeatedly issuing common host commands.\n");
- printf("The intent is to expose errors in kernel<->mcu"
- " communication, such as exceeding timeouts.\n");
- printf("\n");
- printf("reboot - Reboots the target before"
- " starting the stress test.\n");
- printf(" This may force restart the host,"
- " if the main ec is the target.\n");
- return 0;
- } else if (strcmp(argv[i], "reboot") == 0) {
- reboot = true;
- } else {
- fprintf(stderr, "Error - Unknown argument '%s'\n",
- argv[i]);
- return 1;
- }
- }
-
- printf("Stress test tool version: %s %s %s\n",
- CROS_ECTOOL_VERSION, DATE, BUILDER);
-
- start_time = time(NULL);
- last_update_time = start_time;
- printf("Start time: %s\n", ctime(&start_time));
-
- if (reboot) {
- printf("Issuing ec reboot. Expect a few early failed"
- " ioctl messages.\n");
- ec_command(EC_CMD_REBOOT, 0, NULL, 0, NULL, 0);
- sleep(2);
- }
-
- sig_quit = false;
- signal(SIGINT, sig_quit_handler);
- while (!sig_quit) {
- int rv;
- struct ec_response_get_version ver_r;
- char *build_string = (char *)ec_inbuf;
- struct ec_params_flash_protect flash_p;
- struct ec_response_flash_protect flash_r;
- struct ec_params_hello hello_p;
- struct ec_response_hello hello_r;
-
- /* Request EC Version Strings */
- rv = ec_command(EC_CMD_GET_VERSION, 0,
- NULL, 0, &ver_r, sizeof(ver_r));
- if (rv < 0) {
- failures++;
- perror("ERROR: EC_CMD_GET_VERSION failed");
- }
- ver_r.version_string_ro[sizeof(ver_r.version_string_ro) - 1]
- = '\0';
- ver_r.version_string_rw[sizeof(ver_r.version_string_rw) - 1]
- = '\0';
- if (strlen(ver_r.version_string_ro) == 0) {
- failures++;
- fprintf(stderr, "RO version string is empty\n");
- }
- if (strlen(ver_r.version_string_rw) == 0) {
- failures++;
- fprintf(stderr, "RW version string is empty\n");
- }
-
- usleep(rand_r(&rand_seed) % max_sleep_usec);
-
- /* Request EC Build String */
- rv = ec_command(EC_CMD_GET_BUILD_INFO, 0,
- NULL, 0, ec_inbuf, ec_max_insize);
- if (rv < 0) {
- failures++;
- perror("ERROR: EC_CMD_GET_BUILD_INFO failed");
- }
- build_string[ec_max_insize - 1] = '\0';
- if (strlen(build_string) == 0) {
- failures++;
- fprintf(stderr, "Build string is empty\n");
- }
-
- usleep(rand_r(&rand_seed) % max_sleep_usec);
-
- /* Request Flash Protect Status */
- rv = ec_command(EC_CMD_FLASH_PROTECT, EC_VER_FLASH_PROTECT,
- &flash_p, sizeof(flash_p), &flash_r,
- sizeof(flash_r));
- if (rv < 0) {
- failures++;
- perror("ERROR: EC_CMD_FLASH_PROTECT failed");
- }
-
- usleep(rand_r(&rand_seed) % max_sleep_usec);
-
- /* Request Hello */
- hello_p.in_data = 0xa0b0c0d0;
- rv = ec_command(EC_CMD_HELLO, 0, &hello_p, sizeof(hello_p),
- &hello_r, sizeof(hello_r));
- if (rv < 0) {
- failures++;
- perror("ERROR: EC_CMD_HELLO failed");
- }
- if (hello_r.out_data != HELLO_RESP(hello_p.in_data)) {
- failures++;
- fprintf(stderr, "Hello response was invalid.\n");
- }
-
- usleep(rand_r(&rand_seed) % max_sleep_usec);
-
- if ((attempt % loop_update_interval) == 0) {
- now = time(NULL);
- printf("Update: attempt %" PRIu64 " round %" PRIu64
- " | took %.f seconds\n",
- attempt, round,
- difftime(now, last_update_time));
- last_update_time = now;
- }
-
- if (attempt++ == UINT64_MAX)
- round++;
- }
- printf("\n");
-
- now = time(NULL);
- printf("End time: %s\n", ctime(&now));
- printf("Total runtime: %.f seconds\n",
- difftime(time(NULL), start_time));
- printf("Total failures: %" PRIu64 "\n", failures);
- return 0;
-}
-
-int read_mapped_temperature(int id)
-{
- int rv;
-
- if (!read_mapped_mem8(EC_MEMMAP_THERMAL_VERSION)) {
- /*
- * The temp_sensor_init() is not called, which implies no
- * temp sensor is defined.
- */
- rv = EC_TEMP_SENSOR_NOT_PRESENT;
- } else if (id < EC_TEMP_SENSOR_ENTRIES)
- rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR + id);
- else if (read_mapped_mem8(EC_MEMMAP_THERMAL_VERSION) >= 2)
- rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR_B +
- id - EC_TEMP_SENSOR_ENTRIES);
- else {
- /* Sensor in second bank, but second bank isn't supported */
- rv = EC_TEMP_SENSOR_NOT_PRESENT;
- }
- return rv;
-}
-
-
-int cmd_temperature(int argc, char *argv[])
-{
- int rv;
- int id;
- char *e;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <sensorid> | all\n", argv[0]);
- return -1;
- }
-
- if (strcmp(argv[1], "all") == 0) {
- for (id = 0;
- id < EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES;
- id++) {
- rv = read_mapped_temperature(id);
- switch (rv) {
- case EC_TEMP_SENSOR_NOT_PRESENT:
- break;
- case EC_TEMP_SENSOR_ERROR:
- fprintf(stderr, "Sensor %d error\n", id);
- break;
- case EC_TEMP_SENSOR_NOT_POWERED:
- fprintf(stderr, "Sensor %d disabled\n", id);
- break;
- case EC_TEMP_SENSOR_NOT_CALIBRATED:
- fprintf(stderr, "Sensor %d not calibrated\n",
- id);
- break;
- default:
- printf("%d: %d K\n", id,
- rv + EC_TEMP_SENSOR_OFFSET);
- }
- }
- return 0;
- }
-
- id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad sensor ID.\n");
- return -1;
- }
-
- if (id < 0 ||
- id >= EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES) {
- printf("Sensor ID invalid.\n");
- return -1;
- }
-
- printf("Reading temperature...");
- rv = read_mapped_temperature(id);
-
- switch (rv) {
- case EC_TEMP_SENSOR_NOT_PRESENT:
- printf("Sensor not present\n");
- return -1;
- case EC_TEMP_SENSOR_ERROR:
- printf("Error\n");
- return -1;
- case EC_TEMP_SENSOR_NOT_POWERED:
- printf("Sensor disabled/unpowered\n");
- return -1;
- case EC_TEMP_SENSOR_NOT_CALIBRATED:
- fprintf(stderr, "Sensor not calibrated\n");
- return -1;
- default:
- printf("%d K\n", rv + EC_TEMP_SENSOR_OFFSET);
- return 0;
- }
-}
-
-
-int cmd_temp_sensor_info(int argc, char *argv[])
-{
- struct ec_params_temp_sensor_get_info p;
- struct ec_response_temp_sensor_get_info r;
- int rv;
- char *e;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <sensorid> | all\n", argv[0]);
- return -1;
- }
-
- if (strcmp(argv[1], "all") == 0) {
- for (p.id = 0;
- p.id < EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES;
- p.id++) {
- if (read_mapped_temperature(p.id) ==
- EC_TEMP_SENSOR_NOT_PRESENT)
- continue;
- rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- continue;
- printf("%d: %d %s\n", p.id, r.sensor_type,
- r.sensor_name);
- }
- return 0;
- }
-
- p.id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad sensor ID.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Sensor name: %s\n", r.sensor_name);
- printf("Sensor type: %d\n", r.sensor_type);
-
- return 0;
-}
-
-
-int cmd_thermal_get_threshold_v0(int argc, char *argv[])
-{
- struct ec_params_thermal_get_threshold p;
- struct ec_response_thermal_get_threshold r;
- char *e;
- int rv;
-
- if (argc != 3) {
- fprintf(stderr,
- "Usage: %s <sensortypeid> <thresholdid>\n", argv[0]);
- return -1;
- }
-
- p.sensor_type = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad sensor type ID.\n");
- return -1;
- }
-
- p.threshold_id = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad threshold ID.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Threshold %d for sensor type %d is %d K.\n",
- p.threshold_id, p.sensor_type, r.value);
-
- return 0;
-}
-
-
-int cmd_thermal_set_threshold_v0(int argc, char *argv[])
-{
- struct ec_params_thermal_set_threshold p;
- char *e;
- int rv;
-
- if (argc != 4) {
- fprintf(stderr,
- "Usage: %s <sensortypeid> <thresholdid> <value>\n",
- argv[0]);
- return -1;
- }
-
- p.sensor_type = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad sensor type ID.\n");
- return -1;
- }
-
- p.threshold_id = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad threshold ID.\n");
- return -1;
- }
-
- p.value = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad threshold value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_THERMAL_SET_THRESHOLD, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Threshold %d for sensor type %d set to %d.\n",
- p.threshold_id, p.sensor_type, p.value);
-
- return 0;
-}
-
-
-int cmd_thermal_get_threshold_v1(int argc, char *argv[])
-{
- struct ec_params_thermal_get_threshold_v1 p;
- struct ec_thermal_config r;
- struct ec_params_temp_sensor_get_info pi;
- struct ec_response_temp_sensor_get_info ri;
- int rv;
- int i;
-
- printf("sensor warn high halt fan_off fan_max name\n");
- for (i = 0; i < 99; i++) { /* number of sensors is unknown */
-
- /* ask for one */
- p.sensor_num = i;
- rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1,
- &p, sizeof(p), &r, sizeof(r));
- if (rv <= 0) /* stop on first failure */
- break;
-
- /* ask for its name, too */
- pi.id = i;
- rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0,
- &pi, sizeof(pi), &ri, sizeof(ri));
-
- /* print what we know */
- printf(" %2d %3d %3d %3d %3d %3d %s\n",
- i,
- r.temp_host[EC_TEMP_THRESH_WARN],
- r.temp_host[EC_TEMP_THRESH_HIGH],
- r.temp_host[EC_TEMP_THRESH_HALT],
- r.temp_fan_off, r.temp_fan_max,
- rv > 0 ? ri.sensor_name : "?");
- }
- if (i)
- printf("(all temps in degrees Kelvin)\n");
-
- return 0;
-}
-
-int cmd_thermal_set_threshold_v1(int argc, char *argv[])
-{
- struct ec_params_thermal_get_threshold_v1 p;
- struct ec_thermal_config r;
- struct ec_params_thermal_set_threshold_v1 s;
- int i, n, val, rv;
- char *e;
-
- if (argc < 3 || argc > 7) {
- printf("Usage: %s"
- " sensor warn [high [shutdown [fan_off [fan_max]]]]\n",
- argv[0]);
- return 1;
- }
-
- n = strtod(argv[1], &e);
- if (e && *e) {
- printf("arg %d is invalid\n", 1);
- return 1;
- }
-
- p.sensor_num = n;
- rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1,
- &p, sizeof(p), &r, sizeof(r));
- if (rv <= 0)
- return rv;
-
- s.sensor_num = n;
- s.cfg = r;
-
- for (i = 2; i < argc; i++) {
- val = strtod(argv[i], &e);
- if (e && *e) {
- printf("arg %d is invalid\n", i);
- return 1;
- }
-
- if (val < 0)
- continue;
- switch (i) {
- case 2:
- case 3:
- case 4:
- s.cfg.temp_host[i-2] = val;
- break;
- case 5:
- s.cfg.temp_fan_off = val;
- break;
- case 6:
- s.cfg.temp_fan_max = val;
- break;
- }
- }
-
- rv = ec_command(EC_CMD_THERMAL_SET_THRESHOLD, 1,
- &s, sizeof(s), NULL, 0);
-
- return rv;
-}
-
-int cmd_thermal_get_threshold(int argc, char *argv[])
-{
- if (ec_cmd_version_supported(EC_CMD_THERMAL_GET_THRESHOLD, 1))
- return cmd_thermal_get_threshold_v1(argc, argv);
- else if (ec_cmd_version_supported(EC_CMD_THERMAL_GET_THRESHOLD, 0))
- return cmd_thermal_get_threshold_v0(argc, argv);
-
- printf("I got nuthin.\n");
- return -1;
-}
-
-int cmd_thermal_set_threshold(int argc, char *argv[])
-{
- if (ec_cmd_version_supported(EC_CMD_THERMAL_SET_THRESHOLD, 1))
- return cmd_thermal_set_threshold_v1(argc, argv);
- else if (ec_cmd_version_supported(EC_CMD_THERMAL_SET_THRESHOLD, 0))
- return cmd_thermal_set_threshold_v0(argc, argv);
-
- printf("I got nuthin.\n");
- return -1;
-}
-
-
-static int get_num_fans(void)
-{
- int idx, rv;
- struct ec_response_get_features r;
-
- /*
- * iff the EC supports the GET_FEATURES,
- * check whether it has fan support enabled.
- */
- rv = ec_command(EC_CMD_GET_FEATURES, 0, NULL, 0, &r, sizeof(r));
- if (rv >= 0 && !(r.flags[0] & BIT(EC_FEATURE_PWM_FAN)))
- return 0;
-
- for (idx = 0; idx < EC_FAN_SPEED_ENTRIES; idx++) {
- rv = read_mapped_mem16(EC_MEMMAP_FAN + 2 * idx);
- if (rv == EC_FAN_SPEED_NOT_PRESENT)
- break;
- }
-
- return idx;
-}
-
-int cmd_thermal_auto_fan_ctrl(int argc, char *argv[])
-{
- int rv, num_fans;
- struct ec_params_auto_fan_ctrl_v1 p_v1;
- char *e;
- int cmdver = 1;
-
- if (!ec_cmd_version_supported(EC_CMD_THERMAL_AUTO_FAN_CTRL, cmdver)
- || (argc == 1)) {
- /* If no argument is provided then enable auto fan ctrl */
- /* for all fans by using version 0 of the host command */
-
- rv = ec_command(EC_CMD_THERMAL_AUTO_FAN_CTRL, 0,
- NULL, 0, NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Automatic fan control is now on for all fans.\n");
- return 0;
- }
-
- if (argc > 2 || !strcmp(argv[1], "help")) {
- printf("Usage: %s [idx]\n", argv[0]);
- return -1;
- }
-
- num_fans = get_num_fans();
- p_v1.fan_idx = strtol(argv[1], &e, 0);
- if ((e && *e) || (p_v1.fan_idx >= num_fans)) {
- fprintf(stderr, "Bad fan index.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_THERMAL_AUTO_FAN_CTRL, cmdver,
- &p_v1, sizeof(p_v1), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Automatic fan control is now on for fan %d\n", p_v1.fan_idx);
-
- return 0;
-}
-
-static int print_fan(int idx)
-{
- int rv = read_mapped_mem16(EC_MEMMAP_FAN + 2 * idx);
-
- switch (rv) {
- case EC_FAN_SPEED_NOT_PRESENT:
- return -1;
- case EC_FAN_SPEED_STALLED:
- printf("Fan %d stalled!\n", idx);
- break;
- default:
- printf("Fan %d RPM: %d\n", idx, rv);
- break;
- }
-
- return 0;
-}
-
-int cmd_pwm_get_num_fans(int argc, char *argv[])
-{
- int num_fans;
-
- num_fans = get_num_fans();
-
- printf("Number of fans = %d\n", num_fans);
-
- return 0;
-}
-
-int cmd_pwm_get_fan_rpm(int argc, char *argv[])
-{
- int i, num_fans;
-
- num_fans = get_num_fans();
- if (argc < 2 || !strcasecmp(argv[1], "all")) {
- /* Print all the fan speeds */
- for (i = 0; i < num_fans; i++)
- print_fan(i);
- } else {
- char *e;
- int idx;
-
- idx = strtol(argv[1], &e, 0);
- if ((e && *e) || idx < 0 || idx >= num_fans) {
- fprintf(stderr, "Bad index.\n");
- return -1;
- }
-
- print_fan(idx);
- }
-
- return 0;
-}
-
-
-int cmd_pwm_set_fan_rpm(int argc, char *argv[])
-{
- struct ec_params_pwm_set_fan_target_rpm_v1 p_v1;
- char *e;
- int rv, num_fans;
- int cmdver = 1;
-
- if (!ec_cmd_version_supported(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver)) {
- struct ec_params_pwm_set_fan_target_rpm_v0 p_v0;
-
- /* Fall back to command version 0 command */
- cmdver = 0;
-
- if (argc != 2) {
- fprintf(stderr,
- "Usage: %s <targetrpm>\n", argv[0]);
- return -1;
- }
- p_v0.rpm = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad RPM.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver,
- &p_v0, sizeof(p_v0), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan target RPM set for all fans.\n");
- return 0;
- }
-
- if (argc > 3 || (argc == 2 && !strcmp(argv[1], "help")) || argc == 1) {
- printf("Usage: %s [idx] <targetrpm>\n", argv[0]);
- printf("'%s 0 3000' - Set fan 0 RPM to 3000\n", argv[0]);
- printf("'%s 3000' - Set all fans RPM to 3000\n", argv[0]);
- return -1;
- }
-
- num_fans = get_num_fans();
- p_v1.rpm = strtol(argv[argc - 1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad RPM.\n");
- return -1;
- }
-
- if (argc == 2) {
- /* Reuse version 0 command if we're setting targetrpm
- * for all fans */
- struct ec_params_pwm_set_fan_target_rpm_v0 p_v0;
-
- cmdver = 0;
- p_v0.rpm = p_v1.rpm;
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver,
- &p_v0, sizeof(p_v0), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan target RPM set for all fans.\n");
- } else {
- p_v1.fan_idx = strtol(argv[1], &e, 0);
- if ((e && *e) || (p_v1.fan_idx >= num_fans)) {
- fprintf(stderr, "Bad fan index.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver,
- &p_v1, sizeof(p_v1), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan %d target RPM set.\n", p_v1.fan_idx);
- }
-
- return 0;
-}
-
-int cmd_pwm_get_keyboard_backlight(int argc, char *argv[])
-{
- struct ec_response_pwm_get_keyboard_backlight r;
- int rv;
-
- rv = ec_command(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- if (r.enabled == 1)
- printf("Current keyboard backlight percent: %d\n", r.percent);
- else
- printf("Keyboard backlight disabled.\n");
-
- return 0;
-}
-
-
-int cmd_pwm_set_keyboard_backlight(int argc, char *argv[])
-{
- struct ec_params_pwm_set_keyboard_backlight p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <percent>\n", argv[0]);
- return -1;
- }
- p.percent = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad percent.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Keyboard backlight set.\n");
- return 0;
-}
-
-int cmd_pwm_get_duty(int argc, char *argv[])
-{
- struct ec_params_pwm_get_duty p;
- struct ec_response_pwm_get_duty r;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <pwm_idx> | kb | disp\n", argv[0]);
- return -1;
- }
-
- if (!strcmp(argv[1], "kb")) {
- p.pwm_type = EC_PWM_TYPE_KB_LIGHT;
- p.index = 0;
- } else if (!strcmp(argv[1], "disp")) {
- p.pwm_type = EC_PWM_TYPE_DISPLAY_LIGHT;
- p.index = 0;
- } else {
- p.pwm_type = EC_PWM_TYPE_GENERIC;
- p.index = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad pwm_idx\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_PWM_GET_DUTY, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current PWM duty: %d\n", r.duty);
- return 0;
-}
-
-
-int cmd_pwm_set_duty(int argc, char *argv[])
-{
- struct ec_params_pwm_set_duty p;
- char *e;
- int rv;
-
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <pwm_idx> | kb | disp <duty>\n",
- argv[0]);
- return -1;
- }
-
- if (!strcmp(argv[1], "kb")) {
- p.pwm_type = EC_PWM_TYPE_KB_LIGHT;
- p.index = 0;
- } else if (!strcmp(argv[1], "disp")) {
- p.pwm_type = EC_PWM_TYPE_DISPLAY_LIGHT;
- p.index = 0;
- } else {
- p.pwm_type = EC_PWM_TYPE_GENERIC;
- p.index = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad pwm_idx\n");
- return -1;
- }
- }
-
- p.duty = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad duty.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_DUTY, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("PWM set.\n");
- return 0;
-}
-
-int cmd_fanduty(int argc, char *argv[])
-{
- struct ec_params_pwm_set_fan_duty_v1 p_v1;
- char *e;
- int rv, num_fans;
- int cmdver = 1;
-
- if (!ec_cmd_version_supported(EC_CMD_PWM_SET_FAN_DUTY, cmdver)) {
- struct ec_params_pwm_set_fan_duty_v0 p_v0;
-
- if (argc != 2) {
- fprintf(stderr,
- "Usage: %s <percent>\n", argv[0]);
- return -1;
- }
- p_v0.percent = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad percent arg.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, 0,
- &p_v0, sizeof(p_v0), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan duty cycle set.\n");
- return 0;
- }
-
- if (argc > 3 || (argc == 2 && !strcmp(argv[1], "help")) || argc == 1) {
- printf("Usage: %s [idx] <percent>\n", argv[0]);
- printf("'%s 0 50' - Set fan 0 duty cycle to 50 percent\n",
- argv[0]);
- printf("'%s 30' - Set all fans duty cycle to 30 percent\n",
- argv[0]);
- return -1;
- }
-
- num_fans = get_num_fans();
- p_v1.percent = strtol(argv[argc - 1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad percent arg.\n");
- return -1;
- }
-
- if (argc == 2) {
- /* Reuse version 0 command if we're setting duty cycle
- * for all fans */
- struct ec_params_pwm_set_fan_duty_v0 p_v0;
-
- cmdver = 0;
- p_v0.percent = p_v1.percent;
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, cmdver,
- &p_v0, sizeof(p_v0), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan duty cycle set for all fans.\n");
- } else {
- p_v1.fan_idx = strtol(argv[1], &e, 0);
- if ((e && *e) || (p_v1.fan_idx >= num_fans)) {
- fprintf(stderr, "Bad fan index.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, cmdver,
- &p_v1, sizeof(p_v1), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan %d duty cycle set.\n", p_v1.fan_idx);
- }
-
- return 0;
-}
-
-#define LBMSG(state) #state
-#include "lightbar_msg_list.h"
-static const char * const lightbar_cmds[] = {
- LIGHTBAR_MSG_LIST
-};
-#undef LBMSG
-
-/* Size of field <FLD> in structure <ST> */
-#define ST_FLD_SIZE(ST, FLD) sizeof(((struct ST *)0)->FLD)
-
-#define ST_CMD_SIZE ST_FLD_SIZE(ec_params_lightbar, cmd)
-#define ST_PRM_SIZE(SUBCMD) \
- (ST_CMD_SIZE + ST_FLD_SIZE(ec_params_lightbar, SUBCMD))
-#define ST_RSP_SIZE(SUBCMD) ST_FLD_SIZE(ec_response_lightbar, SUBCMD)
-
-static const struct {
- uint8_t insize;
- uint8_t outsize;
-} lb_command_paramcount[] = {
- { ST_CMD_SIZE, ST_RSP_SIZE(dump) },
- { ST_CMD_SIZE, 0 },
- { ST_CMD_SIZE, 0 },
- { ST_CMD_SIZE, 0 },
- { ST_PRM_SIZE(set_brightness), 0},
- { ST_PRM_SIZE(seq), 0},
- { ST_PRM_SIZE(reg), 0},
- { ST_PRM_SIZE(set_rgb), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_seq) },
- { ST_PRM_SIZE(demo), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v0) },
- { ST_PRM_SIZE(set_params_v0), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(version) },
- { ST_CMD_SIZE, ST_RSP_SIZE(get_brightness) },
- { ST_PRM_SIZE(get_rgb), ST_RSP_SIZE(get_rgb) },
- { ST_CMD_SIZE, ST_RSP_SIZE(get_demo) },
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v1) },
- { ST_PRM_SIZE(set_params_v1), 0},
- { ST_PRM_SIZE(set_program), 0},
- { ST_PRM_SIZE(manual_suspend_ctrl), 0},
- { ST_CMD_SIZE, 0 },
- { ST_CMD_SIZE, 0 },
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_timing) },
- { ST_PRM_SIZE(set_v2par_timing), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_tap) },
- { ST_PRM_SIZE(set_v2par_tap), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_osc) },
- { ST_PRM_SIZE(set_v2par_osc), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_bright) },
- { ST_PRM_SIZE(set_v2par_bright), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_thlds) },
- { ST_PRM_SIZE(set_v2par_thlds), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_colors) },
- { ST_PRM_SIZE(set_v2par_colors), 0},
-};
-BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS);
-
-#undef ST_CMD_SIZE
-#undef ST_PRM_SIZE
-#undef ST_RSP_SIZE
-
-static int lb_help(const char *cmd)
-{
- printf("Usage:\n");
- printf(" %s - dump all regs\n", cmd);
- printf(" %s off - enter standby\n", cmd);
- printf(" %s on - leave standby\n", cmd);
- printf(" %s init - load default vals\n", cmd);
- printf(" %s brightness [NUM] - get/set intensity(0-ff)\n", cmd);
- printf(" %s seq [NUM|SEQUENCE] - run given pattern"
- " (no arg for list)\n", cmd);
- printf(" %s CTRL REG VAL - set LED controller regs\n", cmd);
- printf(" %s LED RED GREEN BLUE - set color manually"
- " (LED=4 for all)\n", cmd);
- printf(" %s LED - get current LED color\n", cmd);
- printf(" %s demo [0|1] - turn demo mode on & off\n", cmd);
- printf(" %s params [setfile] - get params"
- " (or set from file)\n", cmd);
- printf(" %s params2 group [setfile] - get params by group\n"
- " (or set from file)\n", cmd);
- printf(" %s program file - load program from file\n", cmd);
- return 0;
-}
-
-static uint8_t lb_find_msg_by_name(const char *str)
-{
- uint8_t i;
- for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++)
- if (!strcasecmp(str, lightbar_cmds[i]))
- return i;
-
- return LIGHTBAR_NUM_SEQUENCES;
-}
-
-static int lb_do_cmd(enum lightbar_command cmd,
- struct ec_params_lightbar *in,
- struct ec_response_lightbar *out)
-{
- int rv;
- in->cmd = cmd;
- rv = ec_command(EC_CMD_LIGHTBAR_CMD, 0,
- in, lb_command_paramcount[cmd].insize,
- out, lb_command_paramcount[cmd].outsize);
- return (rv < 0 ? rv : 0);
-}
-
-static int lb_show_msg_names(void)
-{
- int i, current_state;
- struct ec_params_lightbar param;
- struct ec_response_lightbar resp;
-
- i = lb_do_cmd(LIGHTBAR_CMD_GET_SEQ, &param, &resp);
- if (i < 0)
- return i;
- current_state = resp.get_seq.num;
-
- printf("sequence names:");
- for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++)
- printf(" %s", lightbar_cmds[i]);
- printf("\nCurrent = 0x%x %s\n", current_state,
- lightbar_cmds[current_state]);
-
- return 0;
-}
-
-static int lb_read_params_v0_from_file(const char *filename,
- struct lightbar_params_v0 *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
- int i;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
-
- /* Do it */
- READ(1); p->google_ramp_up = val[0];
- READ(1); p->google_ramp_down = val[0];
- READ(1); p->s3s0_ramp_up = val[0];
- READ(1); p->s0_tick_delay[0] = val[0];
- READ(1); p->s0_tick_delay[1] = val[0];
- READ(1); p->s0a_tick_delay[0] = val[0];
- READ(1); p->s0a_tick_delay[1] = val[0];
- READ(1); p->s0s3_ramp_down = val[0];
- READ(1); p->s3_sleep_for = val[0];
- READ(1); p->s3_ramp_up = val[0];
- READ(1); p->s3_ramp_down = val[0];
- READ(1); p->new_s0 = val[0];
-
- READ(2);
- p->osc_min[0] = val[0];
- p->osc_min[1] = val[1];
- READ(2);
- p->osc_max[0] = val[0];
- p->osc_max[1] = val[1];
- READ(2);
- p->w_ofs[0] = val[0];
- p->w_ofs[1] = val[1];
-
- READ(2);
- p->bright_bl_off_fixed[0] = val[0];
- p->bright_bl_off_fixed[1] = val[1];
-
- READ(2);
- p->bright_bl_on_min[0] = val[0];
- p->bright_bl_on_min[1] = val[1];
-
- READ(2);
- p->bright_bl_on_max[0] = val[0];
- p->bright_bl_on_max[1] = val[1];
-
- READ(3);
- p->battery_threshold[0] = val[0];
- p->battery_threshold[1] = val[1];
- p->battery_threshold[2] = val[2];
-
- READ(4);
- p->s0_idx[0][0] = val[0];
- p->s0_idx[0][1] = val[1];
- p->s0_idx[0][2] = val[2];
- p->s0_idx[0][3] = val[3];
-
- READ(4);
- p->s0_idx[1][0] = val[0];
- p->s0_idx[1][1] = val[1];
- p->s0_idx[1][2] = val[2];
- p->s0_idx[1][3] = val[3];
-
- READ(4);
- p->s3_idx[0][0] = val[0];
- p->s3_idx[0][1] = val[1];
- p->s3_idx[0][2] = val[2];
- p->s3_idx[0][3] = val[3];
-
- READ(4);
- p->s3_idx[1][0] = val[0];
- p->s3_idx[1][1] = val[1];
- p->s3_idx[1][2] = val[2];
- p->s3_idx[1][3] = val[3];
-
- for (i = 0; i < ARRAY_SIZE(p->color); i++) {
- READ(3);
- p->color[i].r = val[0];
- p->color[i].g = val[1];
- p->color[i].b = val[2];
- }
-
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static void lb_show_params_v0(const struct lightbar_params_v0 *p)
-{
- int i;
-
- printf("%d\t\t# .google_ramp_up\n", p->google_ramp_up);
- printf("%d\t\t# .google_ramp_down\n", p->google_ramp_down);
- printf("%d\t\t# .s3s0_ramp_up\n", p->s3s0_ramp_up);
- printf("%d\t\t# .s0_tick_delay (battery)\n", p->s0_tick_delay[0]);
- printf("%d\t\t# .s0_tick_delay (AC)\n", p->s0_tick_delay[1]);
- printf("%d\t\t# .s0a_tick_delay (battery)\n", p->s0a_tick_delay[0]);
- printf("%d\t\t# .s0a_tick_delay (AC)\n", p->s0a_tick_delay[1]);
- printf("%d\t\t# .s0s3_ramp_down\n", p->s0s3_ramp_down);
- printf("%d\t# .s3_sleep_for\n", p->s3_sleep_for);
- printf("%d\t\t# .s3_ramp_up\n", p->s3_ramp_up);
- printf("%d\t\t# .s3_ramp_down\n", p->s3_ramp_down);
- printf("%d\t\t# .new_s0\n", p->new_s0);
- printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n",
- p->osc_min[0], p->osc_min[1]);
- printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n",
- p->osc_max[0], p->osc_max[1]);
- printf("%d %d\t\t# .w_ofs (battery, AC)\n",
- p->w_ofs[0], p->w_ofs[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n",
- p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n",
- p->bright_bl_on_min[0], p->bright_bl_on_min[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n",
- p->bright_bl_on_max[0], p->bright_bl_on_max[1]);
- printf("%d %d %d\t\t# .battery_threshold\n",
- p->battery_threshold[0],
- p->battery_threshold[1],
- p->battery_threshold[2]);
- printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n",
- p->s0_idx[0][0], p->s0_idx[0][1],
- p->s0_idx[0][2], p->s0_idx[0][3]);
- printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n",
- p->s0_idx[1][0], p->s0_idx[1][1],
- p->s0_idx[1][2], p->s0_idx[1][3]);
- printf("%d %d %d %d\t# .s3_idx[] (battery)\n",
- p->s3_idx[0][0], p->s3_idx[0][1],
- p->s3_idx[0][2], p->s3_idx[0][3]);
- printf("%d %d %d %d\t# .s3_idx[] (AC)\n",
- p->s3_idx[1][0], p->s3_idx[1][1],
- p->s3_idx[1][2], p->s3_idx[1][3]);
- for (i = 0; i < ARRAY_SIZE(p->color); i++)
- printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n",
- p->color[i].r,
- p->color[i].g,
- p->color[i].b, i);
-}
-
-static int lb_read_params_v1_from_file(const char *filename,
- struct lightbar_params_v1 *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
- int i;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
-
- /* Do it */
- READ(1); p->google_ramp_up = val[0];
- READ(1); p->google_ramp_down = val[0];
- READ(1); p->s3s0_ramp_up = val[0];
- READ(1); p->s0_tick_delay[0] = val[0];
- READ(1); p->s0_tick_delay[1] = val[0];
- READ(1); p->s0a_tick_delay[0] = val[0];
- READ(1); p->s0a_tick_delay[1] = val[0];
- READ(1); p->s0s3_ramp_down = val[0];
- READ(1); p->s3_sleep_for = val[0];
- READ(1); p->s3_ramp_up = val[0];
- READ(1); p->s3_ramp_down = val[0];
- READ(1); p->tap_tick_delay = val[0];
- READ(1); p->tap_gate_delay = val[0];
- READ(1); p->tap_display_time = val[0];
-
- READ(1); p->tap_pct_red = val[0];
- READ(1); p->tap_pct_green = val[0];
- READ(1); p->tap_seg_min_on = val[0];
- READ(1); p->tap_seg_max_on = val[0];
- READ(1); p->tap_seg_osc = val[0];
- READ(3);
- p->tap_idx[0] = val[0];
- p->tap_idx[1] = val[1];
- p->tap_idx[2] = val[2];
-
- READ(2);
- p->osc_min[0] = val[0];
- p->osc_min[1] = val[1];
- READ(2);
- p->osc_max[0] = val[0];
- p->osc_max[1] = val[1];
- READ(2);
- p->w_ofs[0] = val[0];
- p->w_ofs[1] = val[1];
-
- READ(2);
- p->bright_bl_off_fixed[0] = val[0];
- p->bright_bl_off_fixed[1] = val[1];
-
- READ(2);
- p->bright_bl_on_min[0] = val[0];
- p->bright_bl_on_min[1] = val[1];
-
- READ(2);
- p->bright_bl_on_max[0] = val[0];
- p->bright_bl_on_max[1] = val[1];
-
- READ(3);
- p->battery_threshold[0] = val[0];
- p->battery_threshold[1] = val[1];
- p->battery_threshold[2] = val[2];
-
- READ(4);
- p->s0_idx[0][0] = val[0];
- p->s0_idx[0][1] = val[1];
- p->s0_idx[0][2] = val[2];
- p->s0_idx[0][3] = val[3];
-
- READ(4);
- p->s0_idx[1][0] = val[0];
- p->s0_idx[1][1] = val[1];
- p->s0_idx[1][2] = val[2];
- p->s0_idx[1][3] = val[3];
-
- READ(4);
- p->s3_idx[0][0] = val[0];
- p->s3_idx[0][1] = val[1];
- p->s3_idx[0][2] = val[2];
- p->s3_idx[0][3] = val[3];
-
- READ(4);
- p->s3_idx[1][0] = val[0];
- p->s3_idx[1][1] = val[1];
- p->s3_idx[1][2] = val[2];
- p->s3_idx[1][3] = val[3];
-
- for (i = 0; i < ARRAY_SIZE(p->color); i++) {
- READ(3);
- p->color[i].r = val[0];
- p->color[i].g = val[1];
- p->color[i].b = val[2];
- }
-
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static void lb_show_params_v1(const struct lightbar_params_v1 *p)
-{
- int i;
-
- printf("%d\t\t# .google_ramp_up\n", p->google_ramp_up);
- printf("%d\t\t# .google_ramp_down\n", p->google_ramp_down);
- printf("%d\t\t# .s3s0_ramp_up\n", p->s3s0_ramp_up);
- printf("%d\t\t# .s0_tick_delay (battery)\n", p->s0_tick_delay[0]);
- printf("%d\t\t# .s0_tick_delay (AC)\n", p->s0_tick_delay[1]);
- printf("%d\t\t# .s0a_tick_delay (battery)\n", p->s0a_tick_delay[0]);
- printf("%d\t\t# .s0a_tick_delay (AC)\n", p->s0a_tick_delay[1]);
- printf("%d\t\t# .s0s3_ramp_down\n", p->s0s3_ramp_down);
- printf("%d\t\t# .s3_sleep_for\n", p->s3_sleep_for);
- printf("%d\t\t# .s3_ramp_up\n", p->s3_ramp_up);
- printf("%d\t\t# .s3_ramp_down\n", p->s3_ramp_down);
- printf("%d\t\t# .tap_tick_delay\n", p->tap_tick_delay);
- printf("%d\t\t# .tap_gate_delay\n", p->tap_gate_delay);
- printf("%d\t\t# .tap_display_time\n", p->tap_display_time);
- printf("%d\t\t# .tap_pct_red\n", p->tap_pct_red);
- printf("%d\t\t# .tap_pct_green\n", p->tap_pct_green);
- printf("%d\t\t# .tap_seg_min_on\n", p->tap_seg_min_on);
- printf("%d\t\t# .tap_seg_max_on\n", p->tap_seg_max_on);
- printf("%d\t\t# .tap_seg_osc\n", p->tap_seg_osc);
- printf("%d %d %d\t\t# .tap_idx\n",
- p->tap_idx[0], p->tap_idx[1], p->tap_idx[2]);
- printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n",
- p->osc_min[0], p->osc_min[1]);
- printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n",
- p->osc_max[0], p->osc_max[1]);
- printf("%d %d\t\t# .w_ofs (battery, AC)\n",
- p->w_ofs[0], p->w_ofs[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n",
- p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n",
- p->bright_bl_on_min[0], p->bright_bl_on_min[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n",
- p->bright_bl_on_max[0], p->bright_bl_on_max[1]);
- printf("%d %d %d\t# .battery_threshold\n",
- p->battery_threshold[0],
- p->battery_threshold[1],
- p->battery_threshold[2]);
- printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n",
- p->s0_idx[0][0], p->s0_idx[0][1],
- p->s0_idx[0][2], p->s0_idx[0][3]);
- printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n",
- p->s0_idx[1][0], p->s0_idx[1][1],
- p->s0_idx[1][2], p->s0_idx[1][3]);
- printf("%d %d %d %d\t# .s3_idx[] (battery)\n",
- p->s3_idx[0][0], p->s3_idx[0][1],
- p->s3_idx[0][2], p->s3_idx[0][3]);
- printf("%d %d %d %d\t# .s3_idx[] (AC)\n",
- p->s3_idx[1][0], p->s3_idx[1][1],
- p->s3_idx[1][2], p->s3_idx[1][3]);
- for (i = 0; i < ARRAY_SIZE(p->color); i++)
- printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n",
- p->color[i].r,
- p->color[i].g,
- p->color[i].b, i);
-}
-
-static int lb_rd_timing_v2par_from_file(const char *filename,
- struct lightbar_params_v2_timing *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(1); p->google_ramp_up = val[0];
- READ(1); p->google_ramp_down = val[0];
- READ(1); p->s3s0_ramp_up = val[0];
- READ(1); p->s0_tick_delay[0] = val[0];
- READ(1); p->s0_tick_delay[1] = val[0];
- READ(1); p->s0a_tick_delay[0] = val[0];
- READ(1); p->s0a_tick_delay[1] = val[0];
- READ(1); p->s0s3_ramp_down = val[0];
- READ(1); p->s3_sleep_for = val[0];
- READ(1); p->s3_ramp_up = val[0];
- READ(1); p->s3_ramp_down = val[0];
- READ(1); p->tap_tick_delay = val[0];
- READ(1); p->tap_gate_delay = val[0];
- READ(1); p->tap_display_time = val[0];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_tap_v2par_from_file(const char *filename,
- struct lightbar_params_v2_tap *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(1); p->tap_pct_red = val[0];
- READ(1); p->tap_pct_green = val[0];
- READ(1); p->tap_seg_min_on = val[0];
- READ(1); p->tap_seg_max_on = val[0];
- READ(1); p->tap_seg_osc = val[0];
- READ(3);
- p->tap_idx[0] = val[0];
- p->tap_idx[1] = val[1];
- p->tap_idx[2] = val[2];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_osc_v2par_from_file(const char *filename,
- struct lightbar_params_v2_oscillation *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(2);
- p->osc_min[0] = val[0];
- p->osc_min[1] = val[1];
- READ(2);
- p->osc_max[0] = val[0];
- p->osc_max[1] = val[1];
- READ(2);
- p->w_ofs[0] = val[0];
- p->w_ofs[1] = val[1];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_bright_v2par_from_file(const char *filename,
- struct lightbar_params_v2_brightness *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(2);
- p->bright_bl_off_fixed[0] = val[0];
- p->bright_bl_off_fixed[1] = val[1];
-
- READ(2);
- p->bright_bl_on_min[0] = val[0];
- p->bright_bl_on_min[1] = val[1];
-
- READ(2);
- p->bright_bl_on_max[0] = val[0];
- p->bright_bl_on_max[1] = val[1];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_thlds_v2par_from_file(const char *filename,
- struct lightbar_params_v2_thresholds *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(3);
- p->battery_threshold[0] = val[0];
- p->battery_threshold[1] = val[1];
- p->battery_threshold[2] = val[2];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_colors_v2par_from_file(const char *filename,
- struct lightbar_params_v2_colors *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
- int i;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(4);
- p->s0_idx[0][0] = val[0];
- p->s0_idx[0][1] = val[1];
- p->s0_idx[0][2] = val[2];
- p->s0_idx[0][3] = val[3];
-
- READ(4);
- p->s0_idx[1][0] = val[0];
- p->s0_idx[1][1] = val[1];
- p->s0_idx[1][2] = val[2];
- p->s0_idx[1][3] = val[3];
-
- READ(4);
- p->s3_idx[0][0] = val[0];
- p->s3_idx[0][1] = val[1];
- p->s3_idx[0][2] = val[2];
- p->s3_idx[0][3] = val[3];
-
- READ(4);
- p->s3_idx[1][0] = val[0];
- p->s3_idx[1][1] = val[1];
- p->s3_idx[1][2] = val[2];
- p->s3_idx[1][3] = val[3];
- for (i = 0; i < ARRAY_SIZE(p->color); i++) {
- READ(3);
- p->color[i].r = val[0];
- p->color[i].g = val[1];
- p->color[i].b = val[2];
- }
-
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static void lb_show_v2par_timing(const struct lightbar_params_v2_timing *p)
-{
- printf("%d\t\t# .google_ramp_up\n", p->google_ramp_up);
- printf("%d\t\t# .google_ramp_down\n", p->google_ramp_down);
- printf("%d\t\t# .s3s0_ramp_up\n", p->s3s0_ramp_up);
- printf("%d\t\t# .s0_tick_delay (battery)\n", p->s0_tick_delay[0]);
- printf("%d\t\t# .s0_tick_delay (AC)\n", p->s0_tick_delay[1]);
- printf("%d\t\t# .s0a_tick_delay (battery)\n", p->s0a_tick_delay[0]);
- printf("%d\t\t# .s0a_tick_delay (AC)\n", p->s0a_tick_delay[1]);
- printf("%d\t\t# .s0s3_ramp_down\n", p->s0s3_ramp_down);
- printf("%d\t\t# .s3_sleep_for\n", p->s3_sleep_for);
- printf("%d\t\t# .s3_ramp_up\n", p->s3_ramp_up);
- printf("%d\t\t# .s3_ramp_down\n", p->s3_ramp_down);
- printf("%d\t\t# .tap_tick_delay\n", p->tap_tick_delay);
- printf("%d\t\t# .tap_gate_delay\n", p->tap_gate_delay);
- printf("%d\t\t# .tap_display_time\n", p->tap_display_time);
-}
-
-static void lb_show_v2par_tap(const struct lightbar_params_v2_tap *p)
-{
- printf("%d\t\t# .tap_pct_red\n", p->tap_pct_red);
- printf("%d\t\t# .tap_pct_green\n", p->tap_pct_green);
- printf("%d\t\t# .tap_seg_min_on\n", p->tap_seg_min_on);
- printf("%d\t\t# .tap_seg_max_on\n", p->tap_seg_max_on);
- printf("%d\t\t# .tap_seg_osc\n", p->tap_seg_osc);
- printf("%d %d %d\t\t# .tap_idx\n",
- p->tap_idx[0], p->tap_idx[1], p->tap_idx[2]);
-}
-
-static void lb_show_v2par_osc(const struct lightbar_params_v2_oscillation *p)
-{
- printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n",
- p->osc_min[0], p->osc_min[1]);
- printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n",
- p->osc_max[0], p->osc_max[1]);
- printf("%d %d\t\t# .w_ofs (battery, AC)\n",
- p->w_ofs[0], p->w_ofs[1]);
-}
-
-static void lb_show_v2par_bright(const struct lightbar_params_v2_brightness *p)
-{
- printf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n",
- p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n",
- p->bright_bl_on_min[0], p->bright_bl_on_min[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n",
- p->bright_bl_on_max[0], p->bright_bl_on_max[1]);
-}
-
-static void lb_show_v2par_thlds(const struct lightbar_params_v2_thresholds *p)
-{
- printf("%d %d %d\t# .battery_threshold\n",
- p->battery_threshold[0],
- p->battery_threshold[1],
- p->battery_threshold[2]);
-}
-
-static void lb_show_v2par_colors(const struct lightbar_params_v2_colors *p)
-{
- int i;
-
- printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n",
- p->s0_idx[0][0], p->s0_idx[0][1],
- p->s0_idx[0][2], p->s0_idx[0][3]);
- printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n",
- p->s0_idx[1][0], p->s0_idx[1][1],
- p->s0_idx[1][2], p->s0_idx[1][3]);
- printf("%d %d %d %d\t# .s3_idx[] (battery)\n",
- p->s3_idx[0][0], p->s3_idx[0][1],
- p->s3_idx[0][2], p->s3_idx[0][3]);
- printf("%d %d %d %d\t# .s3_idx[] (AC)\n",
- p->s3_idx[1][0], p->s3_idx[1][1],
- p->s3_idx[1][2], p->s3_idx[1][3]);
-
- for (i = 0; i < ARRAY_SIZE(p->color); i++)
- printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n",
- p->color[i].r,
- p->color[i].g,
- p->color[i].b, i);
-}
-
-static int lb_load_program(const char *filename, struct lightbar_program *prog)
-{
- FILE *fp;
- size_t got;
- int rc;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- rc = fseek(fp, 0, SEEK_END);
- if (rc) {
- fprintf(stderr, "Couldn't find end of file %s",
- filename);
- fclose(fp);
- return 1;
- }
- rc = (int) ftell(fp);
- if (rc > EC_LB_PROG_LEN) {
- fprintf(stderr, "File %s is too long, aborting\n", filename);
- fclose(fp);
- return 1;
- }
- rewind(fp);
-
- memset(prog->data, 0, EC_LB_PROG_LEN);
- got = fread(prog->data, 1, EC_LB_PROG_LEN, fp);
- if (rc != got)
- fprintf(stderr, "Warning: did not read entire file\n");
- prog->size = got;
- fclose(fp);
- return 0;
-}
-
-static int cmd_lightbar_params_v0(int argc, char **argv)
-{
- struct ec_params_lightbar param;
- struct ec_response_lightbar resp;
- int r;
-
- if (argc > 2) {
- r = lb_read_params_v0_from_file(argv[2],
- &param.set_params_v0);
- if (r)
- return r;
- return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V0,
- &param, &resp);
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V0, &param, &resp);
- if (!r)
- lb_show_params_v0(&resp.get_params_v0);
- return r;
-}
-
-static int cmd_lightbar_params_v1(int argc, char **argv)
-{
- struct ec_params_lightbar param;
- struct ec_response_lightbar resp;
- int r;
-
- if (argc > 2) {
- r = lb_read_params_v1_from_file(argv[2],
- &param.set_params_v1);
- if (r)
- return r;
- return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V1,
- &param, &resp);
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V1, &param, &resp);
- if (!r)
- lb_show_params_v1(&resp.get_params_v1);
- return r;
-}
-
-static void lb_param_v2_help(void)
-{
- printf("Usage:\n");
- printf("lightbar params2 group [setfile]\n");
- printf("group list:\n");
- printf(" timing\n");
- printf(" tap\n");
- printf(" oscillation\n");
- printf(" brightness\n");
- printf(" thresholds\n");
- printf(" colors\n");
-
- return;
-}
-
-static int cmd_lightbar_params_v2(int argc, char **argv)
-{
- struct ec_params_lightbar p;
- struct ec_response_lightbar resp;
- int r = 0;
- int set = 0;
-
- memset(&p, 0, sizeof(struct ec_params_lightbar));
- memset(&resp, 0, sizeof(struct ec_response_lightbar));
-
- if (argc < 3) {
- lb_param_v2_help();
- return 1;
- }
-
- /* Set new params if provided with a setfile */
- if (argc > 3)
- set = 1;
-
- /* Show selected v2 params */
- if (!strncasecmp(argv[2], "timing", 6)) {
- if (set) {
- r = lb_rd_timing_v2par_from_file(argv[3],
- &p.set_v2par_timing);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_TIMING,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_TIMING, &p, &resp);
- if (r)
- return r;
- lb_show_v2par_timing(&resp.get_params_v2_timing);
- } else if (!strcasecmp(argv[2], "tap")) {
- if (set) {
- r = lb_rd_tap_v2par_from_file(argv[3],
- &p.set_v2par_tap);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_TAP,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_TAP, &p, &resp);
- if (r)
- return r;
- lb_show_v2par_tap(&resp.get_params_v2_tap);
- } else if (!strncasecmp(argv[2], "oscillation", 11)) {
- if (set) {
- r = lb_rd_osc_v2par_from_file(argv[3],
- &p.set_v2par_osc);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_OSCILLATION,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_OSCILLATION, &p,
- &resp);
- if (r)
- return r;
- lb_show_v2par_osc(&resp.get_params_v2_osc);
- } else if (!strncasecmp(argv[2], "brightness", 10)) {
- if (set) {
- r = lb_rd_bright_v2par_from_file(argv[3],
- &p.set_v2par_bright);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_BRIGHTNESS,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_BRIGHTNESS, &p,
- &resp);
- if (r)
- return r;
- lb_show_v2par_bright(&resp.get_params_v2_bright);
- } else if (!strncasecmp(argv[2], "thresholds", 10)) {
- if (set) {
- r = lb_rd_thlds_v2par_from_file(argv[3],
- &p.set_v2par_thlds);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_THRESHOLDS,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_THRESHOLDS, &p,
- &resp);
- if (r)
- return r;
- lb_show_v2par_thlds(&resp.get_params_v2_thlds);
- } else if (!strncasecmp(argv[2], "colors", 6)) {
- if (set) {
- r = lb_rd_colors_v2par_from_file(argv[3],
- &p.set_v2par_colors);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_COLORS,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_COLORS, &p, &resp);
- if (r)
- return r;
- lb_show_v2par_colors(&resp.get_params_v2_colors);
- } else {
- lb_param_v2_help();
- }
-
- return r;
-}
-
-static int cmd_lightbar(int argc, char **argv)
-{
- int i, r;
- struct ec_params_lightbar param;
- struct ec_response_lightbar resp;
-
- if (1 == argc) { /* no args = dump 'em all */
- r = lb_do_cmd(LIGHTBAR_CMD_DUMP, &param, &resp);
- if (r)
- return r;
- for (i = 0; i < ARRAY_SIZE(resp.dump.vals); i++) {
- printf(" %02x %02x %02x\n",
- resp.dump.vals[i].reg,
- resp.dump.vals[i].ic0,
- resp.dump.vals[i].ic1);
- }
- return 0;
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "init"))
- return lb_do_cmd(LIGHTBAR_CMD_INIT, &param, &resp);
-
- if (argc == 2 && !strcasecmp(argv[1], "off"))
- return lb_do_cmd(LIGHTBAR_CMD_OFF, &param, &resp);
-
- if (argc == 2 && !strcasecmp(argv[1], "on"))
- return lb_do_cmd(LIGHTBAR_CMD_ON, &param, &resp);
-
- if (!strcasecmp(argv[1], "params0"))
- return cmd_lightbar_params_v0(argc, argv);
-
- if (!strcasecmp(argv[1], "params1"))
- return cmd_lightbar_params_v1(argc, argv);
-
- if (!strcasecmp(argv[1], "params2"))
- return cmd_lightbar_params_v2(argc, argv);
-
- if (!strcasecmp(argv[1], "params")) {
- /* Just try them both */
- fprintf(stderr, "trying params1 ...\n");
- if (0 == cmd_lightbar_params_v1(argc, argv))
- return 0;
- fprintf(stderr, "trying params0 ...\n");
- return cmd_lightbar_params_v0(argc, argv);
- }
-
- if (!strcasecmp(argv[1], "version")) {
- r = lb_do_cmd(LIGHTBAR_CMD_VERSION, &param, &resp);
- if (!r)
- printf("version %d flags 0x%x\n",
- resp.version.num, resp.version.flags);
- return r;
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "brightness")) {
- char *e;
- int rv;
- if (argc > 2) {
- param.set_brightness.num = 0xff &
- strtoull(argv[2], &e, 16);
- return lb_do_cmd(LIGHTBAR_CMD_SET_BRIGHTNESS,
- &param, &resp);
- }
- rv = lb_do_cmd(LIGHTBAR_CMD_GET_BRIGHTNESS,
- &param, &resp);
- if (rv)
- return rv;
- printf("%02x\n", resp.get_brightness.num);
- return 0;
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "demo")) {
- int rv;
- if (argc > 2) {
- if (!strcasecmp(argv[2], "on") || argv[2][0] == '1')
- param.demo.num = 1;
- else if (!strcasecmp(argv[2], "off") ||
- argv[2][0] == '0')
- param.demo.num = 0;
- else {
- fprintf(stderr, "Invalid arg\n");
- return -1;
- }
- return lb_do_cmd(LIGHTBAR_CMD_DEMO, &param, &resp);
- }
-
- rv = lb_do_cmd(LIGHTBAR_CMD_GET_DEMO, &param, &resp);
- if (rv)
- return rv;
- printf("%s\n", resp.get_demo.num ? "on" : "off");
- return 0;
- }
-
- if (argc >= 2 && !strcasecmp(argv[1], "seq")) {
- char *e;
- uint8_t num;
- if (argc == 2)
- return lb_show_msg_names();
- num = 0xff & strtoull(argv[2], &e, 16);
- if (e && *e)
- num = lb_find_msg_by_name(argv[2]);
- if (num >= LIGHTBAR_NUM_SEQUENCES) {
- fprintf(stderr, "Invalid arg\n");
- return -1;
- }
- param.seq.num = num;
- return lb_do_cmd(LIGHTBAR_CMD_SEQ, &param, &resp);
- }
-
- if (argc >= 3 && !strcasecmp(argv[1], "program")) {
- lb_load_program(argv[2], &param.set_program);
- return lb_do_cmd(LIGHTBAR_CMD_SET_PROGRAM, &param, &resp);
- }
-
- if (argc == 4) {
- char *e;
- param.reg.ctrl = 0xff & strtoull(argv[1], &e, 16);
- param.reg.reg = 0xff & strtoull(argv[2], &e, 16);
- param.reg.value = 0xff & strtoull(argv[3], &e, 16);
- return lb_do_cmd(LIGHTBAR_CMD_REG, &param, &resp);
- }
-
- if (argc == 5) {
- char *e;
- param.set_rgb.led = strtoull(argv[1], &e, 16);
- param.set_rgb.red = strtoull(argv[2], &e, 16);
- param.set_rgb.green = strtoull(argv[3], &e, 16);
- param.set_rgb.blue = strtoull(argv[4], &e, 16);
- return lb_do_cmd(LIGHTBAR_CMD_SET_RGB, &param, &resp);
- }
-
- /* Only thing left is to try to read an LED value */
- if (argc == 2) {
- char *e;
- param.get_rgb.led = strtoull(argv[1], &e, 0);
- if (!(e && *e)) {
- r = lb_do_cmd(LIGHTBAR_CMD_GET_RGB, &param, &resp);
- if (r)
- return r;
- printf("%02x %02x %02x\n",
- resp.get_rgb.red,
- resp.get_rgb.green,
- resp.get_rgb.blue);
- return 0;
- }
- }
-
- return lb_help(argv[0]);
-}
-
-/* Create an array to store sizes of motion sense param and response structs. */
-#define ST_CMD_SIZE ST_FLD_SIZE(ec_params_motion_sense, cmd)
-#define ST_PRM_SIZE(SUBCMD) \
- (ST_CMD_SIZE + ST_FLD_SIZE(ec_params_motion_sense, SUBCMD))
-#define ST_RSP_SIZE(SUBCMD) ST_FLD_SIZE(ec_response_motion_sense, SUBCMD)
-#define ST_BOTH_SIZES(SUBCMD) { ST_PRM_SIZE(SUBCMD), ST_RSP_SIZE(SUBCMD) }
-
-/*
- * For ectool only, assume no more than 16 sensors. More advanced
- * implementation would allocate the right amount of memory depending on the
- * number of sensors.
- */
-#define ECTOOL_MAX_SENSOR 16
-
-static const struct {
- uint8_t outsize;
- uint8_t insize;
-} ms_command_sizes[] = {
- {
- ST_PRM_SIZE(dump),
- ST_RSP_SIZE(dump) +
- sizeof(struct ec_response_motion_sensor_data) *
- ECTOOL_MAX_SENSOR
- },
- ST_BOTH_SIZES(info_4),
- ST_BOTH_SIZES(ec_rate),
- ST_BOTH_SIZES(sensor_odr),
- ST_BOTH_SIZES(sensor_range),
- ST_BOTH_SIZES(kb_wake_angle),
- ST_BOTH_SIZES(data),
- {
- ST_CMD_SIZE,
- ST_RSP_SIZE(fifo_info) + sizeof(uint16_t) * ECTOOL_MAX_SENSOR
- },
- ST_BOTH_SIZES(fifo_flush),
- ST_BOTH_SIZES(fifo_read),
- ST_BOTH_SIZES(perform_calib),
- ST_BOTH_SIZES(sensor_offset),
- ST_BOTH_SIZES(list_activities),
- { ST_PRM_SIZE(set_activity), 0 },
- { ST_CMD_SIZE, ST_RSP_SIZE(lid_angle) },
- ST_BOTH_SIZES(fifo_int_enable),
- ST_BOTH_SIZES(spoof),
- ST_BOTH_SIZES(tablet_mode_threshold),
- ST_BOTH_SIZES(sensor_scale),
- ST_BOTH_SIZES(online_calib_read),
- ST_BOTH_SIZES(get_activity),
-};
-BUILD_ASSERT(ARRAY_SIZE(ms_command_sizes) == MOTIONSENSE_NUM_CMDS);
-
-#undef ST_CMD_SIZE
-#undef ST_PRM_SIZE
-#undef ST_RSP_SIZE
-#undef ST_BOTH_SIZES
-
-static int ms_help(const char *cmd)
-{
- printf("Usage:\n");
- printf(" %s - dump all motion data\n",
- cmd);
- printf(" %s active - print active flag\n", cmd);
- printf(" %s info NUM - print sensor info\n", cmd);
- printf(" %s ec_rate [RATE_MS] - set/get sample rate\n",
- cmd);
- printf(" %s odr NUM [ODR [ROUNDUP]] - set/get sensor ODR\n",
- cmd);
- printf(" %s range NUM [RANGE [ROUNDUP]] - set/get sensor range\n",
- cmd);
- printf(" %s offset NUM [-- X Y Z [TEMP]] - set/get sensor offset\n",
- cmd);
- printf(" %s kb_wake NUM - set/get KB wake ang\n",
- cmd);
- printf(" %s fifo_info - print fifo info\n", cmd);
- printf(" %s fifo_int_enable [0/1] - enable/disable/get fifo "
- "interrupt status\n", cmd);
- printf(" %s fifo_read MAX_DATA - read fifo data\n", cmd);
- printf(" %s fifo_flush NUM - trigger fifo interrupt\n",
- cmd);
- printf(" %s list_activities - list supported "
- "activities\n", cmd);
- printf(" %s set_activity ACT EN - enable/disable activity\n",
- cmd);
- printf(" %s get_activity ACT - get activity status\n",
- cmd);
- printf(" %s lid_angle - print lid angle\n", cmd);
- printf(" %s spoof -- NUM [0/1] [X Y Z] - enable/disable spoofing\n",
- cmd);
- printf(" %s spoof -- NUM activity ACT [0/1] [STATE] - enable/disable "
- "activity spoofing\n", cmd);
- printf(" %s tablet_mode_angle ANG HYS - set/get tablet mode "
- "angle\n", cmd);
- printf(" %s calibrate NUM - run sensor calibration\n",
- cmd);
-
- return 0;
-}
-
-static void motionsense_display_activities(uint32_t activities)
-{
- if (activities & BIT(MOTIONSENSE_ACTIVITY_SIG_MOTION))
- printf("%d: Significant motion\n",
- MOTIONSENSE_ACTIVITY_SIG_MOTION);
- if (activities & BIT(MOTIONSENSE_ACTIVITY_DOUBLE_TAP))
- printf("%d: Double tap\n",
- MOTIONSENSE_ACTIVITY_DOUBLE_TAP);
- if (activities & BIT(MOTIONSENSE_ACTIVITY_ORIENTATION))
- printf("%d: Orientation\n",
- MOTIONSENSE_ACTIVITY_ORIENTATION);
- if (activities & BIT(MOTIONSENSE_ACTIVITY_BODY_DETECTION))
- printf("%d: Body Detection\n",
- MOTIONSENSE_ACTIVITY_BODY_DETECTION);
-}
-
-static int cmd_motionsense(int argc, char **argv)
-{
- int i, rv, status_only = (argc == 2);
- struct ec_params_motion_sense param;
- /* The largest size using resp as a response buffer */
- uint8_t resp_buffer[ms_command_sizes[MOTIONSENSE_CMD_DUMP].insize];
- struct ec_response_motion_sense *resp =
- (struct ec_response_motion_sense *)resp_buffer;
- char *e;
- /*
- * Warning: the following strings printed out are read in an
- * autotest. Do not change string without consulting autotest
- * for kernel_CrosECSysfsAccel.
- */
- const char *motion_status_string[2][2] = {
- { "Motion sensing inactive", "0"},
- { "Motion sensing active", "1"},
- };
-
- /* No motionsense command has more than 7 args. */
- if (argc > 7)
- return ms_help(argv[0]);
-
- if ((argc == 1) ||
- (argc == 2 && !strcasecmp(argv[1], "active"))) {
- param.cmd = MOTIONSENSE_CMD_DUMP;
- param.dump.max_sensor_count = ECTOOL_MAX_SENSOR;
- rv = ec_command(
- EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv > 0) {
- printf("%s\n", motion_status_string[
- !!(resp->dump.module_flags &
- MOTIONSENSE_MODULE_FLAG_ACTIVE)][
- status_only]);
- if (status_only)
- return 0;
-
- if (resp->dump.sensor_count > ECTOOL_MAX_SENSOR) {
- printf("Too many sensors to handle: %d",
- resp->dump.sensor_count);
- return -1;
- }
- for (i = 0; i < resp->dump.sensor_count; i++) {
- /*
- * Warning: the following string printed out
- * is read by an autotest. Do not change string
- * without consulting autotest for
- * kernel_CrosECSysfsAccel.
- */
- printf("Sensor %d: ", i);
- if (resp->dump.sensor[i].flags &
- MOTIONSENSE_SENSOR_FLAG_PRESENT)
- printf("%d\t%d\t%d\n",
- resp->dump.sensor[i].data[0],
- resp->dump.sensor[i].data[1],
- resp->dump.sensor[i].data[2]);
- else
- printf("None\n");
- }
- return 0;
- } else {
- return rv;
- }
- }
-
- if (argc == 3 && !strcasecmp(argv[1], "info")) {
- int version = 0;
-
- rv = get_latest_cmd_version(EC_CMD_MOTION_SENSE_CMD, &version);
- if (rv < 0)
- return rv;
-
- param.cmd = MOTIONSENSE_CMD_INFO;
- param.sensor_odr.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, version,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("Type: ");
- switch (resp->info.type) {
- case MOTIONSENSE_TYPE_ACCEL:
- printf("accel\n");
- break;
- case MOTIONSENSE_TYPE_GYRO:
- printf("gyro\n");
- break;
- case MOTIONSENSE_TYPE_MAG:
- printf("magnetometer\n");
- break;
- case MOTIONSENSE_TYPE_LIGHT:
- printf("light\n");
- break;
- case MOTIONSENSE_TYPE_LIGHT_RGB:
- printf("rgb light\n");
- break;
- case MOTIONSENSE_TYPE_PROX:
- printf("proximity\n");
- break;
- case MOTIONSENSE_TYPE_ACTIVITY:
- printf("activity\n");
- break;
- case MOTIONSENSE_TYPE_BARO:
- printf("barometer\n");
- break;
- case MOTIONSENSE_TYPE_SYNC:
- printf("sync\n");
- break;
- default:
- printf("unknown\n");
- }
-
- printf("Location: ");
- switch (resp->info.location) {
- case MOTIONSENSE_LOC_BASE:
- printf("base\n");
- break;
- case MOTIONSENSE_LOC_LID:
- printf("lid\n");
- break;
- case MOTIONSENSE_LOC_CAMERA:
- printf("camera\n");
- break;
- default:
- printf("unknown\n");
- }
-
- printf("Chip: ");
- switch (resp->info.chip) {
- case MOTIONSENSE_CHIP_KXCJ9:
- printf("kxcj9\n");
- break;
- case MOTIONSENSE_CHIP_LSM6DS0:
- printf("lsm6ds0\n");
- break;
- case MOTIONSENSE_CHIP_BMI160:
- printf("bmi160\n");
- break;
- case MOTIONSENSE_CHIP_SI1141:
- printf("si1141\n");
- break;
- case MOTIONSENSE_CHIP_KX022:
- printf("kx022\n");
- break;
- case MOTIONSENSE_CHIP_L3GD20H:
- printf("l3gd20h\n");
- break;
- case MOTIONSENSE_CHIP_BMA255:
- printf("bma255\n");
- break;
- case MOTIONSENSE_CHIP_BMP280:
- printf("bmp280\n");
- break;
- case MOTIONSENSE_CHIP_OPT3001:
- printf("opt3001\n");
- break;
- case MOTIONSENSE_CHIP_BH1730:
- printf("bh1730\n");
- break;
- case MOTIONSENSE_CHIP_GPIO:
- printf("gpio\n");
- break;
- case MOTIONSENSE_CHIP_LIS2DH:
- printf("lis2dh\n");
- break;
- case MOTIONSENSE_CHIP_LSM6DSM:
- printf("lsm6dsm\n");
- break;
- case MOTIONSENSE_CHIP_LIS2DE:
- printf("lis2de\n");
- break;
- case MOTIONSENSE_CHIP_LIS2MDL:
- printf("lis2mdl\n");
- break;
- case MOTIONSENSE_CHIP_LSM6DS3:
- printf("lsm6ds3\n");
- break;
- case MOTIONSENSE_CHIP_LSM6DSO:
- printf("lsm6dso\n");
- break;
- case MOTIONSENSE_CHIP_LNG2DM:
- printf("lng2dm\n");
- break;
- case MOTIONSENSE_CHIP_TCS3400:
- printf("tcs3400\n");
- break;
- case MOTIONSENSE_CHIP_LIS2DW12:
- printf("lis2dw12\n");
- break;
- case MOTIONSENSE_CHIP_LIS2DWL:
- printf("lis2dwl\n");
- break;
- case MOTIONSENSE_CHIP_LIS2DS:
- printf("lis2ds\n");
- break;
- case MOTIONSENSE_CHIP_BMI260:
- printf("bmi260\n");
- break;
- case MOTIONSENSE_CHIP_ICM426XX:
- printf("icm426xx\n");
- break;
- case MOTIONSENSE_CHIP_ICM42607:
- printf("icm42607\n");
- break;
- case MOTIONSENSE_CHIP_BMI323:
- printf("bmi323\n");
- break;
- case MOTIONSENSE_CHIP_BMA422:
- printf("bma422\n");
- break;
- default:
- printf("unknown\n");
- }
-
- if (version >= 3) {
- printf("Min Frequency: %d mHz\n",
- resp->info_3.min_frequency);
- printf("Max Frequency: %d mHz\n",
- resp->info_3.max_frequency);
- printf("FIFO Max Event Count: %d\n",
- resp->info_3.fifo_max_event_count);
- }
- if (version >= 4) {
- printf("Flags: %d\n",
- resp->info_4.flags);
- }
- return 0;
- }
-
- if (argc < 4 && !strcasecmp(argv[1], "ec_rate")) {
- param.cmd = MOTIONSENSE_CMD_EC_RATE;
- param.ec_rate.data = EC_MOTION_SENSE_NO_VALUE;
-
- if (argc == 3) {
- param.ec_rate.data = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->ec_rate.ret);
- return 0;
- }
-
- if (argc > 2 && !strcasecmp(argv[1], "odr")) {
- param.cmd = MOTIONSENSE_CMD_SENSOR_ODR;
- param.sensor_odr.data = EC_MOTION_SENSE_NO_VALUE;
- param.sensor_odr.roundup = 1;
-
- param.sensor_odr.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- if (argc >= 4) {
- param.sensor_odr.data = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[3]);
- return -1;
- }
- }
-
- if (argc == 5) {
- param.sensor_odr.roundup = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[4]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->sensor_odr.ret);
- return 0;
- }
-
- if (argc > 2 && !strcasecmp(argv[1], "range")) {
- param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
- param.sensor_range.data = EC_MOTION_SENSE_NO_VALUE;
- param.sensor_range.roundup = 1;
-
- param.sensor_range.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- if (argc >= 4) {
- param.sensor_range.data = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[3]);
- return -1;
- }
- }
-
- if (argc == 5) {
- param.sensor_odr.roundup = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[4]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->sensor_range.ret);
- return 0;
- }
-
- if (argc < 4 && !strcasecmp(argv[1], "kb_wake")) {
- param.cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE;
- param.kb_wake_angle.data = EC_MOTION_SENSE_NO_VALUE;
-
- if (argc == 3) {
- param.kb_wake_angle.data = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->kb_wake_angle.ret);
- return 0;
- }
-
- if (argc < 5 && !strcasecmp(argv[1], "tablet_mode_angle")) {
- param.cmd = MOTIONSENSE_CMD_TABLET_MODE_LID_ANGLE;
- /*
- * EC_MOTION_SENSE_NO_VALUE indicates to the EC that host is
- * attempting to only read the current values.
- */
- param.tablet_mode_threshold.lid_angle =
- EC_MOTION_SENSE_NO_VALUE;
- param.tablet_mode_threshold.hys_degree =
- EC_MOTION_SENSE_NO_VALUE;
-
- if (argc == 4) {
- param.tablet_mode_threshold.lid_angle = strtol(argv[2],
- &e, 0);
-
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- param.tablet_mode_threshold.hys_degree = strtol(argv[3],
- &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[3]);
- return -1;
- }
- } else if (argc != 2) {
- return ms_help(argv[0]);
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("tablet_mode_angle=%d hys=%d\n",
- resp->tablet_mode_threshold.lid_angle,
- resp->tablet_mode_threshold.hys_degree);
-
- return 0;
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "fifo_info")) {
- int sensor_count;
-
- param.cmd = MOTIONSENSE_CMD_DUMP;
- param.dump.max_sensor_count = 0;
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
- sensor_count = resp->dump.sensor_count;
-
- param.cmd = MOTIONSENSE_CMD_FIFO_INFO;
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("Size: %d\n", resp->fifo_info.size);
- printf("Count: %d\n", resp->fifo_info.count);
- printf("Timestamp:%" PRIx32 "\n", resp->fifo_info.timestamp);
- printf("Total lost: %d\n", resp->fifo_info.total_lost);
- for (i = 0; i < sensor_count; i++) {
- int lost = resp->fifo_info.lost[i];
- if (lost != 0)
- printf("Lost %d: %d\n", i, lost);
- }
- return 0;
- }
-
- if (argc >= 2 && !strcasecmp(argv[1], "fifo_int_enable")) {
- param.cmd = MOTIONSENSE_CMD_FIFO_INT_ENABLE;
- if (argc == 3)
- param.fifo_int_enable.enable = strtol(argv[2], &e, 0);
- else
- param.fifo_int_enable.enable = EC_MOTION_SENSE_NO_VALUE;
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->fifo_int_enable.ret);
- return 0;
- }
-
- if (argc == 3 && !strcasecmp(argv[1], "fifo_read")) {
- /* large number to test fragmentation */
- struct {
- uint32_t number_data;
- struct ec_response_motion_sensor_data data[512];
- } fifo_read_buffer = {
- .number_data = UINT32_MAX,
- };
- int print_data = 0, max_data = strtol(argv[2], &e, 0);
-
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
- while (fifo_read_buffer.number_data != 0 &&
- print_data < max_data) {
- struct ec_response_motion_sensor_data *vector;
- param.cmd = MOTIONSENSE_CMD_FIFO_READ;
- param.fifo_read.max_data_vector =
- MIN(ARRAY_SIZE(fifo_read_buffer.data),
- max_data - print_data);
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param,
- ms_command_sizes[param.cmd].outsize,
- &fifo_read_buffer, ec_max_insize);
- if (rv < 0)
- return rv;
-
- print_data += fifo_read_buffer.number_data;
- for (i = 0; i < fifo_read_buffer.number_data; i++) {
- vector = &fifo_read_buffer.data[i];
- if (vector->flags &
- (MOTIONSENSE_SENSOR_FLAG_TIMESTAMP |
- MOTIONSENSE_SENSOR_FLAG_FLUSH)) {
-
- printf("Timestamp:%" PRIx32 "%s\n",
- vector->timestamp,
- (vector->flags &
- MOTIONSENSE_SENSOR_FLAG_FLUSH ?
- " - Flush" : ""));
- } else {
- printf("Sensor %d: %d\t%d\t%d "
- "(as uint16: %u\t%u\t%u)\n",
- vector->sensor_num,
- vector->data[0],
- vector->data[1],
- vector->data[2],
- vector->data[0],
- vector->data[1],
- vector->data[2]);
- }
- }
- }
- return 0;
- }
- if (argc == 3 && !strcasecmp(argv[1], "fifo_flush")) {
- param.cmd = MOTIONSENSE_CMD_FIFO_FLUSH;
-
- param.sensor_odr.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- return rv < 0 ? rv : 0;
- }
-
- if (argc == 3 && !strcasecmp(argv[1], "calibrate")) {
- param.cmd = MOTIONSENSE_CMD_PERFORM_CALIB;
- param.perform_calib.enable = 1;
- param.perform_calib.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("--- Calibrated well ---\n");
- printf("New offset vector: X:%d, Y:%d, Z:%d\n",
- resp->perform_calib.offset[0],
- resp->perform_calib.offset[1],
- resp->perform_calib.offset[2]);
- if ((uint16_t)resp->perform_calib.temp ==
- EC_MOTION_SENSE_INVALID_CALIB_TEMP)
- printf("Temperature at calibration unknown\n");
- else
- printf("Temperature at calibration: %d.%02d C\n",
- resp->perform_calib.temp / 100,
- resp->perform_calib.temp % 100);
- return 0;
- }
-
- if (argc >= 3 && !strcasecmp(argv[1], "offset")) {
- param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET;
- param.sensor_offset.flags = 0;
- param.sensor_offset.temp = EC_MOTION_SENSE_INVALID_CALIB_TEMP;
-
- param.sensor_offset.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- if (argc >= 4) {
- /* Regarded as a command to set offset */
- if (argc >= 6 && argc < 8) {
- /* Set offset : X, Y, Z */
- param.sensor_offset.flags = MOTION_SENSE_SET_OFFSET;
- for (i = 0; i < 3; i++) {
- param.sensor_offset.offset[i] = strtol(argv[3+i], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[3+i]);
- return -1;
- }
- }
- if (argc == 7) {
- /* Set offset : Temperature */
- param.sensor_offset.temp = strtol(argv[6], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[6]);
- return -1;
- }
- }
- } else {
- return ms_help(argv[0]);
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("Offset vector: X:%d, Y:%d, Z:%d\n",
- resp->sensor_offset.offset[0],
- resp->sensor_offset.offset[1],
- resp->sensor_offset.offset[2]);
- if ((uint16_t)resp->sensor_offset.temp ==
- EC_MOTION_SENSE_INVALID_CALIB_TEMP)
- printf("temperature at calibration unknown\n");
- else
- printf("temperature at calibration: %d.%02d C\n",
- resp->sensor_offset.temp / 100,
- resp->sensor_offset.temp % 100);
- return 0;
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "list_activities")) {
- param.cmd = MOTIONSENSE_CMD_LIST_ACTIVITIES;
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("Enabled:\n");
- motionsense_display_activities(resp->list_activities.enabled);
- printf("Disabled:\n");
- motionsense_display_activities(resp->list_activities.disabled);
- return 0;
- }
- if (argc == 4 && !strcasecmp(argv[1], "set_activity")) {
- param.cmd = MOTIONSENSE_CMD_SET_ACTIVITY;
- param.set_activity.activity = strtol(argv[2], &e, 0);
- param.set_activity.enable = strtol(argv[3], &e, 0);
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
- return 0;
- }
- if (argc == 3 && !strcasecmp(argv[1], "get_activity")) {
- param.cmd = MOTIONSENSE_CMD_GET_ACTIVITY;
- param.get_activity.activity = strtol(argv[2], &e, 0);
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
- printf("State: %d\n", resp->get_activity.state);
- return 0;
- }
- if (argc == 2 && !strcasecmp(argv[1], "lid_angle")) {
- param.cmd = MOTIONSENSE_CMD_LID_ANGLE;
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("Lid angle: ");
- if (resp->lid_angle.value == LID_ANGLE_UNRELIABLE)
- printf("unreliable\n");
- else
- printf("%d\n", resp->lid_angle.value);
-
- return 0;
- }
-
- if (argc >= 3 && !strcasecmp(argv[1], "spoof")) {
- param.cmd = MOTIONSENSE_CMD_SPOOF;
- /* By default, just query the current spoof status. */
- param.spoof.spoof_enable = MOTIONSENSE_SPOOF_MODE_QUERY;
- param.spoof.sensor_id = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
- /* spoof activity state */
- if (argc >= 5 && !strcasecmp(argv[3], "activity")) {
- int enable = 0;
-
- param.spoof.activity_num = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Base %s arg.\n", argv[4]);
- return -1;
- }
- if (argc >= 6) {
- enable = strtol(argv[5], &e, 0);
- if ((e && *e) || (enable != 0 && enable != 1)) {
- fprintf(stderr, "Bad %s arg.\n",
- argv[5]);
- return -1;
- }
- }
- if ((enable == 1) && (argc == 6)) {
- /* Enable spoofing, but lock to current state */
- param.spoof.spoof_enable =
- MOTIONSENSE_SPOOF_MODE_LOCK_CURRENT;
- } else if ((enable == 1) && (argc == 7)) {
- /* Enable spoofing, but use provided state */
- int state = strtol(argv[6], &e, 0);
-
- if ((e && *e) || (state != 0 && state != 1)) {
- fprintf(stderr, "Bad %s arg.\n",
- argv[6]);
- return -1;
- }
- param.spoof.activity_state = state;
- param.spoof.spoof_enable =
- MOTIONSENSE_SPOOF_MODE_CUSTOM;
- } else if ((enable == 0) && (argc == 6)) {
- param.spoof.spoof_enable =
- MOTIONSENSE_SPOOF_MODE_DISABLE;
- } else if (argc != 5) {
- return ms_help(argv[0]);
- }
- /* spoof accel data */
- } else if (argc >= 4) {
- int enable, i;
- int16_t val;
-
- enable = strtol(argv[3], &e, 0);
- if ((e && *e) || (enable != 0 && enable != 1)) {
- fprintf(stderr, "Bad %s arg.\n", argv[3]);
- return -1;
- }
-
- if ((enable == 1) && (argc == 4)) {
- /*
- * Enable spoofing, but lock to current sensor
- * values.
- */
- param.spoof.spoof_enable =
- MOTIONSENSE_SPOOF_MODE_LOCK_CURRENT;
- } else if ((enable == 1) && (argc == 7)) {
- /*
- * Enable spoofing, but use provided component
- * values.
- */
- param.spoof.spoof_enable =
- MOTIONSENSE_SPOOF_MODE_CUSTOM;
- for (i = 0; i < 3; i++) {
- val = strtol(argv[4+i], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n",
- argv[4+i]);
- return -1;
- }
- param.spoof.components[i] = val;
- }
- } else if (enable == 0) {
- param.spoof.spoof_enable =
- MOTIONSENSE_SPOOF_MODE_DISABLE;
- } else {
- return ms_help(argv[0]);
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- if (param.spoof.spoof_enable == MOTIONSENSE_SPOOF_MODE_QUERY)
- /*
- * Response is the current spoof status of the
- * sensor.
- */
- printf("Sensor %d spoof mode is %s.\n",
- param.spoof.sensor_id,
- resp->spoof.ret ? "enabled" : "disabled");
-
- return 0;
- }
-
- return ms_help(argv[0]);
-}
-
-int cmd_next_event(int argc, char *argv[])
-{
- uint8_t *rdata = (uint8_t *)ec_inbuf;
- int rv;
- int i;
-
- rv = ec_command(EC_CMD_GET_NEXT_EVENT, 0,
- NULL, 0, rdata, ec_max_insize);
- if (rv < 0)
- return rv;
-
- printf("Next event is 0x%02x\n", rdata[0]);
- if (rv > 1) {
- printf("Event data:\n");
- for (i = 1; i < rv; ++i) {
- printf("%02x ", rdata[i]);
- if (!(i & 0xf))
- printf("\n");
- }
- printf("\n");
- }
-
- return 0;
-}
-
-static int find_led_color_by_name(const char *color)
-{
- int i;
-
- for (i = 0; i < EC_LED_COLOR_COUNT; ++i)
- if (!strcasecmp(color, led_color_names[i]))
- return i;
-
- return -1;
-}
-
-static int find_led_id_by_name(const char *led)
-{
- int i;
-
- for (i = 0; i < EC_LED_ID_COUNT; ++i)
- if (!strcasecmp(led, led_names[i]))
- return i;
-
- return -1;
-}
-
-int cmd_led(int argc, char *argv[])
-{
- struct ec_params_led_control p;
- struct ec_response_led_control r;
- char *e, *ptr;
- int rv, i, j;
-
- memset(p.brightness, 0, sizeof(p.brightness));
- p.flags = 0;
-
- if (argc < 3) {
- fprintf(stderr,
- "Usage: %s <name> <query | auto | "
- "off | <color> | <color>=<value>...>\n", argv[0]);
- return -1;
- }
-
- p.led_id = find_led_id_by_name(argv[1]);
- if (p.led_id == (uint8_t)-1) {
- fprintf(stderr, "Bad LED name: %s\n", argv[1]);
- fprintf(stderr, "Valid LED names: ");
- for (i = 0; i < EC_LED_ID_COUNT; i++)
- fprintf(stderr, "%s ", led_names[i]);
- fprintf(stderr, "\n");
- return -1;
- }
-
- if (!strcasecmp(argv[2], "query")) {
- p.flags = EC_LED_FLAGS_QUERY;
- rv = ec_command(EC_CMD_LED_CONTROL, 1, &p, sizeof(p),
- &r, sizeof(r));
- printf("Brightness range for LED %d:\n", p.led_id);
- if (rv < 0) {
- fprintf(stderr, "Error: Unsupported LED.\n");
- return rv;
- }
- for (i = 0; i < EC_LED_COLOR_COUNT; ++i)
- printf("\t%s\t: 0x%x\n",
- led_color_names[i],
- r.brightness_range[i]);
- return 0;
- }
-
- if (!strcasecmp(argv[2], "off")) {
- /* Brightness initialized to 0 for each color. */
- } else if (!strcasecmp(argv[2], "auto")) {
- p.flags = EC_LED_FLAGS_AUTO;
- } else if ((i = find_led_color_by_name(argv[2])) != -1) {
- p.brightness[i] = 0xff;
- } else {
- for (i = 2; i < argc; ++i) {
- ptr = strtok(argv[i], "=");
- j = find_led_color_by_name(ptr);
- if (j == -1) {
- fprintf(stderr, "Bad color name: %s\n", ptr);
- fprintf(stderr, "Valid colors: ");
- for (j = 0; j < EC_LED_COLOR_COUNT; j++)
- fprintf(stderr, "%s ",
- led_color_names[j]);
- fprintf(stderr, "\n");
- return -1;
- }
- ptr = strtok(NULL, "=");
- if (ptr == NULL) {
- fprintf(stderr, "Missing brightness value\n");
- return -1;
- }
- p.brightness[j] = strtol(ptr, &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad brightness: %s\n", ptr);
- return -1;
- }
- }
- }
-
- rv = ec_command(EC_CMD_LED_CONTROL, 1, &p, sizeof(p), &r, sizeof(r));
- return (rv < 0 ? rv : 0);
-}
-
-
-int cmd_usb_charge_set_mode(int argc, char *argv[])
-{
- struct ec_params_usb_charge_set_mode p;
- char *e;
- int rv;
-
- if (argc != 3 && argc != 4) {
- fprintf(stderr,
- "Usage: %s <port_id> <mode_id> [<inhibit_charge>]\n",
- argv[0]);
- return -1;
- }
- p.usb_port_id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port ID.\n");
- return -1;
- }
- p.mode = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mode ID.\n");
- return -1;
- }
- p.inhibit_charge = 0;
- if (argc == 4) {
- p.inhibit_charge = strtol(argv[3], &e, 0);
- if ((e && *e) || (p.inhibit_charge != 0 &&
- p.inhibit_charge != 1)) {
- fprintf(stderr, "Bad value\n");
- return -1;
- }
- }
-
- printf("Setting port %d to mode %d inhibit_charge %d...\n",
- p.usb_port_id, p.mode, p.inhibit_charge);
-
- rv = ec_command(EC_CMD_USB_CHARGE_SET_MODE, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("USB charging mode set.\n");
- return 0;
-}
-
-
-int cmd_usb_mux(int argc, char *argv[])
-{
- struct ec_params_usb_mux p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mux>\n", argv[0]);
- return -1;
- }
-
- p.mux = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mux value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_USB_MUX, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Set USB mux to 0x%x.\n", p.mux);
-
- return 0;
-}
-
-
-int cmd_usb_pd(int argc, char *argv[])
-{
- const char *role_str[] = {"", "toggle", "toggle-off", "sink", "source",
- "freeze"};
- const char *mux_str[] = {"", "none", "usb", "dp", "dock", "auto"};
- const char *swap_str[] = {"", "dr_swap", "pr_swap", "vconn_swap"};
- struct ec_params_usb_pd_control p;
- struct ec_response_usb_pd_control_v2 *r_v2 =
- (struct ec_response_usb_pd_control_v2 *)ec_inbuf;
- struct ec_response_usb_pd_control_v1 *r_v1 =
- (struct ec_response_usb_pd_control_v1 *)ec_inbuf;
- struct ec_response_usb_pd_control *r =
- (struct ec_response_usb_pd_control *)ec_inbuf;
- int rv, i, j;
- int option_ok;
- char *e;
- int cmdver;
-
- BUILD_ASSERT(ARRAY_SIZE(role_str) == USB_PD_CTRL_ROLE_COUNT);
- BUILD_ASSERT(ARRAY_SIZE(mux_str) == USB_PD_CTRL_MUX_COUNT);
- BUILD_ASSERT(ARRAY_SIZE(swap_str) == USB_PD_CTRL_SWAP_COUNT);
- p.role = USB_PD_CTRL_ROLE_NO_CHANGE;
- p.mux = USB_PD_CTRL_MUX_NO_CHANGE;
- p.swap = USB_PD_CTRL_SWAP_NONE;
-
- if (argc < 2) {
- fprintf(stderr, "No port specified.\n");
- return -1;
- }
-
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Invalid param (port)\n");
- return -1;
- }
-
- for (i = 2; i < argc; ++i) {
- option_ok = 0;
- if (!strcmp(argv[i], "auto")) {
- if (argc != 3) {
- fprintf(stderr, "\"auto\" may not be used "
- "with other options.\n");
- return -1;
- }
- p.role = USB_PD_CTRL_ROLE_TOGGLE_ON;
- p.mux = USB_PD_CTRL_MUX_AUTO;
- continue;
- }
-
- for (j = 0; j < ARRAY_SIZE(role_str); ++j) {
- if (!strcmp(argv[i], role_str[j])) {
- if (p.role != USB_PD_CTRL_ROLE_NO_CHANGE) {
- fprintf(stderr,
- "Only one role allowed.\n");
- return -1;
- }
- p.role = j;
- option_ok = 1;
- break;
- }
- }
- if (option_ok)
- continue;
-
- for (j = 0; j < ARRAY_SIZE(mux_str); ++j) {
- if (!strcmp(argv[i], mux_str[j])) {
- if (p.mux != USB_PD_CTRL_MUX_NO_CHANGE) {
- fprintf(stderr,
- "Only one mux type allowed.\n");
- return -1;
- }
- p.mux = j;
- option_ok = 1;
- break;
- }
- }
- if (option_ok)
- continue;
-
- for (j = 0; j < ARRAY_SIZE(swap_str); ++j) {
- if (!strcmp(argv[i], swap_str[j])) {
- if (p.swap != USB_PD_CTRL_SWAP_NONE) {
- fprintf(stderr,
- "Only one swap type allowed.\n");
- return -1;
- }
- p.swap = j;
- option_ok = 1;
- break;
- }
- }
-
-
- if (!option_ok) {
- fprintf(stderr, "Unknown option: %s\n", argv[i]);
- return -1;
- }
- }
-
- if (ec_cmd_version_supported(EC_CMD_USB_PD_CONTROL, 2))
- cmdver = 2;
- else if (ec_cmd_version_supported(EC_CMD_USB_PD_CONTROL, 1))
- cmdver = 1;
- else
- cmdver = 0;
-
- rv = ec_command(EC_CMD_USB_PD_CONTROL, cmdver, &p, sizeof(p),
- ec_inbuf, ec_max_insize);
-
- if (rv < 0 || argc != 2)
- return (rv < 0) ? rv : 0;
-
- if (cmdver == 0) {
- printf("Port C%d is %sabled, Role:%s Polarity:CC%d State:%d\n",
- p.port, (r->enabled) ? "en" : "dis",
- r->role == PD_ROLE_SOURCE ? "SRC" : "SNK",
- r->polarity + 1, r->state);
- } else {
- printf("Port C%d: %s, %s State:%s\n"
- "Role:%s %s%s, Polarity:CC%d\n",
- p.port,
- (r_v1->enabled & PD_CTRL_RESP_ENABLED_COMMS) ?
- "enabled" : "disabled",
- (r_v1->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) ?
- "connected" : "disconnected",
- r_v1->state,
-
- (r_v1->role & PD_CTRL_RESP_ROLE_POWER) ? "SRC" : "SNK",
- (r_v1->role & PD_CTRL_RESP_ROLE_DATA) ? "DFP" : "UFP",
- (r_v1->role & PD_CTRL_RESP_ROLE_VCONN) ? " VCONN" : "",
- r_v1->polarity + 1);
-
- if (cmdver == 2) {
- printf("CC State:");
- if (r_v2->cc_state == PD_CC_NONE)
- printf("None");
- else if (r_v2->cc_state == PD_CC_UFP_AUDIO_ACC)
- printf("UFP Audio accessory");
- else if (r_v2->cc_state == PD_CC_UFP_DEBUG_ACC)
- printf("UFP Debug accessory");
- else if (r_v2->cc_state == PD_CC_UFP_ATTACHED)
- printf("UFP attached");
- else if (r_v2->cc_state == PD_CC_DFP_DEBUG_ACC)
- printf("DFP Debug accessory");
- else if (r_v2->cc_state == PD_CC_DFP_ATTACHED)
- printf("DFP attached");
- else
- printf("UNKNOWN");
- printf("\n");
-
- if (r_v2->dp_mode) {
- printf("DP pin mode:");
- if (r_v2->dp_mode == MODE_DP_PIN_A)
- printf("A");
- else if (r_v2->dp_mode == MODE_DP_PIN_B)
- printf("B");
- else if (r_v2->dp_mode == MODE_DP_PIN_C)
- printf("C");
- else if (r_v2->dp_mode == MODE_DP_PIN_D)
- printf("D");
- else if (r_v2->dp_mode == MODE_DP_PIN_E)
- printf("E");
- else if (r_v2->dp_mode == MODE_DP_PIN_F)
- printf("F");
- else
- printf("UNKNOWN");
- printf("\n");
- }
-
- printf("Cable type:%s\n",
- r_v2->control_flags & USB_PD_CTRL_ACTIVE_CABLE ?
- "Active" : "Passive");
-
- printf("TBT Adapter type:%s\n",
- r_v2->control_flags &
- USB_PD_CTRL_TBT_LEGACY_ADAPTER ?
- "Legacy" : "Gen3");
-
- printf("Optical Cable:%s\n",
- r_v2->control_flags &
- USB_PD_CTRL_OPTICAL_CABLE ? "True" : "False");
-
- printf("Link LSRX Communication:%s-directional\n",
- r_v2->control_flags &
- USB_PD_CTRL_ACTIVE_LINK_UNIDIR ? "Uni" : "Bi");
-
- printf("TBT Cable Speed:");
- switch (r_v2->cable_speed) {
- case TBT_SS_U31_GEN1:
- printf("TBT Gen1");
- break;
- case TBT_SS_U32_GEN1_GEN2:
- printf("TBT Gen1 and TBT Gen2");
- break;
- case TBT_SS_TBT_GEN3:
- printf("TBT Gen3");
- break;
- default:
- printf("UNKNOWN");
- }
- printf("\n");
-
- printf("Rounded support: 3rd Gen %srounded support\n",
- r_v2->cable_gen ? "and 4th Gen " : "");
- }
- /* If connected to a PD device, then print port partner info */
- if ((r_v1->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) &&
- (r_v1->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE))
- printf("PD Partner Capabilities:\n%s%s%s%s",
- (r_v1->role & PD_CTRL_RESP_ROLE_DR_POWER) ?
- " DR power\n" : "",
- (r_v1->role & PD_CTRL_RESP_ROLE_DR_DATA) ?
- " DR data\n" : "",
- (r_v1->role & PD_CTRL_RESP_ROLE_USB_COMM) ?
- " USB capable\n" : "",
- (r_v1->role & PD_CTRL_RESP_ROLE_UNCONSTRAINED) ?
- " Unconstrained power\n" : "");
- }
- return 0;
-}
-
-static void print_pd_power_info(struct ec_response_usb_pd_power_info *r)
-{
- switch (r->role) {
- case USB_PD_PORT_POWER_DISCONNECTED:
- printf("Disconnected");
- break;
- case USB_PD_PORT_POWER_SOURCE:
- printf("SRC");
- break;
- case USB_PD_PORT_POWER_SINK:
- printf("SNK");
- break;
- case USB_PD_PORT_POWER_SINK_NOT_CHARGING:
- printf("SNK (not charging)");
- break;
- default:
- printf("Unknown");
- }
-
- if ((r->role == USB_PD_PORT_POWER_SOURCE) &&
- (r->meas.current_max))
- printf(" %dmA", r->meas.current_max);
-
- if ((r->role == USB_PD_PORT_POWER_DISCONNECTED) ||
- (r->role == USB_PD_PORT_POWER_SOURCE)) {
- printf("\n");
- return;
- }
-
- printf(r->dualrole ? " DRP" : " Charger");
- switch (r->type) {
- case USB_CHG_TYPE_PD:
- printf(" PD");
- break;
- case USB_CHG_TYPE_C:
- printf(" Type-C");
- break;
- case USB_CHG_TYPE_PROPRIETARY:
- printf(" Proprietary");
- break;
- case USB_CHG_TYPE_BC12_DCP:
- printf(" DCP");
- break;
- case USB_CHG_TYPE_BC12_CDP:
- printf(" CDP");
- break;
- case USB_CHG_TYPE_BC12_SDP:
- printf(" SDP");
- break;
- case USB_CHG_TYPE_OTHER:
- printf(" Other");
- break;
- case USB_CHG_TYPE_VBUS:
- printf(" VBUS");
- break;
- case USB_CHG_TYPE_UNKNOWN:
- printf(" Unknown");
- break;
- }
- printf(" %dmV / %dmA, max %dmV / %dmA",
- r->meas.voltage_now, r->meas.current_lim, r->meas.voltage_max,
- r->meas.current_max);
- if (r->max_power)
- printf(" / %dmW", r->max_power / 1000);
- printf("\n");
-}
-
-int cmd_usb_pd_mux_info(int argc, char *argv[])
-{
- struct ec_params_usb_pd_mux_info p;
- struct ec_response_usb_pd_mux_info r;
- int num_ports, rv, i;
-
- rv = ec_command(EC_CMD_USB_PD_PORTS, 0, NULL, 0,
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
- num_ports = ((struct ec_response_usb_pd_ports *)ec_inbuf)->num_ports;
-
- for (i = 0; i < num_ports; i++) {
- p.port = i;
- rv = ec_command(EC_CMD_USB_PD_MUX_INFO, 0,
- &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Port %d: ", i);
- printf("USB=%d ", !!(r.flags & USB_PD_MUX_USB_ENABLED));
- printf("DP=%d ", !!(r.flags & USB_PD_MUX_DP_ENABLED));
- printf("POLARITY=%s ", r.flags & USB_PD_MUX_POLARITY_INVERTED ?
- "INVERTED" : "NORMAL");
- printf("HPD_IRQ=%d ", !!(r.flags & USB_PD_MUX_HPD_IRQ));
- printf("HPD_LVL=%d ", !!(r.flags & USB_PD_MUX_HPD_LVL));
- printf("SAFE=%d ", !!(r.flags & USB_PD_MUX_SAFE_MODE));
- printf("TBT=%d ", !!(r.flags & USB_PD_MUX_TBT_COMPAT_ENABLED));
- printf("USB4=%d ", !!(r.flags & USB_PD_MUX_USB4_ENABLED));
- printf("\n");
- }
-
- return 0;
-}
-
-int cmd_usb_pd_power(int argc, char *argv[])
-{
- struct ec_params_usb_pd_power_info p;
- struct ec_response_usb_pd_power_info *r =
- (struct ec_response_usb_pd_power_info *)ec_inbuf;
- int num_ports, i, rv;
- char *e;
-
- rv = ec_command(EC_CMD_USB_PD_PORTS, 0, NULL, 0,
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
- num_ports = ((struct ec_response_usb_pd_ports *)r)->num_ports;
-
- if (argc < 2) {
- for (i = 0; i < num_ports; i++) {
- p.port = i;
- rv = ec_command(EC_CMD_USB_PD_POWER_INFO, 0,
- &p, sizeof(p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- printf("Port %d: ", i);
- print_pd_power_info(r);
- }
- } else {
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
- rv = ec_command(EC_CMD_USB_PD_POWER_INFO, 0,
- &p, sizeof(p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- printf("Port %d: ", p.port);
- print_pd_power_info(r);
- }
-
- return 0;
-}
-
-int cmd_kbpress(int argc, char *argv[])
-{
- struct ec_params_mkbp_simulate_key p;
- char *e;
- int rv;
-
- if (argc != 4) {
- fprintf(stderr,
- "Usage: %s <row> <col> <0|1>\n", argv[0]);
- return -1;
- }
- p.row = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad row.\n");
- return -1;
- }
- p.col = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad column.\n");
- return -1;
- }
- p.pressed = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad pressed flag.\n");
- return -1;
- }
-
- printf("%s row %d col %d.\n", p.pressed ? "Pressing" : "Releasing",
- p.row,
- p.col);
-
- rv = ec_command(EC_CMD_MKBP_SIMULATE_KEY, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
- printf("Done.\n");
- return 0;
-}
-
-int cmd_keyboard_factory_test(int argc, char *argv[])
-{
- struct ec_response_keyboard_factory_test r;
- int rv;
-
- rv = ec_command(EC_CMD_KEYBOARD_FACTORY_TEST, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- if (r.shorted != 0)
- printf("Keyboard %d and %d pin are shorted.\n",
- r.shorted & 0x00ff, r.shorted >> 8);
- else
- printf("Keyboard factory test passed.\n");
-
- return 0;
-}
-
-int cmd_panic_info(int argc, char *argv[])
-{
- int rv;
-
- rv = ec_command(EC_CMD_GET_PANIC_INFO, 0, NULL, 0,
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- if (rv == 0) {
- printf("No panic data.\n");
- return 0;
- }
-
- return parse_panic_info((char *)(ec_inbuf), rv);
-}
-
-
-int cmd_power_info(int argc, char *argv[])
-{
- struct ec_response_power_info_v1 r;
- int rv;
-
- rv = ec_command(EC_CMD_POWER_INFO, 1, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Power source:\t");
- switch (r.system_power_source) {
- case POWER_SOURCE_UNKNOWN:
- printf("Unknown\n");
- break;
- case POWER_SOURCE_BATTERY:
- printf("Battery\n");
- break;
- case POWER_SOURCE_AC:
- printf("AC\n");
- break;
- case POWER_SOURCE_AC_BATTERY:
- printf("AC + battery\n");
- break;
- }
-
- printf("Battery state-of-charge: %d%%\n", r.battery_soc);
- printf("Max AC power: %d Watts\n", r.ac_adapter_100pct);
- printf("Battery 1Cd rate: %d\n", r.battery_1cd);
- printf("RoP Avg: %d Watts\n", r.rop_avg);
- printf("RoP Peak: %d Watts\n", r.rop_peak);
- printf("Battery DBPT support level: %d\n",
- r.intel.batt_dbpt_support_level);
- printf("Battery DBPT Max Peak Power: %d Watts\n",
- r.intel.batt_dbpt_max_peak_power);
- printf("Battery DBPT Sus Peak Power: %d Watts\n",
- r.intel.batt_dbpt_sus_peak_power);
- return 0;
-}
-
-
-int cmd_pse(int argc, char *argv[])
-{
- struct ec_params_pse p;
- struct ec_response_pse_status r;
- int rsize = 0;
- char *e;
- int rv;
-
- if (argc < 2 || argc > 3 || !strcmp(argv[1], "help")) {
- printf("Usage: %s <port> [<subcmd>]\n", argv[0]);
- printf("'pse <port> [status]' - Get port status\n");
- printf("'pse <port> disable' - Disable port\n");
- printf("'pse <port> enable' - Enable port\n");
- return -1;
- }
-
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- if (argc == 2 || !strcmp(argv[2], "status")) {
- p.cmd = EC_PSE_STATUS;
- rsize = sizeof(r);
- } else if (!strcmp(argv[2], "disable")) {
- p.cmd = EC_PSE_DISABLE;
- } else if (!strcmp(argv[2], "enable")) {
- p.cmd = EC_PSE_ENABLE;
- } else {
- fprintf(stderr, "Unknown command: %s\n", argv[2]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_PSE, 0, &p, sizeof(p), &r, rsize);
- if (rv < 0)
- return rv;
-
- if (p.cmd == EC_PSE_STATUS) {
- const char *status;
-
- switch (r.status) {
- case EC_PSE_STATUS_DISABLED:
- status = "disabled";
- break;
- case EC_PSE_STATUS_ENABLED:
- status = "enabled";
- break;
- case EC_PSE_STATUS_POWERED:
- status = "powered";
- break;
- default:
- status = "unknown";
- break;
- }
-
- printf("Port %d: %s\n", p.port, status);
- }
-
- return 0;
-}
-
-
-int cmd_pstore_info(int argc, char *argv[])
-{
- struct ec_response_pstore_info r;
- int rv;
-
- rv = ec_command(EC_CMD_PSTORE_INFO, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("PstoreSize %d\nAccessSize %d\n", r.pstore_size, r.access_size);
- return 0;
-}
-
-
-int cmd_pstore_read(int argc, char *argv[])
-{
- struct ec_params_pstore_read p;
- uint8_t rdata[EC_PSTORE_SIZE_MAX];
- int offset, size;
- int rv;
- int i;
- char *e;
- char *buf;
-
- if (argc < 4) {
- fprintf(stderr,
- "Usage: %s <offset> <size> <filename>\n", argv[0]);
- return -1;
- }
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > 0x10000) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
- size = strtol(argv[2], &e, 0);
- if ((e && *e) || size <= 0 || size > 0x10000) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
- printf("Reading %d bytes at offset %d...\n", size, offset);
-
- buf = (char *)malloc(size);
- if (!buf) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- return -1;
- }
-
- /* Read data in chunks */
- for (i = 0; i < size; i += EC_PSTORE_SIZE_MAX) {
- p.offset = offset + i;
- p.size = MIN(size - i, EC_PSTORE_SIZE_MAX);
- rv = ec_command(EC_CMD_PSTORE_READ, 0,
- &p, sizeof(p), rdata, sizeof(rdata));
- if (rv < 0) {
- fprintf(stderr, "Read error at offset %d\n", i);
- free(buf);
- return rv;
- }
- memcpy(buf + i, rdata, p.size);
- }
-
- rv = write_file(argv[3], buf, size);
- free(buf);
- if (rv)
- return rv;
-
- printf("done.\n");
- return 0;
-}
-
-
-int cmd_pstore_write(int argc, char *argv[])
-{
- struct ec_params_pstore_write p;
- int offset, size;
- int rv;
- int i;
- char *e;
- char *buf;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <offset> <filename>\n", argv[0]);
- return -1;
- }
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > 0x10000) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
-
- /* Read the input file */
- buf = read_file(argv[2], &size);
- if (!buf)
- return -1;
-
- printf("Writing to offset %d...\n", offset);
-
- /* Write data in chunks */
- for (i = 0; i < size; i += EC_PSTORE_SIZE_MAX) {
- p.offset = offset + i;
- p.size = MIN(size - i, EC_PSTORE_SIZE_MAX);
- memcpy(p.data, buf + i, p.size);
- rv = ec_command(EC_CMD_PSTORE_WRITE, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0) {
- fprintf(stderr, "Write error at offset %d\n", i);
- free(buf);
- return rv;
- }
- }
-
- free(buf);
- printf("done.\n");
- return 0;
-}
-
-
-int cmd_host_event_get_raw(int argc, char *argv[])
-{
- uint32_t events = read_mapped_mem32(EC_MEMMAP_HOST_EVENTS);
-
- if (events & EC_HOST_EVENT_MASK(EC_HOST_EVENT_INVALID)) {
- printf("Current host events: invalid\n");
- return -1;
- }
-
- printf("Current host events: 0x%08x\n", events);
- return 0;
-}
-
-
-int cmd_host_event_get_b(int argc, char *argv[])
-{
- struct ec_response_host_event_mask r;
- int rv;
-
- rv = ec_command(EC_CMD_HOST_EVENT_GET_B, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
- if (rv < sizeof(r)) {
- fprintf(stderr, "Insufficient data received.\n");
- return -1;
- }
-
- if (r.mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_INVALID)) {
- printf("Current host events-B: invalid\n");
- return -1;
- }
-
- printf("Current host events-B: 0x%08x\n", r.mask);
- return 0;
-}
-
-
-int cmd_host_event_get_smi_mask(int argc, char *argv[])
-{
- struct ec_response_host_event_mask r;
- int rv;
-
- rv = ec_command(EC_CMD_HOST_EVENT_GET_SMI_MASK, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current host event SMI mask: 0x%08x\n", r.mask);
- return 0;
-}
-
-
-int cmd_host_event_get_sci_mask(int argc, char *argv[])
-{
- struct ec_response_host_event_mask r;
- int rv;
-
- rv = ec_command(EC_CMD_HOST_EVENT_GET_SCI_MASK, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current host event SCI mask: 0x%08x\n", r.mask);
- return 0;
-}
-
-
-int cmd_host_event_get_wake_mask(int argc, char *argv[])
-{
- struct ec_response_host_event_mask r;
- int rv;
-
- rv = ec_command(EC_CMD_HOST_EVENT_GET_WAKE_MASK, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current host event wake mask: 0x%08x\n", r.mask);
- return 0;
-}
-
-
-int cmd_host_event_set_smi_mask(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_SET_SMI_MASK, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Mask set.\n");
- return 0;
-}
-
-
-int cmd_host_event_set_sci_mask(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_SET_SCI_MASK, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Mask set.\n");
- return 0;
-}
-
-
-int cmd_host_event_set_wake_mask(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_SET_WAKE_MASK, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Mask set.\n");
- return 0;
-}
-
-
-int cmd_host_event_clear(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_CLEAR, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Host events cleared.\n");
- return 0;
-}
-
-
-int cmd_host_event_clear_b(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_CLEAR_B, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Host events-B cleared.\n");
- return 0;
-}
-
-
-int cmd_switches(int argc, char *argv[])
-{
- uint8_t s = read_mapped_mem8(EC_MEMMAP_SWITCHES);
- printf("Current switches: 0x%02x\n", s);
- printf("Lid switch: %s\n",
- (s & EC_SWITCH_LID_OPEN ? "OPEN" : "CLOSED"));
- printf("Power button: %s\n",
- (s & EC_SWITCH_POWER_BUTTON_PRESSED ? "DOWN" : "UP"));
- printf("Write protect: %sABLED\n",
- (s & EC_SWITCH_WRITE_PROTECT_DISABLED ? "DIS" : "EN"));
- printf("Dedicated recovery: %sABLED\n",
- (s & EC_SWITCH_DEDICATED_RECOVERY ? "EN" : "DIS"));
-
- return 0;
-}
-
-
-int cmd_wireless(int argc, char *argv[])
-{
- char *e;
- int rv;
- int now_flags;
-
- if (argc < 2) {
- fprintf(stderr,
- "Usage: %s <flags> [<mask> [<susflags> <susmask>]]\n",
- argv[0]);
- fprintf(stderr, " 0x1 = WLAN radio\n"
- " 0x2 = Bluetooth radio\n"
- " 0x4 = WWAN power\n"
- " 0x8 = WLAN power\n");
- return -1;
- }
-
- now_flags = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad flags.\n");
- return -1;
- }
-
- if (argc < 3) {
- /* Old-style - current flags only */
- struct ec_params_switch_enable_wireless_v0 p;
-
- p.enabled = now_flags;
- rv = ec_command(EC_CMD_SWITCH_ENABLE_WIRELESS, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Success.\n");
- } else {
- /* New-style - masks and suspend flags */
- struct ec_params_switch_enable_wireless_v1 p;
- struct ec_response_switch_enable_wireless_v1 r;
-
- memset(&p, 0, sizeof(p));
-
- p.now_flags = now_flags;
-
- p.now_mask = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- if (argc > 4) {
- p.suspend_flags = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad suspend flags.\n");
- return -1;
- }
-
- p.suspend_mask = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad suspend mask.\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_SWITCH_ENABLE_WIRELESS,
- EC_VER_SWITCH_ENABLE_WIRELESS,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Now=0x%x, suspend=0x%x\n",
- r.now_flags, r.suspend_flags);
- }
-
- return 0;
-}
-
-
-int cmd_i2c_protect(int argc, char *argv[])
-{
- struct ec_params_i2c_passthru_protect p;
- char *e;
- int rv;
-
- if (argc != 2 && (argc != 3 || strcmp(argv[2], "status"))) {
- fprintf(stderr, "Usage: %s <port> [status]\n",
- argv[0]);
- return -1;
- }
-
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- if (argc == 3) {
- struct ec_response_i2c_passthru_protect r;
-
- p.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_STATUS;
-
- rv = ec_command(EC_CMD_I2C_PASSTHRU_PROTECT, 0, &p, sizeof(p),
- &r, sizeof(r));
-
- if (rv < 0)
- return rv;
-
- printf("I2C port %d: %s (%d)\n", p.port,
- r.status ? "Protected" : "Unprotected", r.status);
- } else {
- p.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE;
-
- rv = ec_command(EC_CMD_I2C_PASSTHRU_PROTECT, 0, &p, sizeof(p),
- NULL, 0);
-
- if (rv < 0)
- return rv;
- }
- return 0;
-}
-
-
-int do_i2c_xfer(unsigned int port, unsigned int addr,
- uint8_t *write_buf, int write_len,
- uint8_t **read_buf, int read_len) {
- struct ec_params_i2c_passthru *p =
- (struct ec_params_i2c_passthru *)ec_outbuf;
- struct ec_response_i2c_passthru *r =
- (struct ec_response_i2c_passthru *)ec_inbuf;
- struct ec_params_i2c_passthru_msg *msg = p->msg;
- uint8_t *pdata;
- int size;
- int rv;
-
- p->port = port;
- p->num_msgs = (read_len != 0) + (write_len != 0);
-
- size = sizeof(*p) + p->num_msgs * sizeof(*msg);
- if (size + write_len > ec_max_outsize) {
- fprintf(stderr, "Params too large for buffer\n");
- return -1;
- }
- if (sizeof(*r) + read_len > ec_max_insize) {
- fprintf(stderr, "Read length too big for buffer\n");
- return -1;
- }
-
- pdata = (uint8_t *)p + size;
- if (write_len) {
- msg->addr_flags = addr;
- msg->len = write_len;
-
- memcpy(pdata, write_buf, write_len);
- msg++;
- }
-
- if (read_len) {
- msg->addr_flags = addr | EC_I2C_FLAG_READ;
- msg->len = read_len;
- }
-
- rv = ec_command(EC_CMD_I2C_PASSTHRU, 0, p, size + write_len,
- r, sizeof(*r) + read_len);
- if (rv < 0)
- return rv;
-
- /* Parse response */
- if (r->i2c_status & (EC_I2C_STATUS_NAK | EC_I2C_STATUS_TIMEOUT)) {
- fprintf(stderr, "Transfer failed with status=0x%x\n",
- r->i2c_status);
- return -1;
- }
-
- if (rv < sizeof(*r) + read_len) {
- fprintf(stderr, "Truncated read response\n");
- return -1;
- }
-
- if (read_len)
- *read_buf = r->data;
-
- return 0;
-}
-
-static void cmd_i2c_help(void)
-{
- fprintf(stderr,
- " Usage: i2cread <8 | 16> <port> <addr8> <offset>\n"
- " Usage: i2cwrite <8 | 16> <port> <addr8> <offset> <data>\n"
- " Usage: i2cxfer <port> <addr7> <read_count> [bytes...]\n"
- " <port> i2c port number\n"
- " <addr8> 8-bit i2c address\n"
- " <addr7> 7-bit i2c address\n"
- " <offset> offset to read from or write to\n"
- " <data> data to write\n"
- " <read_count> number of bytes to read\n"
- " [bytes ...] data to write\n"
- );
-
-}
-
-int cmd_i2c_read(int argc, char *argv[])
-{
- unsigned int port, addr8, addr7;
- int read_len, write_len;
- uint8_t write_buf[1];
- uint8_t *read_buf = NULL;
- char *e;
- int rv;
-
- if (argc != 5) {
- cmd_i2c_help();
- return -1;
- }
-
- read_len = strtol(argv[1], &e, 0);
- if ((e && *e) || (read_len != 8 && read_len != 16)) {
- fprintf(stderr, "Bad read size.\n");
- return -1;
- }
- read_len = read_len / 8;
-
- port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- addr8 = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad address.\n");
- return -1;
- }
- addr7 = addr8 >> 1;
-
- write_buf[0] = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
- write_len = 1;
-
- rv = do_i2c_xfer(port, addr7, write_buf, write_len, &read_buf,
- read_len);
-
- if (rv < 0)
- return rv;
-
- printf("Read from I2C port %d at 0x%x offset 0x%x = 0x%x\n",
- port, addr8, write_buf[0], *(uint16_t *)read_buf);
- return 0;
-}
-
-
-int cmd_i2c_write(int argc, char *argv[])
-{
- unsigned int port, addr8, addr7;
- int write_len;
- uint8_t write_buf[3];
- char *e;
- int rv;
-
- if (argc != 6) {
- cmd_i2c_help();
- return -1;
- }
-
- write_len = strtol(argv[1], &e, 0);
- if ((e && *e) || (write_len != 8 && write_len != 16)) {
- fprintf(stderr, "Bad write size.\n");
- return -1;
- }
- /* Include offset (length 1) */
- write_len = 1 + write_len / 8;
-
- port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- addr8 = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad address.\n");
- return -1;
- }
- addr7 = addr8 >> 1;
-
- write_buf[0] = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
-
- *((uint16_t *)&write_buf[1]) = strtol(argv[5], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad data.\n");
- return -1;
- }
-
- rv = do_i2c_xfer(port, addr7, write_buf, write_len, NULL, 0);
-
- if (rv < 0)
- return rv;
-
- printf("Wrote 0x%x to I2C port %d at 0x%x offset 0x%x.\n",
- *((uint16_t *)&write_buf[1]), port, addr8, write_buf[0]);
- return 0;
-}
-
-int cmd_i2c_xfer(int argc, char *argv[])
-{
- unsigned int port, addr;
- int read_len, write_len;
- uint8_t *write_buf = NULL;
- uint8_t *read_buf;
- char *e;
- int rv, i;
-
- if (argc < 4) {
- cmd_i2c_help();
- return -1;
- }
-
- port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- addr = strtol(argv[2], &e, 0) & 0x7f;
- if (e && *e) {
- fprintf(stderr, "Bad peripheral address.\n");
- return -1;
- }
-
- read_len = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad read length.\n");
- return -1;
- }
-
- /* Skip over params to bytes to write */
- argc -= 4;
- argv += 4;
- write_len = argc;
-
- if (write_len) {
- write_buf = (uint8_t *)(malloc(write_len));
- if (write_buf == NULL)
- return -1;
- for (i = 0; i < write_len; i++) {
- write_buf[i] = strtol(argv[i], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad write byte %d\n", i);
- free(write_buf);
- return -1;
- }
- }
- }
-
- rv = do_i2c_xfer(port, addr, write_buf, write_len, &read_buf, read_len);
-
- if (write_len)
- free(write_buf);
-
- if (rv)
- return rv;
-
- if (read_len) {
- if (ascii_mode) {
- for (i = 0; i < read_len; i++)
- printf(isprint(read_buf[i]) ? "%c" : "\\x%02x",
- read_buf[i]);
- } else {
- printf("Read bytes:");
- for (i = 0; i < read_len; i++)
- printf(" %#02x", read_buf[i]);
- }
- printf("\n");
- } else {
- printf("Write successful.\n");
- }
-
- return 0;
-}
-
-static void cmd_locate_chip_help(const char *const cmd)
-{
- fprintf(stderr,
- "Usage: %s <type> <index>\n"
- " <type> is one of:\n"
- " 0: CBI_EEPROM\n"
- " 1: TCPCs\n"
- " <index> instance # of <type>\n",
- cmd);
-}
-
-static const char *bus_type[] = {
- "I2C",
- "EMBEDDED"
-};
-
-int cmd_locate_chip(int argc, char *argv[])
-{
- struct ec_params_locate_chip p;
- struct ec_response_locate_chip r = {0};
- char *e;
- int rv;
-
- if (argc != 3) {
- cmd_locate_chip_help(argv[0]);
- return -1;
- }
-
- p.type = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad type.\n");
- cmd_locate_chip_help(argv[0]);
- return -1;
- }
-
- p.index = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad index.\n");
- cmd_locate_chip_help(argv[0]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_LOCATE_CHIP, 0, &p, sizeof(p), &r, sizeof(r));
-
- if (rv == -EC_RES_INVALID_PARAM - EECRESULT) {
- fprintf(stderr, "Bus type %d not supported.\n", p.type);
- return rv;
- }
-
- if (rv == -EC_RES_UNAVAILABLE - EECRESULT) {
- fprintf(stderr, "Chip not found\n");
- return rv;
- }
-
- if (rv == -EC_RES_OVERFLOW - EECRESULT) {
- fprintf(stderr, "Index too large\n");
- return rv;
- }
-
- if (rv < 0)
- return rv;
-
- if (r.bus_type >= EC_BUS_TYPE_COUNT
- || r.bus_type >= ARRAY_SIZE(bus_type)) {
- fprintf(stderr, "Unknown bus type (%d)\n", r.bus_type);
- return -1;
- }
-
- /*
- * When changing the format of this print, make sure FAFT
- * (firmware_ECCbiEeprom) still passes. It may silently skip the test.
- */
- printf("Bus: %s; Port: %d; Address: 0x%02x (7-bit format)\n",
- bus_type[r.bus_type], r.i2c_info.port,
- I2C_STRIP_FLAGS(r.i2c_info.addr_flags));
-
- return 0;
-}
-
-int cmd_lcd_backlight(int argc, char *argv[])
-{
- struct ec_params_switch_enable_backlight p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <0|1>\n", argv[0]);
- return -1;
- }
- p.enabled = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_SWITCH_ENABLE_BKLIGHT, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Success.\n");
- return 0;
-}
-
-static void cmd_basestate_help(void)
-{
- fprintf(stderr,
- "Usage: ectool basestate [attach | detach | reset]\n");
-}
-
-int cmd_basestate(int argc, char *argv[])
-{
- struct ec_params_set_base_state p;
-
- if (argc != 2) {
- cmd_basestate_help();
- return -1;
- }
-
- if (!strncmp(argv[1], "attach", 6)) {
- p.cmd = EC_SET_BASE_STATE_ATTACH;
- } else if (!strncmp(argv[1], "detach", 6)) {
- p.cmd = EC_SET_BASE_STATE_DETACH;
- } else if (!strncmp(argv[1], "reset", 5)) {
- p.cmd = EC_SET_BASE_STATE_RESET;
- } else {
- cmd_basestate_help();
- return -1;
- }
-
- return ec_command(EC_CMD_SET_BASE_STATE, 0,
- &p, sizeof(p), NULL, 0);
-}
-
-int cmd_ext_power_limit(int argc, char *argv[])
-{
- /* Version 1 is used, no support for obsolete version 0 */
- struct ec_params_external_power_limit_v1 p;
- char *e;
-
- if (argc != 3) {
- fprintf(stderr,
- "Usage: %s <max_current_mA> <max_voltage_mV>\n",
- argv[0]);
- return -1;
- }
-
- p.current_lim = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad param1.\n");
- return -1;
- }
-
- p.voltage_lim = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad param2.\n");
- return -1;
- }
-
- /* Send version 1 of command */
- return ec_command(EC_CMD_EXTERNAL_POWER_LIMIT, 1, &p, sizeof(p),
- NULL, 0);
-}
-
-
-int cmd_charge_current_limit(int argc, char *argv[])
-{
- struct ec_params_current_limit p;
- int rv;
- char *e;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <max_current_mA>\n", argv[0]);
- return -1;
- }
-
- p.limit = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_CHARGE_CURRENT_LIMIT, 0, &p, sizeof(p),
- NULL, 0);
- return rv;
-}
-
-static void cmd_charge_control_help(const char *cmd, const char *msg)
-{
- if (msg)
- fprintf(stderr, "ERROR: %s\n", msg);
-
- fprintf(stderr,
- "\n"
- " Usage: %s\n"
- " Get current settings.\n"
- " Usage: %s normal|idle|discharge\n"
- " Set charge mode (and disable battery sustainer).\n"
- " Usage: %s normal <lower> <upper>\n"
- " Enable battery sustainer. <lower> and <upper> are battery SoC\n"
- " between which EC tries to keep the battery level.\n"
- "\n",
- cmd, cmd, cmd);
-}
-
-int cmd_charge_control(int argc, char *argv[])
-{
- struct ec_params_charge_control p;
- struct ec_response_charge_control r;
- int version = 2;
- const char * const charge_mode_text[] = EC_CHARGE_MODE_TEXT;
- char *e;
- int rv;
-
- if (!ec_cmd_version_supported(EC_CMD_CHARGE_CONTROL, 2))
- version = 1;
-
- if (argc == 1) {
- if (version < 2) {
- cmd_charge_control_help(argv[0],
- "Old EC doesn't support GET.");
- return -1;
- }
- p.cmd = EC_CHARGE_CONTROL_CMD_GET;
- rv = ec_command(EC_CMD_CHARGE_CONTROL, version,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "Command failed.\n");
- return rv;
- }
- printf("Charge mode = %s (%d)\n",
- r.mode < ARRAY_SIZE(charge_mode_text)
- ? charge_mode_text[r.mode] : "UNDEFINED",
- r.mode);
- printf("Battery sustainer = %s (%d%% ~ %d%%)\n",
- (r.sustain_soc.lower != -1 && r.sustain_soc.upper != -1)
- ? "on" : "off",
- r.sustain_soc.lower, r.sustain_soc.upper);
- return 0;
- }
-
- p.cmd = EC_CHARGE_CONTROL_CMD_SET;
- if (!strcasecmp(argv[1], "normal")) {
- p.mode = CHARGE_CONTROL_NORMAL;
- if (argc == 2) {
- p.sustain_soc.lower = -1;
- p.sustain_soc.upper = -1;
- } else if (argc == 4) {
- if (version < 2) {
- cmd_charge_control_help(argv[0],
- "Old EC doesn't support sustainer.");
- return -1;
- }
- p.sustain_soc.lower = strtol(argv[2], &e, 0);
- if (e && *e) {
- cmd_charge_control_help(argv[0],
- "Bad character in <lower>");
- return -1;
- }
- p.sustain_soc.upper = strtol(argv[3], &e, 0);
- if (e && *e) {
- cmd_charge_control_help(argv[0],
- "Bad character in <upper>");
- return -1;
- }
- } else {
- cmd_charge_control_help(argv[0], "Bad arguments");
- return -1;
- }
- } else if (!strcasecmp(argv[1], "idle")) {
- if (argc != 2) {
- cmd_charge_control_help(argv[0], "Bad arguments");
- return -1;
- }
- p.mode = CHARGE_CONTROL_IDLE;
- } else if (!strcasecmp(argv[1], "discharge")) {
- if (argc != 2) {
- cmd_charge_control_help(argv[0], "Bad arguments");
- return -1;
- }
- p.mode = CHARGE_CONTROL_DISCHARGE;
- } else {
- cmd_charge_control_help(argv[0], "Bad sub-command");
- return -1;
- }
-
- rv = ec_command(EC_CMD_CHARGE_CONTROL, version, &p, sizeof(p), NULL, 0);
- if (rv < 0) {
- fprintf(stderr, "Is AC connected?\n");
- return rv;
- }
-
- switch (p.mode) {
- case CHARGE_CONTROL_NORMAL:
- printf("Charge state machine is in normal mode%s.\n",
- (p.sustain_soc.lower == -1 || p.sustain_soc.upper == -1)
- ? "" : " with sustainer enabled");
- break;
- case CHARGE_CONTROL_IDLE:
- printf("Charge state machine force idle.\n");
- break;
- case CHARGE_CONTROL_DISCHARGE:
- printf("Charge state machine force discharge.\n");
- break;
- default:
- break;
- }
- return 0;
-}
-
-
-#define ST_CMD_SIZE ST_FLD_SIZE(ec_params_charge_state, cmd)
-#define ST_PRM_SIZE(SUBCMD) \
- (ST_CMD_SIZE + ST_FLD_SIZE(ec_params_charge_state, SUBCMD))
-#define ST_RSP_SIZE(SUBCMD) ST_FLD_SIZE(ec_response_charge_state, SUBCMD)
-
-/* Table of subcommand sizes for EC_CMD_CHARGE_STATE */
-static const struct {
- uint8_t to_ec_size;
- uint8_t from_ec_size;
-} cs_paramcount[] = {
- /* Order must match enum charge_state_command */
- { ST_CMD_SIZE, ST_RSP_SIZE(get_state) },
- { ST_PRM_SIZE(get_param), ST_RSP_SIZE(get_param) },
- { ST_PRM_SIZE(set_param), 0},
-};
-BUILD_ASSERT(ARRAY_SIZE(cs_paramcount) == CHARGE_STATE_NUM_CMDS);
-
-#undef ST_CMD_SIZE
-#undef ST_PRM_SIZE
-#undef ST_RSP_SIZE
-
-static int cs_do_cmd(struct ec_params_charge_state *to_ec,
- struct ec_response_charge_state *from_ec)
-{
- int rv;
- int cmd = to_ec->cmd;
-
- rv = ec_command(EC_CMD_CHARGE_STATE, 0,
- to_ec, cs_paramcount[cmd].to_ec_size,
- from_ec, cs_paramcount[cmd].from_ec_size);
-
- return (rv < 0 ? 1 : 0);
-}
-
-static const char * const base_params[] = {
- "chg_voltage",
- "chg_current",
- "chg_input_current",
- "chg_status",
- "chg_option",
- "limit_power",
-};
-BUILD_ASSERT(ARRAY_SIZE(base_params) == CS_NUM_BASE_PARAMS);
-
-static int cmd_charge_state(int argc, char **argv)
-{
- struct ec_params_charge_state param;
- struct ec_response_charge_state resp;
- uint32_t p, v;
- int i, r;
- char *e;
-
- if (argc > 1 && !strcasecmp(argv[1], "show")) {
- param.cmd = CHARGE_STATE_CMD_GET_STATE;
- r = cs_do_cmd(&param, &resp);
- if (r)
- return r;
- printf("ac = %d\n", resp.get_state.ac);
- printf("chg_voltage = %dmV\n", resp.get_state.chg_voltage);
- printf("chg_current = %dmA\n", resp.get_state.chg_current);
- printf("chg_input_current = %dmA\n",
- resp.get_state.chg_input_current);
- printf("batt_state_of_charge = %d%%\n",
- resp.get_state.batt_state_of_charge);
- return 0;
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "param")) {
- switch (argc) {
- case 3:
- if (!strcasecmp(argv[2], "help"))
- break;
- param.cmd = CHARGE_STATE_CMD_GET_PARAM;
- p = strtoull(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad param: %s\n", argv[2]);
- return -1;
- }
- param.get_param.param = p;
- r = cs_do_cmd(&param, &resp);
- if (r)
- return r;
- v = resp.get_param.value;
- if (p < CS_NUM_BASE_PARAMS)
- printf("%d (0x%x) # %s\n", v, v,
- base_params[p]);
- else
- printf("%d (0x%x)\n", v, v);
- return 0;
- case 4:
- param.cmd = CHARGE_STATE_CMD_SET_PARAM;
- p = strtoull(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad param: %s\n", argv[2]);
- return -1;
- }
- v = strtoull(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value: %s\n", argv[3]);
- return -1;
- }
- param.set_param.param = p;
- param.set_param.value = v;
- return cs_do_cmd(&param, &resp);
- }
-
- printf("base params:\n");
- for (i = 0; i < CS_NUM_BASE_PARAMS; i++)
- printf(" %d %s\n", i, base_params[i]);
- printf("custom profile params:\n");
- printf(" 0x%x - 0x%x\n", CS_PARAM_CUSTOM_PROFILE_MIN,
- CS_PARAM_CUSTOM_PROFILE_MAX);
-
- return 0;
- }
-
- printf("Usage:\n");
- printf(" %s show - show current state\n", argv[0]);
- printf(" %s param NUM [VALUE] - get/set param NUM\n", argv[0]);
- printf(" %s param help - show known param NUMs\n", argv[0]);
- return 0;
-}
-
-int cmd_gpio_get(int argc, char *argv[])
-{
- struct ec_params_gpio_get_v1 p_v1;
- struct ec_response_gpio_get_v1 r_v1;
- int i, rv, subcmd, num_gpios;
- int cmdver = 1;
-
- if (!ec_cmd_version_supported(EC_CMD_GPIO_GET, cmdver)) {
- struct ec_params_gpio_get p;
- struct ec_response_gpio_get r;
-
- /* Fall back to version 0 command */
- cmdver = 0;
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <GPIO name>\n", argv[0]);
- return -1;
- }
-
- if (strlen(argv[1]) + 1 > sizeof(p.name)) {
- fprintf(stderr, "GPIO name too long.\n");
- return -1;
- }
- strcpy(p.name, argv[1]);
-
- rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p,
- sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("GPIO %s = %d\n", p.name, r.val);
- return 0;
- }
-
- if (argc > 2 || (argc == 2 && !strcmp(argv[1], "help"))) {
- printf("Usage: %s [<subcmd> <GPIO name>]\n", argv[0]);
- printf("'gpioget <GPIO_NAME>' - Get value by name\n");
- printf("'gpioget count' - Get count of GPIOS\n");
- printf("'gpioget all' - Get info for all GPIOs\n");
- return -1;
- }
-
- /* Keeping it consistent with console command behavior */
- if (argc == 1)
- subcmd = EC_GPIO_GET_INFO;
- else if (!strcmp(argv[1], "count"))
- subcmd = EC_GPIO_GET_COUNT;
- else if (!strcmp(argv[1], "all"))
- subcmd = EC_GPIO_GET_INFO;
- else
- subcmd = EC_GPIO_GET_BY_NAME;
-
- if (subcmd == EC_GPIO_GET_BY_NAME) {
- p_v1.subcmd = EC_GPIO_GET_BY_NAME;
- if (strlen(argv[1]) + 1 > sizeof(p_v1.get_value_by_name.name)) {
- fprintf(stderr, "GPIO name too long.\n");
- return -1;
- }
- strcpy(p_v1.get_value_by_name.name, argv[1]);
-
- rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1,
- sizeof(p_v1), &r_v1, sizeof(r_v1));
-
- if (rv < 0)
- return rv;
-
- printf("GPIO %s = %d\n", p_v1.get_value_by_name.name,
- r_v1.get_value_by_name.val);
- return 0;
- }
-
- /* Need GPIO count for EC_GPIO_GET_COUNT or EC_GPIO_GET_INFO */
- p_v1.subcmd = EC_GPIO_GET_COUNT;
- rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1,
- sizeof(p_v1), &r_v1, sizeof(r_v1));
- if (rv < 0)
- return rv;
-
- if (subcmd == EC_GPIO_GET_COUNT) {
- printf("GPIO COUNT = %d\n", r_v1.get_count.val);
- return 0;
- }
-
- /* subcmd EC_GPIO_GET_INFO */
- num_gpios = r_v1.get_count.val;
- p_v1.subcmd = EC_GPIO_GET_INFO;
-
- for (i = 0; i < num_gpios; i++) {
- p_v1.get_info.index = i;
-
- rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1,
- sizeof(p_v1), &r_v1, sizeof(r_v1));
- if (rv < 0)
- return rv;
-
- printf("%2d %-32s 0x%04X\n", r_v1.get_info.val,
- r_v1.get_info.name, r_v1.get_info.flags);
- }
-
- return 0;
-}
-
-
-int cmd_gpio_set(int argc, char *argv[])
-{
- struct ec_params_gpio_set p;
- char *e;
- int rv;
-
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <GPIO name> <0 | 1>\n", argv[0]);
- return -1;
- }
-
- if (strlen(argv[1]) + 1 > sizeof(p.name)) {
- fprintf(stderr, "GPIO name too long.\n");
- return -1;
- }
- strcpy(p.name, argv[1]);
-
- p.val = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_GPIO_SET, 0, &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("GPIO %s set to %d\n", p.name, p.val);
- return 0;
-}
-
-void print_battery_flags(int flags)
-{
- printf(" Flags 0x%02x", flags);
- if (flags & EC_BATT_FLAG_AC_PRESENT)
- printf(" AC_PRESENT");
- if (flags & EC_BATT_FLAG_BATT_PRESENT)
- printf(" BATT_PRESENT");
- if (flags & EC_BATT_FLAG_DISCHARGING)
- printf(" DISCHARGING");
- if (flags & EC_BATT_FLAG_CHARGING)
- printf(" CHARGING");
- if (flags & EC_BATT_FLAG_LEVEL_CRITICAL)
- printf(" LEVEL_CRITICAL");
- printf("\n");
-}
-
-int get_battery_command(int index)
-{
- struct ec_params_battery_static_info static_p;
- struct ec_response_battery_static_info_v1 static_r;
- struct ec_params_battery_dynamic_info dynamic_p;
- struct ec_response_battery_dynamic_info dynamic_r;
- int rv;
-
- printf("Battery %d info:\n", index);
-
- static_p.index = index;
- rv = ec_command(EC_CMD_BATTERY_GET_STATIC, 1,
- &static_p, sizeof(static_p),
- &static_r, sizeof(static_r));
- if (rv < 0)
- return -1;
-
- dynamic_p.index = index;
- rv = ec_command(EC_CMD_BATTERY_GET_DYNAMIC, 0,
- &dynamic_p, sizeof(dynamic_p),
- &dynamic_r, sizeof(dynamic_r));
- if (rv < 0)
- return -1;
-
- if (dynamic_r.flags & EC_BATT_FLAG_INVALID_DATA) {
- printf(" Invalid data (not present?)\n");
- return -1;
- }
-
- if (!is_string_printable(static_r.manufacturer_ext))
- goto cmd_error;
- printf(" OEM name: %s\n", static_r.manufacturer_ext);
-
- if (!is_string_printable(static_r.model_ext))
- goto cmd_error;
- printf(" Model number: %s\n", static_r.model_ext);
-
- if (!is_string_printable(static_r.type_ext))
- goto cmd_error;
- printf(" Chemistry : %s\n", static_r.type_ext);
-
- if (!is_string_printable(static_r.serial_ext))
- goto cmd_error;
- printf(" Serial number: %s\n", static_r.serial_ext);
-
- if (!is_battery_range(static_r.design_capacity))
- goto cmd_error;
- printf(" Design capacity: %u mAh\n", static_r.design_capacity);
-
- if (!is_battery_range(dynamic_r.full_capacity))
- goto cmd_error;
- printf(" Last full charge: %u mAh\n", dynamic_r.full_capacity);
-
- if (!is_battery_range(static_r.design_voltage))
- goto cmd_error;
- printf(" Design output voltage %u mV\n", static_r.design_voltage);
-
- if (!is_battery_range(static_r.cycle_count))
- goto cmd_error;
- printf(" Cycle count %u\n", static_r.cycle_count);
-
- if (!is_battery_range(dynamic_r.actual_voltage))
- goto cmd_error;
- printf(" Present voltage %u mV\n", dynamic_r.actual_voltage);
-
- /* current can be negative */
- printf(" Present current %d mA\n", dynamic_r.actual_current);
-
- if (!is_battery_range(dynamic_r.remaining_capacity))
- goto cmd_error;
- printf(" Remaining capacity %u mAh\n",
- dynamic_r.remaining_capacity);
-
- if (!is_battery_range(dynamic_r.desired_voltage))
- goto cmd_error;
- printf(" Desired voltage %u mV\n", dynamic_r.desired_voltage);
-
- if (!is_battery_range(dynamic_r.desired_current))
- goto cmd_error;
- printf(" Desired current %u mA\n", dynamic_r.desired_current);
-
- print_battery_flags(dynamic_r.flags);
- return 0;
-
-cmd_error:
- fprintf(stderr, "Bad battery info value.\n");
- return -1;
-}
-
-int cmd_battery(int argc, char *argv[])
-{
- char batt_text[EC_MEMMAP_TEXT_MAX];
- int rv, val;
- char *e;
- int index = 0;
-
- if (argc > 2) {
- fprintf(stderr, "Usage: %s [index]\n", argv[0]);
- return -1;
- } else if (argc == 2) {
- index = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad battery index.\n");
- return -1;
- }
- }
-
- /*
- * Read non-primary batteries through hostcmd, and all batteries
- * if longer strings are supported for static info.
- */
- if (index > 0 ||
- ec_cmd_version_supported(EC_CMD_BATTERY_GET_STATIC, 1))
- return get_battery_command(index);
-
- val = read_mapped_mem8(EC_MEMMAP_BATTERY_VERSION);
- if (val < 1) {
- fprintf(stderr, "Battery version %d is not supported\n", val);
- return -1;
- }
-
- printf("Battery info:\n");
-
- rv = read_mapped_string(EC_MEMMAP_BATT_MFGR, batt_text,
- sizeof(batt_text));
- if (rv < 0 || !is_string_printable(batt_text))
- goto cmd_error;
- printf(" OEM name: %s\n", batt_text);
-
- rv = read_mapped_string(EC_MEMMAP_BATT_MODEL, batt_text,
- sizeof(batt_text));
- if (rv < 0 || !is_string_printable(batt_text))
- goto cmd_error;
- printf(" Model number: %s\n", batt_text);
-
- rv = read_mapped_string(EC_MEMMAP_BATT_TYPE, batt_text,
- sizeof(batt_text));
- if (rv < 0 || !is_string_printable(batt_text))
- goto cmd_error;
- printf(" Chemistry : %s\n", batt_text);
-
- rv = read_mapped_string(EC_MEMMAP_BATT_SERIAL, batt_text,
- sizeof(batt_text));
- printf(" Serial number: %s\n", batt_text);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_DCAP);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Design capacity: %u mAh\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_LFCC);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Last full charge: %u mAh\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_DVLT);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Design output voltage %u mV\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_CCNT);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Cycle count %u\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_VOLT);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Present voltage %u mV\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_RATE);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Present current %u mA\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_CAP);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Remaining capacity %u mAh\n", val);
-
- val = read_mapped_mem8(EC_MEMMAP_BATT_FLAG);
- print_battery_flags(val);
-
- return 0;
-cmd_error:
- fprintf(stderr, "Bad battery info value. Check protocol version.\n");
- return -1;
-}
-
-int cmd_battery_cut_off(int argc, char *argv[])
-{
- struct ec_params_battery_cutoff p;
- int cmd_version;
- int rv;
-
- memset(&p, 0, sizeof(p));
- if (ec_cmd_version_supported(EC_CMD_BATTERY_CUT_OFF, 1)) {
- cmd_version = 1;
- if (argc > 1) {
- if (!strcasecmp(argv[1], "at-shutdown")) {
- p.flags = EC_BATTERY_CUTOFF_FLAG_AT_SHUTDOWN;
- } else {
- fprintf(stderr, "Bad parameter: %s\n", argv[1]);
- return -1;
- }
- }
- } else {
- /* Fall back to version 0 command */
- cmd_version = 0;
- if (argc > 1) {
- if (!strcasecmp(argv[1], "at-shutdown")) {
- fprintf(stderr, "Explicit 'at-shutdown' ");
- fprintf(stderr, "parameter not supported.\n");
- } else {
- fprintf(stderr, "Bad parameter: %s\n", argv[1]);
- }
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_BATTERY_CUT_OFF, cmd_version, &p, sizeof(p),
- NULL, 0);
- rv = (rv < 0 ? rv : 0);
-
- if (rv < 0) {
- fprintf(stderr, "Failed to cut off battery, rv=%d\n", rv);
- fprintf(stderr, "It is expected if the rv is -%d "
- "(EC_RES_INVALID_COMMAND) if the battery "
- "doesn't support cut-off function.\n",
- EC_RES_INVALID_COMMAND);
- } else {
- printf("\n");
- printf("SUCCESS. The battery has arranged a cut-off.\n");
-
- if (cmd_version == 1 &&
- (p.flags & EC_BATTERY_CUTOFF_FLAG_AT_SHUTDOWN))
- printf("The battery will be cut off after shutdown.\n");
- else
- printf("The system should be shutdown immediately.\n");
-
- printf("\n");
- }
- return rv;
-}
-
-int cmd_battery_vendor_param(int argc, char *argv[])
-{
- struct ec_params_battery_vendor_param p;
- struct ec_response_battery_vendor_param r;
- char *e;
- int rv;
-
- if (argc < 3)
- goto cmd_battery_vendor_param_usage;
-
- if (!strcasecmp(argv[1], "get"))
- p.mode = BATTERY_VENDOR_PARAM_MODE_GET;
- else if (!strcasecmp(argv[1], "set"))
- p.mode = BATTERY_VENDOR_PARAM_MODE_SET;
- else
- goto cmd_battery_vendor_param_usage;
-
- p.param = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Invalid param.\n");
- goto cmd_battery_vendor_param_usage;
- }
-
- if (p.mode == BATTERY_VENDOR_PARAM_MODE_SET) {
- if (argc != 4) {
- fprintf(stderr, "Missing value.\n");
- goto cmd_battery_vendor_param_usage;
- }
-
- p.value = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Invalid value.\n");
- goto cmd_battery_vendor_param_usage;
- }
- }
-
- rv = ec_command(EC_CMD_BATTERY_VENDOR_PARAM, 0, &p, sizeof(p),
- &r, sizeof(r));
-
- if (rv < 0)
- return rv;
-
- printf("0x%08x\n", r.value);
-
- return 0;
-
-cmd_battery_vendor_param_usage:
- fprintf(stderr,
- "Usage:\t %s get <param>\n"
- "\t %s set <param> <value>\n",
- argv[0], argv[0]);
- return -1;
-}
-
-int cmd_board_version(int argc, char *argv[])
-{
- struct ec_response_board_version response;
- int rv;
-
- rv = ec_command(EC_CMD_GET_BOARD_VERSION, 0, NULL, 0, &response,
- sizeof(response));
- if (rv < 0)
- return rv;
-
- printf("%d\n", response.board_version);
- return rv;
-}
-
-static void cmd_cbi_help(char *cmd)
-{
- fprintf(stderr,
- " Usage: %s get <tag> [get_flag]\n"
- " Usage: %s set <tag> <value/string> <size> [set_flag]\n"
- " Usage: %s remove <tag> [set_flag]\n"
- " <tag> is one of:\n"
- " 0: BOARD_VERSION\n"
- " 1: OEM_ID\n"
- " 2: SKU_ID\n"
- " 3: DRAM_PART_NUM (string)\n"
- " 4: OEM_NAME (string)\n"
- " 5: MODEL_ID\n"
- " 6: FW_CONFIG\n"
- " 7: PCB_VENDOR\n"
- " 8: SSFC\n"
- " 9: REWORK_ID\n"
- " <size> is the size of the data in byte. It should be zero for\n"
- " string types.\n"
- " <value/string> is an integer or a string to be set\n"
- " [get_flag] is combination of:\n"
- " 01b: Invalidate cache and reload data from EEPROM\n"
- " [set_flag] is combination of:\n"
- " 01b: Skip write to EEPROM. Use for back-to-back writes\n"
- " 10b: Set all fields to defaults first\n", cmd, cmd, cmd);
-}
-
-static int cmd_cbi_is_string_field(enum cbi_data_tag tag)
-{
- return tag == CBI_TAG_DRAM_PART_NUM || tag == CBI_TAG_OEM_NAME;
-}
-
-/*
- * Write value to CBI
- *
- * TODO: Support asynchronous write
- */
-static int cmd_cbi(int argc, char *argv[])
-{
- enum cbi_data_tag tag;
- char *e;
- int rv;
-
- if (argc < 3) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cbi_help(argv[0]);
- return -1;
- }
-
- /* Tag */
- tag = (enum cbi_data_tag)(strtol(argv[2], &e, 0));
- if (e && *e) {
- fprintf(stderr, "Bad tag\n");
- return -1;
- }
-
- if (!strcasecmp(argv[1], "get")) {
- struct ec_params_get_cbi p = { 0 };
- int i;
-
- p.tag = tag;
- if (argc > 3) {
- p.flag = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad flag\n");
- return -1;
- }
- }
- rv = ec_command(EC_CMD_GET_CROS_BOARD_INFO, 0, &p, sizeof(p),
- ec_inbuf, ec_max_insize);
- if (rv < 0) {
- fprintf(stderr, "Error code: %d\n", rv);
- return rv;
- }
- if (rv < sizeof(uint8_t)) {
- fprintf(stderr, "Invalid size: %d\n", rv);
- return -1;
- }
- if (cmd_cbi_is_string_field(tag)) {
- printf("%.*s", rv, (const char *)ec_inbuf);
- } else {
- const uint8_t * const buffer =
- (const uint8_t *const)(ec_inbuf);
- uint64_t int_value = 0;
- for(i = 0; i < rv; i++)
- int_value |= (uint64_t)buffer[i] << (i * 8);
-
- printf("As uint: %llu (0x%llx)\n",
- (unsigned long long)int_value,
- (unsigned long long)int_value);
- printf("As binary:");
- for (i = 0; i < rv; i++) {
- if (i % 32 == 31)
- printf("\n");
- printf(" %02x", buffer[i]);
- }
- }
- printf("\n");
- return 0;
- } else if (!strcasecmp(argv[1], "set")) {
- struct ec_params_set_cbi *p =
- (struct ec_params_set_cbi *)ec_outbuf;
- void *val_ptr;
- uint64_t val = 0;
- uint8_t size;
- uint8_t bad_size = 0;
- if (argc < 5) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cbi_help(argv[0]);
- return -1;
- }
- memset(p, 0, ec_max_outsize);
- p->tag = tag;
-
- if (cmd_cbi_is_string_field(tag)) {
- val_ptr = argv[3];
- size = strlen((char *)(val_ptr)) + 1;
- } else {
- val = strtoul(argv[3], &e, 0);
- /* strtoul sets an errno for invalid input. If the value
- * read is out of range of representable values by an
- * unsigned long int, the function returns ULONG_MAX
- * or ULONG_MIN and the errno is set to ERANGE.
- */
- if ((e && *e) || errno == ERANGE) {
- fprintf(stderr, "Bad value\n");
- return -1;
- }
- size = strtol(argv[4], &e, 0);
- if (tag == CBI_TAG_REWORK_ID) {
- if ((e && *e) || size < 1 || size > 8 ||
- (size < 8 && val >= (1ull << size*8)))
- bad_size = 1;
- } else {
- if ((e && *e) || size < 1 || 4 < size ||
- val >= (1ull << size*8))
- bad_size = 1;
- }
- if (bad_size == 1) {
- fprintf(stderr, "Bad size: %d\n", size);
- return -1;
- }
-
- val_ptr = &val;
- }
-
- if (size > ec_max_outsize - sizeof(*p)) {
- fprintf(stderr, "Size exceeds parameter buffer: %d\n",
- size);
- return -1;
- }
- /* Little endian */
- memcpy(p->data, val_ptr, size);
- p->size = size;
- if (argc > 5) {
- p->flag = strtol(argv[5], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad flag\n");
- return -1;
- }
- }
- rv = ec_command(EC_CMD_SET_CROS_BOARD_INFO, 0,
- p, sizeof(*p) + size, NULL, 0);
- if (rv < 0) {
- if (rv == -EC_RES_ACCESS_DENIED - EECRESULT)
- fprintf(stderr, "Write-protect is enabled or "
- "EC explicitly refused to change the "
- "requested field.\n");
- else
- fprintf(stderr, "Error code: %d\n", rv);
- return rv;
- }
- return 0;
- } else if (!strcasecmp(argv[1], "remove")) {
- struct ec_params_set_cbi p = { 0 };
-
- p.tag = tag;
- p.size = 0;
- if (argc > 3) {
- p.flag = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad flag\n");
- return -1;
- }
- }
- rv = ec_command(EC_CMD_SET_CROS_BOARD_INFO, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0) {
- if (rv == -EC_RES_ACCESS_DENIED - EECRESULT)
- fprintf(stderr, "Write-protect is enabled or "
- "EC explicitly refused to change the "
- "requested field.\n");
- else
- fprintf(stderr, "Error code: %d\n", rv);
- return rv;
- }
- return 0;
- }
-
- fprintf(stderr, "Invalid sub command: %s\n", argv[1]);
- cmd_cbi_help(argv[0]);
-
- return -1;
-}
-
-int cmd_chipinfo(int argc, char *argv[])
-{
- struct ec_response_get_chip_info info;
- int rv;
-
- printf("Chip info:\n");
-
- rv = ec_command(EC_CMD_GET_CHIP_INFO, 0, NULL, 0, &info, sizeof(info));
- if (rv < 0)
- return rv;
- printf(" vendor: %s\n", info.vendor);
- printf(" name: %s\n", info.name);
- printf(" revision: %s\n", info.revision);
-
- return 0;
-}
-
-int cmd_proto_info(int argc, char *argv[])
-{
- struct ec_response_get_protocol_info info;
- int rv;
- int i;
-
- printf("Protocol info:\n");
-
- rv = ec_command(EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0,
- &info, sizeof(info));
- if (rv < 0) {
- fprintf(stderr, "Protocol info unavailable. EC probably only "
- "supports protocol version 2.\n");
- return rv;
- }
-
- printf(" protocol versions:");
- for (i = 0; i < 32; i++) {
- if (info.protocol_versions & BIT(i))
- printf(" %d", i);
- }
- printf("\n");
-
- printf(" max request: %4d bytes\n", info.max_request_packet_size);
- printf(" max response: %4d bytes\n", info.max_response_packet_size);
- printf(" flags: 0x%08x\n", info.flags);
- if (info.flags & EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED)
- printf(" EC_RES_IN_PROGRESS supported\n");
- return 0;
-}
-
-static int ec_hash_help(const char *cmd)
-{
- printf("Usage:\n");
- printf(" %s - get last hash\n", cmd);
- printf(" %s abort - abort hashing\n", cmd);
- printf(" %s start [<offset> <size> [<nonce>]] - start hashing\n", cmd);
- printf(" %s recalc [<offset> <size> [<nonce>]] - sync rehash\n", cmd);
- printf("\n"
- "If <offset> is RO or RW, offset and size are computed\n"
- "automatically for the EC-RO or EC-RW firmware image.\n");
-
- return 0;
-}
-
-
-static int ec_hash_print(const struct ec_response_vboot_hash *r)
-{
- int i;
-
- if (r->status == EC_VBOOT_HASH_STATUS_BUSY) {
- printf("status: busy\n");
- return 0;
- } else if (r->status == EC_VBOOT_HASH_STATUS_NONE) {
- printf("status: unavailable\n");
- return 0;
- } else if (r->status != EC_VBOOT_HASH_STATUS_DONE) {
- printf("status: %d\n", r->status);
- return 0;
- }
-
- printf("status: done\n");
- if (r->hash_type == EC_VBOOT_HASH_TYPE_SHA256)
- printf("type: SHA-256\n");
- else
- printf("type: %d\n", r->hash_type);
-
- printf("offset: 0x%08x\n", r->offset);
- printf("size: 0x%08x\n", r->size);
-
- printf("hash: ");
- for (i = 0; i < r->digest_size; i++)
- printf("%02x", r->hash_digest[i]);
- printf("\n");
- return 0;
-}
-
-
-int cmd_ec_hash(int argc, char *argv[])
-{
- struct ec_params_vboot_hash p;
- struct ec_response_vboot_hash r;
- char *e;
- int rv;
-
- memset(&p, 0, sizeof(p));
- if (argc < 2) {
- /* Get hash status */
- p.cmd = EC_VBOOT_HASH_GET;
- rv = ec_command(EC_CMD_VBOOT_HASH, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- return ec_hash_print(&r);
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "abort")) {
- /* Abort hash calculation */
- p.cmd = EC_VBOOT_HASH_ABORT;
- rv = ec_command(EC_CMD_VBOOT_HASH, 0,
- &p, sizeof(p), &r, sizeof(r));
- return (rv < 0 ? rv : 0);
- }
-
- /* The only other commands are start and recalc */
- if (!strcasecmp(argv[1], "start"))
- p.cmd = EC_VBOOT_HASH_START;
- else if (!strcasecmp(argv[1], "recalc"))
- p.cmd = EC_VBOOT_HASH_RECALC;
- else
- return ec_hash_help(argv[0]);
-
- p.hash_type = EC_VBOOT_HASH_TYPE_SHA256;
-
- if (argc < 3) {
- fprintf(stderr, "Must specify offset\n");
- return -1;
- }
-
- if (!strcasecmp(argv[2], "ro")) {
- p.offset = EC_VBOOT_HASH_OFFSET_RO;
- p.size = 0;
- printf("Hashing EC-RO...\n");
- } else if (!strcasecmp(argv[2], "rw")) {
- p.offset = EC_VBOOT_HASH_OFFSET_ACTIVE;
- p.size = 0;
- printf("Hashing EC-RW...\n");
- } else if (argc < 4) {
- fprintf(stderr, "Must specify size\n");
- return -1;
- } else {
- p.offset = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
- p.size = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
- printf("Hashing %d bytes at offset %d...\n", p.size, p.offset);
- }
-
- if (argc == 5) {
- /*
- * Technically nonce can be any binary data up to 64 bytes,
- * but this command only supports a 32-bit value.
- */
- uint32_t nonce = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad nonce integer.\n");
- return -1;
- }
- memcpy(p.nonce_data, &nonce, sizeof(nonce));
- p.nonce_size = sizeof(nonce);
- } else
- p.nonce_size = 0;
-
- rv = ec_command(EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- /* Start command doesn't wait for hashing to finish */
- if (p.cmd == EC_VBOOT_HASH_START)
- return 0;
-
- /* Recalc command does wait around, so a result is ready now */
- return ec_hash_print(&r);
-}
-
-
-int cmd_rtc_get(int argc, char *argv[])
-{
- struct ec_response_rtc r;
- int rv;
-
- rv = ec_command(EC_CMD_RTC_GET_VALUE, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current time: 0x%08x (%d)\n", r.time, r.time);
- return 0;
-}
-
-
-int cmd_rtc_set(int argc, char *argv[])
-{
- struct ec_params_rtc p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <time>\n", argv[0]);
- return -1;
- }
- p.time = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad time.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_RTC_SET_VALUE, 0, &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Time set.\n");
- return 0;
-}
-
-int cmd_rtc_set_alarm(int argc, char *argv[])
-{
- struct ec_params_rtc p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <sec>\n", argv[0]);
- return -1;
- }
- p.time = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad time.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_RTC_SET_ALARM, 0, &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- if (p.time == 0)
- printf("Disabling alarm.\n");
- else
- printf("Alarm set to go off in %d secs.\n", p.time);
- return 0;
-}
-
-int cmd_rtc_get_alarm(int argc, char *argv[])
-{
- struct ec_response_rtc r;
- int rv;
-
- rv = ec_command(EC_CMD_RTC_GET_ALARM, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- if (r.time == 0)
- printf("Alarm not set\n");
- else
- printf("Alarm to go off in %d secs\n", r.time);
- return 0;
-}
-
-int cmd_console(int argc, char *argv[])
-{
- char *out = (char *)ec_inbuf;
- int rv;
-
- /* Snapshot the EC console */
- rv = ec_command(EC_CMD_CONSOLE_SNAPSHOT, 0, NULL, 0, NULL, 0);
- if (rv < 0)
- return rv;
-
- /* Loop and read from the snapshot until it's done */
- while (1) {
- rv = ec_command(EC_CMD_CONSOLE_READ, 0,
- NULL, 0, ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- /* Empty response means done */
- if (!rv || !*out)
- break;
-
- /* Make sure output is null-terminated, then dump it */
- out[ec_max_insize - 1] = '\0';
- fputs(out, stdout);
- }
- printf("\n");
- return 0;
-}
-struct param_info {
- const char *name; /* name of this parameter */
- const char *help; /* help message */
- int size; /* size in bytes */
- int offset; /* offset within structure */
-};
-
-#define FIELD(fname, field, help_str) \
- { \
- .name = fname, \
- .help = help_str, \
- .size = sizeof(((struct ec_mkbp_config *)NULL)->field), \
- .offset = __builtin_offsetof(struct ec_mkbp_config, field), \
- }
-
-static const struct param_info keyconfig_params[] = {
- FIELD("scan_period", scan_period_us, "period between scans"),
- FIELD("poll_timeout", poll_timeout_us,
- "revert to irq mode after no activity for this long"),
- FIELD("min_post_scan_delay", min_post_scan_delay_us,
- "minimum post-scan delay before starting a new scan"),
- FIELD("output_settle", output_settle_us,
- "delay to wait for output to settle"),
- FIELD("debounce_down", debounce_down_us,
- "time for debounce on key down"),
- FIELD("debounce_up", debounce_up_us, "time for debounce on key up"),
- FIELD("fifo_max_depth", fifo_max_depth,
- "maximum depth to allow for fifo (0 = disable)"),
- FIELD("flags", flags, "0 to disable scanning, 1 to enable"),
-};
-
-static const struct param_info *find_field(const struct param_info *params,
- int count, const char *name, unsigned int *nump)
-{
- const struct param_info *param;
- int i;
-
- for (i = 0, param = params; i < count; i++, param++) {
- if (0 == strcmp(param->name, name)) {
- if (nump)
- *nump = i;
- return param;
- }
- }
-
- fprintf(stderr, "Unknown parameter '%s'\n", name);
- return NULL;
-}
-
-static int get_value(const struct param_info *param, const char *config)
-{
- const char *field;
-
- field = config + param->offset;
- switch (param->size) {
- case 1:
- return *(uint8_t *)field;
- case 2:
- return *(uint16_t *)field;
- case 4:
- return *(uint32_t *)field;
- default:
- fprintf(stderr, "Internal error: unknown size %d\n",
- param->size);
- }
-
- return -1;
-}
-
-static int show_fields(struct ec_mkbp_config *config, int argc, char *argv[])
-{
- const struct param_info *param;
- uint32_t mask;
- int i;
-
- if (!argc) {
- mask = -1U; /* show all fields */
- } else {
- mask = 0;
- while (argc > 0) {
- unsigned int num;
-
- param = find_field(keyconfig_params,
- ARRAY_SIZE(keyconfig_params),
- argv[0], &num);
- if (!param)
- return -1;
- mask |= 1 << num;
- argc--;
- argv++;
- }
- }
-
- param = keyconfig_params;
- for (i = 0; i < ARRAY_SIZE(keyconfig_params); i++, param++) {
- if (mask & BIT(i)) {
- fprintf(stderr, "%-12s %u\n", param->name,
- get_value(param, (char *)config));
- }
- }
-
- return 0;
-}
-
-static int cmd_kbinfo(int argc, char *argv[])
-{
- struct ec_params_mkbp_info info = {
- .info_type = EC_MKBP_INFO_KBD,
- };
- struct ec_response_mkbp_info resp;
- int rv;
-
- if (argc > 1) {
- fprintf(stderr, "Too many args\n");
- return -1;
- }
- rv = ec_command(EC_CMD_MKBP_INFO, 0, &info, sizeof(info), &resp,
- sizeof(resp));
- if (rv < 0)
- return rv;
-
- printf("Matrix rows: %d\n", resp.rows);
- printf("Matrix columns: %d\n", resp.cols);
-
- return 0;
-}
-
-static int cmd_kbid(int argc, char *argv[])
-{
- struct ec_response_keyboard_id response;
- int rv;
-
- if (argc > 1) {
- fprintf(stderr, "Too many args\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_GET_KEYBOARD_ID, 0, NULL, 0, &response,
- sizeof(response));
- if (rv < 0)
- return rv;
- switch (response.keyboard_id) {
- case KEYBOARD_ID_UNSUPPORTED:
- /* Keyboard ID was not supported */
- printf("Keyboard doesn't support ID\n");
- break;
- case KEYBOARD_ID_UNREADABLE:
- /* Ghosting ID was detected */
- printf("Reboot and keep hands off the keyboard during"
- " next boot-up\n");
- break;
- default:
- /* Valid keyboard ID value was reported*/
- printf("%x\n", response.keyboard_id);
- }
- return rv;
-}
-
-static int cmd_keyconfig(int argc, char *argv[])
-{
- struct ec_params_mkbp_set_config req;
- int cmd;
- int rv;
-
- if (argc < 2) {
- const struct param_info *param;
- int i;
-
- fprintf(stderr, "Usage: %s get [<param>] - print params\n"
- "\t%s set [<param>> <value>]\n"
- " Available params are: (all time values are in us)",
- argv[0], argv[0]);
-
- param = keyconfig_params;
- for (i = 0; i < ARRAY_SIZE(keyconfig_params); i++, param++) {
- fprintf(stderr, "%-12s %s\n", param->name,
- param->name);
- }
- return -1;
- }
-
- /* Get the command */
- if (0 == strcmp(argv[1], "get")) {
- cmd = EC_CMD_MKBP_GET_CONFIG;
- } else if (0 == strcmp(argv[1], "set")) {
- cmd = EC_CMD_MKBP_SET_CONFIG;
- } else {
- fprintf(stderr, "Invalid command '%s\n", argv[1]);
- return -1;
- }
-
- switch (cmd) {
- case EC_CMD_MKBP_GET_CONFIG:
- /* Read the existing config */
- rv = ec_command(cmd, 0, NULL, 0, &req, sizeof(req));
- if (rv < 0)
- return rv;
- show_fields(&req.config, argc - 2, argv + 2);
- break;
- }
-
- return 0;
-}
-
-static const char * const mkbp_button_strings[] = {
- [EC_MKBP_POWER_BUTTON] = "Power",
- [EC_MKBP_VOL_UP] = "Volume up",
- [EC_MKBP_VOL_DOWN] = "Volume down",
- [EC_MKBP_RECOVERY] = "Recovery",
-};
-
-static const char * const mkbp_switch_strings[] = {
- [EC_MKBP_LID_OPEN] = "Lid open",
- [EC_MKBP_TABLET_MODE] = "Tablet mode",
- [EC_MKBP_BASE_ATTACHED] = "Base attached",
-};
-
-static int cmd_mkbp_get(int argc, char *argv[])
-{
- struct ec_params_mkbp_info p;
- union ec_response_get_next_data r;
- int rv;
- int i;
- uint32_t supported;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <buttons|switches>\n", argv[0]);
- return -1;
- }
-
- if (strncmp(argv[1], "button", 6) == 0) {
- p.event_type = EC_MKBP_EVENT_BUTTON;
- } else if (strncmp(argv[1], "switch", 6) == 0) {
- p.event_type = EC_MKBP_EVENT_SWITCH;
- } else {
- fprintf(stderr, "Invalid param: '%s'\n", argv[1]);
- return -1;
- }
-
- p.info_type = EC_MKBP_INFO_SUPPORTED;
- rv = ec_command(EC_CMD_MKBP_INFO, 0, &p, sizeof(p), &r,
- sizeof(r));
- if (rv < 0)
- return rv;
- if (p.event_type == EC_MKBP_EVENT_BUTTON)
- supported = r.buttons;
- else if (p.event_type == EC_MKBP_EVENT_SWITCH)
- supported = r.switches;
- else
- return -1;
-
- p.info_type = EC_MKBP_INFO_CURRENT;
- rv = ec_command(EC_CMD_MKBP_INFO, 0, &p, sizeof(p), &r,
- sizeof(r));
- if (rv < 0)
- return rv;
-
- if (p.event_type == EC_MKBP_EVENT_BUTTON) {
- printf("MKBP buttons state: 0x%04x (supported: 0x%04x)\n",
- r.buttons, supported);
- for (i = 0; i < ARRAY_SIZE(mkbp_button_strings); i++) {
- if (supported & BIT(i) && mkbp_button_strings[i]) {
- printf("%s: %s\n", mkbp_button_strings[i],
- r.buttons & BIT(i) ? "ON" : "OFF");
- supported &= ~BIT(i);
- }
- }
- if (supported)
- printf("Unknown buttons: 0x%04x\n", supported);
- } else if (p.event_type == EC_MKBP_EVENT_SWITCH) {
- printf("MKBP switches state: 0x%04x (supported: 0x%04x)\n",
- r.switches, supported);
- for (i = 0; i < ARRAY_SIZE(mkbp_switch_strings); i++) {
- if (supported & BIT(i) && mkbp_switch_strings[i]) {
- printf("%s: %s\n", mkbp_switch_strings[i],
- r.switches & BIT(i) ? "ON" : "OFF");
- supported &= ~BIT(i);
- }
- }
- if (supported)
- printf("Unknown switches: 0x%04x\n", supported);
- }
-
- return 0;
-}
-
-static int cmd_mkbp_wake_mask(int argc, char *argv[])
-{
- struct ec_params_mkbp_event_wake_mask p;
- struct ec_response_mkbp_event_wake_mask r;
- int rv;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s get <event|hostevent>\n"
- "\t%s set <event|hostevent> <mask>\n", argv[0],
- argv[0]);
- return -1;
- }
-
- /* Determine if the user want to get or set the wake mask. */
- if (strncmp(argv[1], "get", 3) == 0) {
- p.action = GET_WAKE_MASK;
- } else if (strncmp(argv[1], "set", 3) == 0) {
- p.action = SET_WAKE_MASK;
- } else {
- fprintf(stderr, "Invalid param: '%s'\n", argv[1]);
- return -1;
- }
-
- /* Determine which mask is of interest. */
- if (strncmp(argv[2], "event", 5) == 0) {
- p.mask_type = EC_MKBP_EVENT_WAKE_MASK;
- } else if (strncmp(argv[2], "hostevent", 9) == 0) {
- p.mask_type = EC_MKBP_HOST_EVENT_WAKE_MASK;
- } else {
- fprintf(stderr, "Invalid param: '%s'\n", argv[2]);
- return -1;
- }
-
- if (p.action == SET_WAKE_MASK) {
- char *e;
-
- if (argc < 4) {
- fprintf(stderr, "Missing mask value!");
- return -1;
- }
-
- p.new_wake_mask = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask: '%s'", argv[1]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MKBP_WAKE_MASK, 0, &p, sizeof(p), &r,
- sizeof(r));
- if (rv < 0) {
- if (rv == -EECRESULT-EC_RES_INVALID_PARAM) {
- fprintf(stderr, "Unknown mask, or mask is not in use. "
- "You may need to enable the "
- "CONFIG_MKBP_%s_WAKEUP_MASK option in the EC.\n"
- , p.mask_type == EC_MKBP_EVENT_WAKE_MASK ?
- "EVENT" : "HOSTEVENT");
- }
- return rv;
- }
-
- if (p.action == GET_WAKE_MASK)
- printf("MBKP %s wake mask: 0x%08x\n", argv[2], r.wake_mask);
- else if (p.action == SET_WAKE_MASK)
- printf("MKBP %s wake mask set.\n", argv[2]);
-
- return 0;
-}
-
-/* Index is already checked. argv[0] is first param value */
-static int cmd_tmp006cal_v0(int idx, int argc, char *argv[])
-{
- struct ec_params_tmp006_get_calibration pg;
- struct ec_response_tmp006_get_calibration_v0 rg;
- struct ec_params_tmp006_set_calibration_v0 ps;
- float val;
- char *e;
- int i, rv;
-
- /* Get current values */
- pg.index = idx;
- rv = ec_command(EC_CMD_TMP006_GET_CALIBRATION, 0,
- &pg, sizeof(pg), &rg, sizeof(rg));
- if (rv < 0)
- return rv;
-
- if (!argc) {
- /* If no new values are given, just print what we have */
- printf("S0: %e\n", rg.s0);
- printf("b0: %e\n", rg.b0);
- printf("b1: %e\n", rg.b1);
- printf("b2: %e\n", rg.b2);
- return EC_SUCCESS;
- }
-
- /* Prepare to reuse the current values */
- memset(&ps, 0, sizeof(ps));
- ps.index = idx;
- ps.s0 = rg.s0;
- ps.b0 = rg.b0;
- ps.b1 = rg.b1;
- ps.b2 = rg.b2;
-
- /* Parse up to four args, skipping any that are just "-" */
- for (i = 0; i < argc && i < 4; i++) {
- if (!strcmp(argv[i], "-"))
- continue;
- val = strtod(argv[i], &e);
- if (e && *e) {
- fprintf(stderr,
- "Bad arg \"%s\". Use \"-\" to skip a param.\n",
- argv[i]);
- return -1;
- }
- switch (i) {
- case 0:
- ps.s0 = val;
- break;
- case 1:
- ps.b0 = val;
- break;
- case 2:
- ps.b1 = val;
- break;
- case 3:
- ps.b2 = val;
- break;
- }
- }
-
- /* Set 'em */
- return ec_command(EC_CMD_TMP006_SET_CALIBRATION, 0,
- &ps, sizeof(ps), NULL, 0);
-}
-
-/* Index is already checked. argv[0] is first param value */
-static int cmd_tmp006cal_v1(int idx, int argc, char *argv[])
-{
- struct ec_params_tmp006_get_calibration pg;
- struct ec_response_tmp006_get_calibration_v1 *rg =
- (struct ec_response_tmp006_get_calibration_v1 *)(ec_inbuf);
- struct ec_params_tmp006_set_calibration_v1 *ps =
- (struct ec_params_tmp006_set_calibration_v1 *)(ec_outbuf);
- float val;
- char *e;
- int i, rv, cmdsize;
-
- /* Algorithm 1 parameter names */
- static const char * const alg1_pname[] = {
- "s0", "a1", "a2", "b0", "b1", "b2", "c2",
- "d0", "d1", "ds", "e0", "e1",
- };
-
- /* Get current values */
- pg.index = idx;
- rv = ec_command(EC_CMD_TMP006_GET_CALIBRATION, 1,
- &pg, sizeof(pg), rg, ec_max_insize);
- if (rv < 0)
- return rv;
-
- if (!argc) {
- /* If no new values are given, just print what we have */
- printf("algorithm: %d\n", rg->algorithm);
- printf("params:\n");
- /* We only know about alg 1 at the moment */
- if (rg->algorithm == 1)
- for (i = 0; i < rg->num_params; i++)
- printf(" %s %e\n", alg1_pname[i], rg->val[i]);
- else
- for (i = 0; i < rg->num_params; i++)
- printf(" param%d %e\n", i, rg->val[i]);
- return EC_SUCCESS;
- }
-
- /* Prepare to reuse the current values */
- memset(ps, 0, ec_max_outsize);
- ps->index = idx;
- ps->algorithm = rg->algorithm;
- ps->num_params = rg->num_params;
- for (i = 0; i < rg->num_params; i++)
- ps->val[i] = rg->val[i];
-
- /* Parse the args, skipping any that are just "-" */
- for (i = 0; i < argc && i < rg->num_params; i++) {
- if (!strcmp(argv[i], "-"))
- continue;
- val = strtod(argv[i], &e);
- if (e && *e) {
- fprintf(stderr,
- "Bad arg \"%s\". Use \"-\" to skip a param.\n",
- argv[i]);
- return -1;
- }
- ps->val[i] = val;
- }
-
- /* Set 'em */
- cmdsize = sizeof(*ps) + ps->num_params * sizeof(ps->val[0]);
- return ec_command(EC_CMD_TMP006_SET_CALIBRATION, 1,
- ps, cmdsize, NULL, 0);
-}
-
-int cmd_tmp006cal(int argc, char *argv[])
-{
- char *e;
- int idx;
-
- if (argc < 2) {
- fprintf(stderr, "Must specify tmp006 index.\n");
- return -1;
- }
-
- idx = strtol(argv[1], &e, 0);
- if ((e && *e) || idx < 0 || idx > 255) {
- fprintf(stderr, "Bad index.\n");
- return -1;
- }
-
- /* Pass just the params (if any) to the helper function */
- argc -= 2;
- argv += 2;
-
- if (ec_cmd_version_supported(EC_CMD_TMP006_GET_CALIBRATION, 1))
- return cmd_tmp006cal_v1(idx, argc, argv);
-
- if (ec_cmd_version_supported(EC_CMD_TMP006_GET_CALIBRATION, 0))
- return cmd_tmp006cal_v0(idx, argc, argv);
-
- printf("The EC is being stupid\n");
- return -1;
-}
-
-int cmd_tmp006raw(int argc, char *argv[])
-{
- struct ec_params_tmp006_get_raw p;
- struct ec_response_tmp006_get_raw r;
- char *e;
- int idx;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Must specify tmp006 index.\n");
- return -1;
- }
-
- idx = strtol(argv[1], &e, 0);
- if ((e && *e) || idx < 0 || idx > 255) {
- fprintf(stderr, "Bad index.\n");
- return -1;
- }
-
- p.index = idx;
-
- rv = ec_command(EC_CMD_TMP006_GET_RAW, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("T: %d.%02d K\n", r.t / 100, r.t % 100);
- printf("V: %d nV\n", r.v);
- return EC_SUCCESS;
-}
-
-static int cmd_hang_detect(int argc, char *argv[])
-{
- struct ec_params_hang_detect req;
- char *e;
-
- memset(&req, 0, sizeof(req));
-
- if (argc == 2 && !strcasecmp(argv[1], "stop")) {
- req.flags = EC_HANG_STOP_NOW;
- return ec_command(EC_CMD_HANG_DETECT, 0, &req, sizeof(req),
- NULL, 0);
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "start")) {
- req.flags = EC_HANG_START_NOW;
- return ec_command(EC_CMD_HANG_DETECT, 0, &req, sizeof(req),
- NULL, 0);
- }
-
- if (argc == 4) {
- req.flags = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad flags.\n");
- return -1;
- }
-
- req.host_event_timeout_msec = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad event timeout.\n");
- return -1;
- }
-
- req.warm_reboot_timeout_msec = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad reboot timeout.\n");
- return -1;
- }
-
- printf("hang flags=0x%x\n"
- "event_timeout=%d ms\n"
- "reboot_timeout=%d ms\n",
- req.flags, req.host_event_timeout_msec,
- req.warm_reboot_timeout_msec);
-
- return ec_command(EC_CMD_HANG_DETECT, 0, &req, sizeof(req),
- NULL, 0);
- }
-
- fprintf(stderr,
- "Must specify start/stop or <flags> <event_ms> <reboot_ms>\n");
- return -1;
-}
-
-enum port_80_event {
- PORT_80_EVENT_RESUME = 0x1001, /* S3->S0 transition */
- PORT_80_EVENT_RESET = 0x1002, /* RESET transition */
-};
-
-int cmd_port80_read(int argc, char *argv[])
-{
- struct ec_params_port80_read p;
- int cmdver = 1, rv;
- int i, head, tail;
- uint16_t *history;
- uint32_t writes, history_size;
- struct ec_response_port80_read rsp;
- int printed = 0;
-
- if (!ec_cmd_version_supported(EC_CMD_PORT80_READ, cmdver)) {
- /* fall back to last boot */
- struct ec_response_port80_last_boot r;
- rv = ec_command(EC_CMD_PORT80_LAST_BOOT, 0,
- NULL, 0, &r, sizeof(r));
- fprintf(stderr, "Last boot %2x\n", r.code);
- printf("done.\n");
- return 0;
- }
-
-
- /* read writes and history_size */
- p.subcmd = EC_PORT80_GET_INFO;
- rv = ec_command(EC_CMD_PORT80_READ, cmdver,
- &p, sizeof(p), &rsp, sizeof(rsp));
- if (rv < 0) {
- fprintf(stderr, "Read error at writes\n");
- return rv;
- }
- writes = rsp.get_info.writes;
- history_size = rsp.get_info.history_size;
-
- history = (uint16_t *)(
- malloc(history_size * sizeof(uint16_t)));
- if (!history) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- return -1;
- }
- /* As the history buffer is quite large, we read data in chunks, with
- size in bytes of EC_PORT80_SIZE_MAX in each chunk.
- Incrementing offset until all history buffer has been read. To
- simplify the design, chose HISTORY_LEN is always multiple of
- EC_PORT80_SIZE_MAX.
-
- offset: entry offset from the beginning of history buffer.
- num_entries: number of entries requested.
- */
- p.subcmd = EC_PORT80_READ_BUFFER;
- for (i = 0; i < history_size; i += EC_PORT80_SIZE_MAX) {
- p.read_buffer.offset = i;
- p.read_buffer.num_entries = EC_PORT80_SIZE_MAX;
- rv = ec_command(EC_CMD_PORT80_READ, cmdver,
- &p, sizeof(p), &rsp, sizeof(rsp));
- if (rv < 0) {
- fprintf(stderr, "Read error at offset %d\n", i);
- free(history);
- return rv;
- }
- memcpy((void *)(history + i), rsp.data.codes,
- EC_PORT80_SIZE_MAX*sizeof(uint16_t));
- }
-
- head = writes;
- if (head > history_size)
- tail = head - history_size;
- else
- tail = 0;
-
- fprintf(stderr, "Port 80 writes");
- for (i = tail; i < head; i++) {
- int e = history[i % history_size];
- switch (e) {
- case PORT_80_EVENT_RESUME:
- fprintf(stderr, "\n(S3->S0)");
- printed = 0;
- break;
- case PORT_80_EVENT_RESET:
- fprintf(stderr, "\n(RESET)");
- printed = 0;
- break;
- default:
- if (!(printed++ % 20))
- fprintf(stderr, "\n ");
- fprintf(stderr, " %02x", e);
- }
- }
- fprintf(stderr, " <--new\n");
-
- free(history);
- printf("done.\n");
- return 0;
-}
-
-int cmd_force_lid_open(int argc, char *argv[])
-{
- struct ec_params_force_lid_open p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <0|1>\n", argv[0]);
- return -1;
- }
- p.enabled = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_FORCE_LID_OPEN, 0, &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
- printf("Success.\n");
- return 0;
-}
-
-int cmd_charge_port_override(int argc, char *argv[])
-{
- struct ec_params_charge_port_override p;
- char *e;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <port# | dontcharge | off>\n",
- argv[0]);
- return -1;
- }
-
- if (!strcasecmp(argv[1], "dontcharge"))
- p.override_port = OVERRIDE_DONT_CHARGE;
- else if (!strcasecmp(argv[1], "off"))
- p.override_port = OVERRIDE_OFF;
- else {
- p.override_port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad parameter.\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_PD_CHARGE_PORT_OVERRIDE, 0, &p, sizeof(p),
- NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Override port set to %d\n", p.override_port);
- return 0;
-}
-
-static void cmd_pchg_help(char *cmd)
-{
- fprintf(stderr,
- " Usage1: %s\n"
- " Print the number of ports.\n"
- "\n"
- " Usage2: %s <port>\n"
- " Print the status of <port>.\n"
- "\n"
- " Usage3: %s <port> reset\n"
- " Reset <port>.\n"
- "\n"
- " Usage4: %s <port> update <version> <addr1> <file1> <addr2> <file2> ...\n"
- " Update firmware of <port>.\n",
- cmd, cmd, cmd, cmd);
-}
-
-static int cmd_pchg_info(const struct ec_response_pchg *res)
-{
- static const char * const pchg_state_text[] = EC_PCHG_STATE_TEXT;
-
- BUILD_ASSERT(ARRAY_SIZE(pchg_state_text) == PCHG_STATE_COUNT);
-
- printf("State: %s (%d)\n", res->state < PCHG_STATE_COUNT
- ? pchg_state_text[res->state] : "UNDEF", res->state);
- printf("Battery: %u%%\n", res->battery_percentage);
- printf("Errors: 0x%x\n", res->error);
- printf("FW Version: 0x%x\n", res->fw_version);
- printf("Dropped events: %u\n", res->dropped_event_count);
- return 0;
-}
-
-static int cmd_pchg_wait_event(int port, uint32_t expected)
-{
- struct ec_response_get_next_event_v1 event;
- const long timeout = 5000;
- uint32_t *e = &event.data.host_event;
- int rv;
-
- rv = wait_event(EC_MKBP_EVENT_PCHG, &event, sizeof(event), timeout);
- if (rv < 0)
- return rv;
-
- if (EC_MKBP_PCHG_EVENT_TO_PORT(*e) == port) {
- if (*e & EC_MKBP_PCHG_UPDATE_ERROR) {
- fprintf(stderr, "\nReceived update error\n");
- return -1;
- }
- if (*e & expected)
- return 0;
- }
-
- fprintf(stderr, "\nExpected event=0x%x but received 0x%x\n",
- expected, *e);
- return -1;
-}
-
-static int cmd_pchg_update_open(int port, uint32_t version,
- uint32_t *block_size, uint32_t *crc)
-{
- struct ec_params_pchg_update *p =
- (struct ec_params_pchg_update *)(ec_outbuf);
- struct ec_response_pchg_update *r =
- (struct ec_response_pchg_update *)(ec_inbuf);
- int rv;
-
- /* Open session. */
- p->port = port;
- p->cmd = EC_PCHG_UPDATE_CMD_OPEN;
- p->version = version;
- rv = ec_command(EC_CMD_PCHG_UPDATE, 0, p, sizeof(*p), r, sizeof(*r));
- if (rv < 0) {
- fprintf(stderr, "\nFailed to open update session: %d\n", rv);
- return rv;
- }
-
- if (r->block_size + sizeof(*p) > ec_max_outsize) {
- fprintf(stderr, "\nBlock size (%d) is too large.\n",
- r->block_size);
- return -1;
- }
-
- rv = cmd_pchg_wait_event(port, EC_MKBP_PCHG_UPDATE_OPENED);
- if (rv)
- return rv;
-
- printf("Opened update session (port=%d ver=0x%x bsize=%d):\n",
- port, version, r->block_size);
-
- *block_size = r->block_size;
- crc32_ctx_init(crc);
-
- return 0;
-}
-
-static int cmd_pchg_update_write(int port, uint32_t address,
- const char *filename, uint32_t block_size,
- uint32_t *crc)
-{
- struct ec_params_pchg_update *p =
- (struct ec_params_pchg_update *)(ec_outbuf);
- FILE *fp;
- size_t len, total;
- int progress = 0;
- int rv;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "\nCan't open %s: %s\n",
- filename, strerror(errno));
- return -1;
- }
-
- fseek(fp, 0L, SEEK_END);
- total = ftell(fp);
- rewind(fp);
- printf("Writing %s (%zu bytes).\n", filename, total);
-
- p->cmd = EC_PCHG_UPDATE_CMD_WRITE;
- p->addr = address;
-
- /* Write firmware in blocks. */
- len = fread(p->data, 1, block_size, fp);
- while (len > 0) {
- int previous_progress = progress;
- int i;
-
- crc32_ctx_hash(crc, p->data, len);
- p->size = len;
- rv = ec_command(EC_CMD_PCHG_UPDATE, 0, p,
- sizeof(*p) + len, NULL, 0);
- if (rv < 0) {
- fprintf(stderr, "\nFailed to write FW: %d\n", rv);
- fclose(fp);
- return rv;
- }
-
- rv = cmd_pchg_wait_event(port, EC_MKBP_PCHG_WRITE_COMPLETE);
- if (rv)
- return rv;
-
- p->addr += len;
- progress = (p->addr - address) * 100 / total;
- for (i = 0; i < progress - previous_progress; i++) {
- printf("*");
- fflush(stdout);
- }
-
- len = fread(p->data, 1, block_size, fp);
- }
-
- printf("\n");
- fclose(fp);
-
- return 0;
-}
-
-static int cmd_pchg_update_close(int port, uint32_t *crc)
-{
- struct ec_params_pchg_update *p =
- (struct ec_params_pchg_update *)(ec_outbuf);
- int rv;
-
- p->cmd = EC_PCHG_UPDATE_CMD_CLOSE;
- p->crc32 = crc32_ctx_result(crc);
- rv = ec_command(EC_CMD_PCHG_UPDATE, 0, p, sizeof(*p), NULL, 0);
-
- if (rv < 0) {
- fprintf(stderr, "\nFailed to close update session: %d\n", rv);
- return rv;
- }
-
- rv = cmd_pchg_wait_event(port, EC_MKBP_PCHG_UPDATE_CLOSED);
- if (rv)
- return rv;
-
- printf("Firmware was updated successfully (CRC32=0x%x).\n", p->crc32);
-
- return 0;
-}
-
-static int cmd_pchg(int argc, char *argv[])
-{
- const size_t max_input_files = 8;
- int port, port_count;
- struct ec_response_pchg_count rcnt;
- struct ec_params_pchg p;
- struct ec_response_pchg r;
- char *e;
- int rv;
-
- rv = ec_command(EC_CMD_PCHG_COUNT, 0, NULL, 0, &rcnt, sizeof(rcnt));
- if (rv < 0) {
- fprintf(stderr, "\nFailed to get port count: %d\n", rv);
- return rv;
- }
- port_count = rcnt.port_count;
-
- if (argc == 1) {
- /* Usage.1 */
- printf("%d\n", port_count);
- return 0;
- }
-
- port = strtol(argv[1], &e, 0);
- if ((e && *e) || port >= port_count) {
- fprintf(stderr, "\nBad port index: %s\n", argv[1]);
- cmd_pchg_help(argv[0]);
- return -1;
- }
-
- p.port = port;
- rv = ec_command(EC_CMD_PCHG, 1, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "\nError code: %d\n", rv);
- return rv;
- }
-
- if (argc == 2) {
- /* Usage.2 */
- return cmd_pchg_info(&r);
- } else if (argc == 3 && !strcmp(argv[2], "reset")) {
- /* Usage.3 */
- struct ec_params_pchg_update *u =
- (struct ec_params_pchg_update *)(ec_outbuf);
-
- u->cmd = EC_PCHG_UPDATE_CMD_RESET_TO_NORMAL;
- rv = ec_command(EC_CMD_PCHG_UPDATE, 0, u, sizeof(*u), NULL, 0);
- if (rv < 0) {
- fprintf(stderr, "\nFailed to reset port %d: %d\n",
- port, rv);
- cmd_pchg_help(argv[0]);
- return rv;
- }
- printf("Reset port %d complete.\n", port);
- return 0;
- } else if (argc >= 6 && !strcmp(argv[2], "update")) {
- /*
- * Usage.4:
- * argv[3]: <version>
- * argv[4]: <addr1>
- * argv[5]: <file1>
- * argv[6]: <addr2>
- * argv[7]: <file2>
- * ...
- */
- uint32_t address, version;
- uint32_t block_size = 0;
- uint32_t crc;
- int i;
-
- if (argc > 4 + max_input_files * 2) {
- fprintf(stderr, "\nToo many input files.\n");
- return -1;
- }
-
- version = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "\nBad version: %s.\n", argv[3]);
- cmd_pchg_help(argv[0]);
- return -1;
- }
-
- rv = cmd_pchg_update_open(port, version, &block_size, &crc);
- if (rv < 0 || block_size == 0) {
- fprintf(stderr, "\nFailed to open update session: %d\n",
- rv);
- return -1;
- }
-
- /* Write files one by one. */
- for (i = 4; i + 1 < argc; i += 2) {
- address = strtol(argv[i], &e, 0);
- if (e && *e) {
- fprintf(stderr, "\nBad address: %s\n", argv[i]);
- cmd_pchg_help(argv[0]);
- return -1;
- }
- rv = cmd_pchg_update_write(port, address, argv[i+1],
- block_size, &crc);
- if (rv < 0) {
- fprintf(stderr,
- "\nFailed to write file '%s': %d",
- argv[i+i], rv);
- return -1;
- }
- }
-
- rv = cmd_pchg_update_close(port, &crc);
- if (rv < 0) {
- fprintf(stderr, "\nFailed to close update session: %d",
- rv);
- return -1;
- }
-
- return 0;
- }
-
- fprintf(stderr, "Invalid parameter\n\n");
- cmd_pchg_help(argv[0]);
-
- return -1;
-}
-
-int cmd_pd_log(int argc, char *argv[])
-{
- union {
- struct ec_response_pd_log r;
- uint32_t words[8]; /* space for the payload */
- } u;
- struct mcdp_info minfo;
- struct ec_response_usb_pd_power_info pinfo;
- int rv;
- unsigned long long milliseconds;
- unsigned seconds;
- time_t now;
- struct tm ltime;
- char time_str[64];
-
- while (1) {
- now = time(NULL);
- rv = ec_command(EC_CMD_PD_GET_LOG_ENTRY, 0,
- NULL, 0, &u, sizeof(u));
- if (rv < 0)
- return rv;
-
- if (u.r.type == PD_EVENT_NO_ENTRY) {
- printf("--- END OF LOG ---\n");
- break;
- }
-
- /* the timestamp is in 1024th of seconds */
- milliseconds = ((uint64_t)u.r.timestamp <<
- PD_LOG_TIMESTAMP_SHIFT) / 1000;
- /* the timestamp is the number of milliseconds in the past */
- seconds = (milliseconds + 999) / 1000;
- milliseconds -= seconds * 1000;
- now -= seconds;
- localtime_r(&now, &ltime);
- strftime(time_str, sizeof(time_str), "%F %T", &ltime);
- printf("%s.%03lld P%d ", time_str, -milliseconds,
- PD_LOG_PORT(u.r.size_port));
- if (u.r.type == PD_EVENT_MCU_CHARGE) {
- if (u.r.data & CHARGE_FLAGS_OVERRIDE)
- printf("override ");
- if (u.r.data & CHARGE_FLAGS_DELAYED_OVERRIDE)
- printf("pending_override ");
- memcpy(&pinfo.meas, u.r.payload,
- sizeof(struct usb_chg_measures));
- pinfo.dualrole = !!(u.r.data & CHARGE_FLAGS_DUAL_ROLE);
- pinfo.role = u.r.data & CHARGE_FLAGS_ROLE_MASK;
- pinfo.type = (u.r.data & CHARGE_FLAGS_TYPE_MASK)
- >> CHARGE_FLAGS_TYPE_SHIFT;
- pinfo.max_power = 0;
- print_pd_power_info(&pinfo);
- } else if (u.r.type == PD_EVENT_MCU_CONNECT) {
- printf("New connection\n");
- } else if (u.r.type == PD_EVENT_MCU_BOARD_CUSTOM) {
- printf("Board-custom event\n");
- } else if (u.r.type == PD_EVENT_ACC_RW_FAIL) {
- printf("RW signature check failed\n");
- } else if (u.r.type == PD_EVENT_PS_FAULT) {
- static const char * const fault_names[] = {
- "---", "OCP", "fast OCP", "OVP", "Discharge"
- };
- const char *fault = u.r.data < ARRAY_SIZE(fault_names) ?
- fault_names[u.r.data] : "???";
- printf("Power supply fault: %s\n", fault);
- } else if (u.r.type == PD_EVENT_VIDEO_DP_MODE) {
- printf("DP mode %sabled\n", (u.r.data == 1) ?
- "en" : "dis");
- } else if (u.r.type == PD_EVENT_VIDEO_CODEC) {
- memcpy(&minfo, u.r.payload,
- sizeof(struct mcdp_info));
- printf("HDMI info: family:%04x chipid:%04x "
- "irom:%d.%d.%d fw:%d.%d.%d\n",
- MCDP_FAMILY(minfo.family),
- MCDP_CHIPID(minfo.chipid),
- minfo.irom.major, minfo.irom.minor,
- minfo.irom.build, minfo.fw.major,
- minfo.fw.minor, minfo.fw.build);
- } else { /* Unknown type */
- int i;
- printf("Event %02x (%04x) [", u.r.type, u.r.data);
- for (i = 0; i < PD_LOG_SIZE(u.r.size_port); i++)
- printf("%02x ", u.r.payload[i]);
- printf("]\n");
- }
- }
-
- return 0;
-}
-
-int cmd_pd_control(int argc, char *argv[])
-{
- struct ec_params_pd_control p;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Missing parameter\n");
- return -1;
- }
-
- /* Parse command */
- if (!strcmp(argv[1], "reset"))
- p.subcmd = PD_RESET;
- else if (!strcmp(argv[1], "suspend"))
- p.subcmd = PD_SUSPEND;
- else if (!strcmp(argv[1], "resume"))
- p.subcmd = PD_RESUME;
- else if (!strcmp(argv[1], "disable"))
- p.subcmd = PD_CONTROL_DISABLE;
- else if (!strcmp(argv[1], "on") || !strcmp(argv[1], "chip_on"))
- p.subcmd = PD_CHIP_ON;
- else {
- fprintf(stderr, "Unknown command: %s\n", argv[1]);
- return -1;
- }
-
- if (argc == 2) {
- p.chip = 0;
- } else {
- char *e;
- p.chip = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port number '%s'.\n", argv[2]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_PD_CONTROL, 0, &p, sizeof(p), NULL, 0);
- return (rv < 0 ? rv : 0);
-}
-
-int cmd_pd_chip_info(int argc, char *argv[])
-{
- struct ec_params_pd_chip_info p;
- struct ec_response_pd_chip_info_v1 r;
- char *e;
- int rv;
- int cmdver = 1;
-
- if (argc < 2 || 3 < argc) {
- fprintf(stderr, "Usage: %s <port> [<live>]\n"
- "live parameter can take values 0 or 1\n"
- "0 -> Return hard-coded value for VID/PID and\n"
- " cached value for Firmware Version\n"
- "1 -> Return live chip value for VID/PID/FW Version\n",
- argv[0]);
- return -1;
- }
-
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port number.\n");
- return -1;
- }
-
- p.live = 0;
- if (argc == 3) {
- p.live = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid arg \"%s\"\n", argv[2]);
- return -1;
- }
- }
-
- if (!ec_cmd_version_supported(EC_CMD_PD_CHIP_INFO, cmdver))
- cmdver = 0;
-
- rv = ec_command(EC_CMD_PD_CHIP_INFO, cmdver, &p, sizeof(p), &r,
- sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("vendor_id: 0x%x\n", r.vendor_id);
- printf("product_id: 0x%x\n", r.product_id);
- printf("device_id: 0x%x\n", r.device_id);
-
- if (r.fw_version_number != -1)
- printf("fw_version: 0x%" PRIx64 "\n", r.fw_version_number);
- else
- printf("fw_version: UNSUPPORTED\n");
-
- if (cmdver >= 1)
- printf("min_req_fw_version: 0x%" PRIx64 "\n",
- r.min_req_fw_version_number);
- else
- printf("min_req_fw_version: UNSUPPORTED\n");
-
- return 0;
-}
-
-int cmd_pd_write_log(int argc, char *argv[])
-{
- struct ec_params_pd_write_log_entry p;
- char *e;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <log_type> <port>\n",
- argv[0]);
- return -1;
- }
-
- if (!strcasecmp(argv[1], "charge"))
- p.type = PD_EVENT_MCU_CHARGE;
- else {
- p.type = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad log_type parameter.\n");
- return -1;
- }
- }
-
- p.port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port parameter.\n");
- return -1;
- }
-
- return ec_command(EC_CMD_PD_WRITE_LOG_ENTRY, 0, &p, sizeof(p), NULL, 0);
-}
-
-int cmd_typec_control(int argc, char *argv[])
-{
- struct ec_params_typec_control p;
- long conversion_result;
- char *endptr;
- int rv;
-
- if (argc < 3) {
- fprintf(stderr,
- "Usage: %s <port> <command> [args]\n"
- " <port> is the type-c port to query\n"
- " <command> is one of:\n"
- " 0: Exit modes\n"
- " 1: Clear events\n"
- " args: <event mask>\n"
- " 2: Enter mode\n"
- " args: <0: DP, 1:TBT, 2:USB4>\n",
- argv[0]);
- return -1;
- }
-
- p.port = strtol(argv[1], &endptr, 0);
- if (endptr && *endptr) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- p.command = strtol(argv[2], &endptr, 0);
- if (endptr && *endptr) {
- fprintf(stderr, "Bad command\n");
- return -1;
- }
-
- switch (p.command) {
- case TYPEC_CONTROL_COMMAND_CLEAR_EVENTS:
- if (argc < 4) {
- fprintf(stderr, "Missing event mask\n");
- return -1;
- }
-
- p.clear_events_mask = strtol(argv[3], &endptr, 0);
- if (endptr && *endptr) {
- fprintf(stderr, "Bad event mask\n");
- return -1;
- }
- break;
- case TYPEC_CONTROL_COMMAND_ENTER_MODE:
- if (argc < 4) {
- fprintf(stderr, "Missing mode\n");
- return -1;
- }
-
- conversion_result = strtol(argv[3], &endptr, 0);
- if ((endptr && *endptr) || conversion_result > UINT8_MAX ||
- conversion_result < 0) {
- fprintf(stderr, "Bad mode\n");
- return -1;
- }
- p.mode_to_enter = conversion_result;
- }
-
- rv = ec_command(EC_CMD_TYPEC_CONTROL, 0, &p, sizeof(p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return -1;
-
- return 0;
-}
-
-int cmd_typec_discovery(int argc, char *argv[])
-{
- struct ec_params_typec_discovery p;
- struct ec_response_typec_discovery *r =
- (struct ec_response_typec_discovery *)ec_inbuf;
- char *e;
- int rv, i, j;
-
- if (argc < 3) {
- fprintf(stderr,
- "Usage: %s <port> <type>\n"
- " <port> is the type-c port to query\n"
- " <type> is one of:\n"
- " 0: SOP\n"
- " 1: SOP prime\n", argv[0]);
- return -1;
- }
-
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- p.partner_type = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad type\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_TYPEC_DISCOVERY, 0, &p, sizeof(p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return -1;
-
- if (r->identity_count == 0) {
- printf("No identity discovered\n");
- return 0;
- }
-
- printf("Identity VDOs:\n");
- for (i = 0; i < r->identity_count; i++)
- printf("0x%08x\n", r->discovery_vdo[i]);
-
- if (r->svid_count == 0) {
- printf("No SVIDs discovered\n");
- return 0;
- }
-
- for (i = 0; i < r->svid_count; i++) {
- printf("SVID 0x%04x Modes:\n", r->svids[i].svid);
- for (j = 0; j < r->svids[i].mode_count; j++)
- printf("0x%08x\n", r->svids[i].mode_vdo[j]);
- }
-
- return 0;
-}
-
-/* Print shared fields of sink and source cap PDOs */
-static inline void print_pdo_fixed(uint32_t pdo)
-{
- printf(" Fixed: %dmV %dmA %s%s%s%s",
- PDO_FIXED_VOLTAGE(pdo),
- PDO_FIXED_CURRENT(pdo),
- pdo & PDO_FIXED_DUAL_ROLE ? "DRP " : "",
- pdo & PDO_FIXED_UNCONSTRAINED ? "UP " : "",
- pdo & PDO_FIXED_COMM_CAP ? "USB " : "",
- pdo & PDO_FIXED_DATA_SWAP ? "DRD" : "");
-}
-
-static inline void print_pdo_battery(uint32_t pdo)
-{
- printf(" Battery: max %dmV min %dmV max %dmW\n",
- PDO_BATT_MAX_VOLTAGE(pdo),
- PDO_BATT_MIN_VOLTAGE(pdo),
- PDO_BATT_MAX_POWER(pdo));
-}
-
-static inline void print_pdo_variable(uint32_t pdo)
-{
- printf(" Variable: max %dmV min %dmV max %dmA\n",
- PDO_VAR_MAX_VOLTAGE(pdo),
- PDO_VAR_MIN_VOLTAGE(pdo),
- PDO_VAR_MAX_CURRENT(pdo));
-}
-
-static inline void print_pdo_augmented(uint32_t pdo)
-{
- printf(" Augmented: max %dmV min %dmV max %dmA\n",
- PDO_AUG_MAX_VOLTAGE(pdo),
- PDO_AUG_MIN_VOLTAGE(pdo),
- PDO_AUG_MAX_CURRENT(pdo));
-}
-
-int cmd_typec_status(int argc, char *argv[])
-{
- struct ec_params_typec_status p;
- struct ec_response_typec_status *r =
- (struct ec_response_typec_status *)ec_inbuf;
- char *endptr;
- int rv, i;
- const char *desc;
-
- if (argc != 2) {
- fprintf(stderr,
- "Usage: %s <port>\n"
- " <port> is the type-c port to query\n", argv[0]);
- return -1;
- }
-
- p.port = strtol(argv[1], &endptr, 0);
- if (endptr && *endptr) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_TYPEC_STATUS, 0, &p, sizeof(p),
- ec_inbuf, ec_max_insize);
- if (rv == -EC_RES_INVALID_COMMAND - EECRESULT)
- /* Fall back to PD_CONTROL to support older ECs */
- return cmd_usb_pd(argc, argv);
- else if (rv < 0)
- return -1;
-
- printf("Port C%d: %s, %s State:%s\n"
- "Role:%s %s%s, Polarity:CC%d\n",
- p.port,
- r->pd_enabled ? "enabled" : "disabled",
- r->dev_connected ? "connected" : "disconnected",
- r->tc_state,
- (r->power_role == PD_ROLE_SOURCE) ? "SRC" : "SNK",
- (r->data_role == PD_ROLE_DFP) ? "DFP" :
- (r->data_role == PD_ROLE_UFP) ? "UFP" : "",
- (r->vconn_role == PD_ROLE_VCONN_SRC) ? " VCONN" : "",
- (r->polarity % 2 + 1));
-
- switch (r->cc_state) {
- case PD_CC_NONE:
- desc = "None";
- break;
- case PD_CC_UFP_AUDIO_ACC:
- desc = "UFP Audio accessory";
- break;
- case PD_CC_UFP_DEBUG_ACC:
- desc = "UFP Debug accessory";
- break;
- case PD_CC_UFP_ATTACHED:
- desc = "UFP attached";
- break;
- case PD_CC_DFP_DEBUG_ACC:
- desc = "DFP Debug accessory";
- break;
- case PD_CC_DFP_ATTACHED:
- desc = "DFP attached";
- break;
- default:
- desc = "UNKNOWN";
- break;
- }
- printf("CC State: %s\n", desc);
-
- if (r->dp_pin) {
- switch (r->dp_pin) {
- case MODE_DP_PIN_A:
- desc = "A";
- break;
- case MODE_DP_PIN_B:
- desc = "B";
- break;
- case MODE_DP_PIN_C:
- desc = "C";
- break;
- case MODE_DP_PIN_D:
- desc = "D";
- break;
- case MODE_DP_PIN_E:
- desc = "E";
- break;
- case MODE_DP_PIN_F:
- desc = "F";
- break;
- default:
- desc = "UNKNOWN";
- break;
- }
- printf("DP pin mode: %s\n", desc);
- }
-
- if (r->mux_state) {
- printf("MUX: USB=%d DP=%d POLARITY=%s HPD_IRQ=%d HPD_LVL=%d\n"
- " SAFE=%d TBT=%d USB4=%d\n",
- !!(r->mux_state & USB_PD_MUX_USB_ENABLED),
- !!(r->mux_state & USB_PD_MUX_DP_ENABLED),
- (r->mux_state & USB_PD_MUX_POLARITY_INVERTED) ?
- "INVERTED" : "NORMAL",
- !!(r->mux_state & USB_PD_MUX_HPD_IRQ),
- !!(r->mux_state & USB_PD_MUX_HPD_LVL),
- !!(r->mux_state & USB_PD_MUX_SAFE_MODE),
- !!(r->mux_state & USB_PD_MUX_TBT_COMPAT_ENABLED),
- !!(r->mux_state & USB_PD_MUX_USB4_ENABLED));
- }
-
- printf("Port events: 0x%08x\n", r->events);
-
- if (r->sop_revision)
- printf("SOP PD Rev: %d.%d\n",
- PD_STATUS_REV_GET_MAJOR(r->sop_revision),
- PD_STATUS_REV_GET_MINOR(r->sop_revision));
-
- if (r->sop_prime_revision)
- printf("SOP' PD Rev: %d.%d\n",
- PD_STATUS_REV_GET_MAJOR(r->sop_prime_revision),
- PD_STATUS_REV_GET_MINOR(r->sop_prime_revision));
-
- for (i = 0; i < r->source_cap_count; i++) {
- /*
- * Bits 31:30 always indicate the type of PDO
- *
- * Table 6-7 PD Rev 3.0 Ver 2.0
- */
- uint32_t pdo = r->source_cap_pdos[i];
- int pdo_type = pdo & PDO_TYPE_MASK;
-
- if (i == 0)
- printf("Source Capabilities:\n");
-
- if (pdo_type == PDO_TYPE_FIXED) {
- print_pdo_fixed(pdo);
- printf("\n");
- } else if (pdo_type == PDO_TYPE_BATTERY) {
- print_pdo_battery(pdo);
- } else if (pdo_type == PDO_TYPE_VARIABLE) {
- print_pdo_variable(pdo);
- } else {
- print_pdo_augmented(pdo);
- }
- }
-
- for (i = 0; i < r->sink_cap_count; i++) {
- /*
- * Bits 31:30 always indicate the type of PDO
- *
- * Table 6-7 PD Rev 3.0 Ver 2.0
- */
- uint32_t pdo = r->sink_cap_pdos[i];
- int pdo_type = pdo & PDO_TYPE_MASK;
-
- if (i == 0)
- printf("Sink Capabilities:\n");
-
- if (pdo_type == PDO_TYPE_FIXED) {
- print_pdo_fixed(pdo);
- /* Note: FRS bits are reserved in PD 2.0 spec */
- printf("%s\n", pdo & PDO_FIXED_FRS_CURR_MASK ?
- "FRS" : "");
- } else if (pdo_type == PDO_TYPE_BATTERY) {
- print_pdo_battery(pdo);
- } else if (pdo_type == PDO_TYPE_VARIABLE) {
- print_pdo_variable(pdo);
- } else {
- print_pdo_augmented(pdo);
- }
- }
-
- return 0;
-}
-
-int cmd_tp_self_test(int argc, char* argv[])
-{
- int rv;
-
- rv = ec_command(EC_CMD_TP_SELF_TEST, 0, NULL, 0, NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Touchpad self test: %s\n",
- rv == EC_RES_SUCCESS ? "passed" : "failed");
-
- return rv;
-}
-
-int cmd_tp_frame_get(int argc, char* argv[])
-{
- int i, j;
- uint32_t remaining = 0, offset = 0;
- int rv = EC_SUCCESS;
- uint8_t *data;
- struct ec_response_tp_frame_info* r;
- struct ec_params_tp_frame_get p;
-
- data = (uint8_t *)(malloc(ec_max_insize));
- r = (struct ec_response_tp_frame_info *)(malloc(ec_max_insize));
-
- if (data == NULL || r == NULL) {
- fprintf(stderr, "Couldn't allocate memory.\n");
- free(r);
- free(data);
- return EC_ERROR_UNKNOWN;
- }
-
- rv = ec_command(EC_CMD_TP_FRAME_INFO, 0, NULL, 0, r, ec_max_insize);
- if (rv < 0) {
- fprintf(stderr, "Failed to get touchpad frame info.\n");
- goto err;
- }
-
- rv = ec_command(EC_CMD_TP_FRAME_SNAPSHOT, 0, NULL, 0, NULL, 0);
- if (rv < 0) {
- fprintf(stderr, "Failed to snapshot frame.\n");
- goto err;
- }
-
- for (i = 0; i < r->n_frames; i++) {
- p.frame_index = i;
- offset = 0;
- remaining = r->frame_sizes[i];
-
- while (remaining > 0) {
- p.offset = offset;
- p.size = MIN(remaining, ec_max_insize);
-
- rv = ec_command(EC_CMD_TP_FRAME_GET, 0,
- &p, sizeof(p), data, p.size);
- if (rv < 0) {
- fprintf(stderr, "Failed to get frame data "
- "at offset 0x%x\n", offset);
- goto err;
- }
-
- for (j = 0; j < p.size; j++)
- printf("%02x ", data[j]);
-
- offset += p.size;
- remaining -= p.size;
- }
- printf("\n");
- }
-
-err:
- free(data);
- free(r);
-
- return rv < 0;
-}
-
-int cmd_wait_event(int argc, char *argv[])
-{
- int rv, i;
- struct ec_response_get_next_event_v1 buffer;
- long timeout = 5000;
- long event_type;
- char *e;
-
- if (!ec_pollevent) {
- fprintf(stderr, "Polling for MKBP event not supported\n");
- return -EINVAL;
- }
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <type> [<timeout>]\n",
- argv[0]);
- return -1;
- }
-
- event_type = strtol(argv[1], &e, 0);
- if ((e && *e) || event_type < 0 || event_type >= EC_MKBP_EVENT_COUNT) {
- fprintf(stderr, "Bad event type '%s'.\n", argv[1]);
- return -1;
- }
- if (argc >= 3) {
- timeout = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad timeout value '%s'.\n", argv[2]);
- return -1;
- }
- }
-
- rv = wait_event(event_type, &buffer, sizeof(buffer), timeout);
- if (rv < 0)
- return rv;
-
- printf("MKBP event %d data: ", buffer.event_type);
- for (i = 0; i < rv - 1; ++i)
- printf("%02x ", buffer.data.key_matrix[i]);
- printf("\n");
-
- return 0;
-}
-
-static void cmd_cec_help(const char *cmd)
-{
- fprintf(stderr,
- " Usage: %s write [write bytes...]\n"
- " Write message on the CEC bus\n"
- " Usage: %s read [timeout]\n"
- " [timeout] in seconds\n"
- " Usage: %s get <param>\n"
- " Usage: %s set <param> <val>\n"
- " <param> is one of:\n"
- " address: CEC receive address\n"
- " <val> is the new CEC address\n"
- " enable: Enable or disable CEC\n"
- " <val> is 1 to enable, 0 to disable\n",
- cmd, cmd, cmd, cmd);
-
-}
-
-static int cmd_cec_write(int argc, char *argv[])
-{
- char *e;
- long val;
- int rv, i, msg_len;
- struct ec_params_cec_write p;
- struct ec_response_get_next_event_v1 buffer;
-
- if (argc < 3 || argc > 18) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cec_help(argv[0]);
- return -1;
- }
-
- msg_len = argc - 2;
- for (i = 0; i < msg_len; i++) {
- val = strtol(argv[i + 2], &e, 16);
- if (e && *e)
- return -1;
- if (val < 0 || val > 0xff)
- return -1;
- p.msg[i] = (uint8_t)val;
- }
-
- printf("Write to CEC: ");
- for (i = 0; i < msg_len; i++)
- printf("0x%02x ", p.msg[i]);
- printf("\n");
-
- rv = ec_command(EC_CMD_CEC_WRITE_MSG, 0, &p, msg_len, NULL, 0);
- if (rv < 0)
- return rv;
-
- rv = wait_event(EC_MKBP_EVENT_CEC_EVENT, &buffer, sizeof(buffer), 1000);
- if (rv < 0)
- return rv;
-
- if (buffer.data.cec_events & EC_MKBP_CEC_SEND_OK)
- return 0;
-
- if (buffer.data.cec_events & EC_MKBP_CEC_SEND_FAILED) {
- fprintf(stderr, "Send failed\n");
- return -1;
- }
-
- fprintf(stderr, "No send result received\n");
-
- return -1;
-}
-
-static int cmd_cec_read(int argc, char *argv[])
-{
- int i, rv;
- char *e;
- struct ec_response_get_next_event_v1 buffer;
- long timeout = 5000;
-
- if (!ec_pollevent) {
- fprintf(stderr, "Polling for MKBP event not supported\n");
- return -EINVAL;
- }
-
- if (argc >= 3) {
- timeout = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad timeout value '%s'.\n", argv[2]);
- return -1;
- }
- }
-
- rv = wait_event(EC_MKBP_EVENT_CEC_MESSAGE, &buffer,
- sizeof(buffer), timeout);
- if (rv < 0)
- return rv;
-
- printf("CEC data: ");
- for (i = 0; i < rv - 1; i++)
- printf("0x%02x ", buffer.data.cec_message[i]);
- printf("\n");
-
- return 0;
-}
-
-static int cec_cmd_from_str(const char *str)
-{
- if (!strcmp("address", str))
- return CEC_CMD_LOGICAL_ADDRESS;
- if (!strcmp("enable", str))
- return CEC_CMD_ENABLE;
- return -1;
-}
-
-static int cmd_cec_set(int argc, char *argv[])
-{
- char *e;
- struct ec_params_cec_set p;
- uint8_t val;
- int cmd;
-
- if (argc != 4) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cec_help(argv[0]);
- return -1;
- }
-
- val = (uint8_t)strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad parameter '%s'.\n", argv[3]);
- return -1;
- }
-
- cmd = cec_cmd_from_str(argv[2]);
- if (cmd < 0) {
- fprintf(stderr, "Invalid command '%s'.\n", argv[2]);
- return -1;
- }
- p.cmd = cmd;
- p.val = val;
-
- return ec_command(EC_CMD_CEC_SET,
- 0, &p, sizeof(p), NULL, 0);
-}
-
-
-static int cmd_cec_get(int argc, char *argv[])
-{
- int rv, cmd;
- struct ec_params_cec_get p;
- struct ec_response_cec_get r;
-
-
- if (argc != 3) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cec_help(argv[0]);
- return -1;
- }
-
- cmd = cec_cmd_from_str(argv[2]);
- if (cmd < 0) {
- fprintf(stderr, "Invalid command '%s'.\n", argv[2]);
- return -1;
- }
- p.cmd = cmd;
-
-
- rv = ec_command(EC_CMD_CEC_GET, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("%d\n", r.val);
-
- return 0;
-}
-
-int cmd_cec(int argc, char *argv[])
-{
- if (argc < 2) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cec_help(argv[0]);
- return -1;
- }
- if (!strcmp(argv[1], "write"))
- return cmd_cec_write(argc, argv);
- if (!strcmp(argv[1], "read"))
- return cmd_cec_read(argc, argv);
- if (!strcmp(argv[1], "get"))
- return cmd_cec_get(argc, argv);
- if (!strcmp(argv[1], "set"))
- return cmd_cec_set(argc, argv);
-
- fprintf(stderr, "Invalid sub command: %s\n", argv[1]);
- cmd_cec_help(argv[0]);
-
- return -1;
-}
-
-/* NULL-terminated list of commands */
-const struct command commands[] = {
- {"adcread", cmd_adc_read},
- {"addentropy", cmd_add_entropy},
- {"apreset", cmd_apreset},
- {"autofanctrl", cmd_thermal_auto_fan_ctrl},
- {"backlight", cmd_lcd_backlight},
- {"basestate", cmd_basestate},
- {"battery", cmd_battery},
- {"batterycutoff", cmd_battery_cut_off},
- {"batteryparam", cmd_battery_vendor_param},
- {"boardversion", cmd_board_version},
- {"button", cmd_button},
- {"cbi", cmd_cbi},
- {"chargecurrentlimit", cmd_charge_current_limit},
- {"chargecontrol", cmd_charge_control},
- {"chargeoverride", cmd_charge_port_override},
- {"chargestate", cmd_charge_state},
- {"chipinfo", cmd_chipinfo},
- {"cmdversions", cmd_cmdversions},
- {"console", cmd_console},
- {"cec", cmd_cec},
- {"echash", cmd_ec_hash},
- {"eventclear", cmd_host_event_clear},
- {"eventclearb", cmd_host_event_clear_b},
- {"eventget", cmd_host_event_get_raw},
- {"eventgetb", cmd_host_event_get_b},
- {"eventgetscimask", cmd_host_event_get_sci_mask},
- {"eventgetsmimask", cmd_host_event_get_smi_mask},
- {"eventgetwakemask", cmd_host_event_get_wake_mask},
- {"eventsetscimask", cmd_host_event_set_sci_mask},
- {"eventsetsmimask", cmd_host_event_set_smi_mask},
- {"eventsetwakemask", cmd_host_event_set_wake_mask},
- {"extpwrlimit", cmd_ext_power_limit},
- {"fanduty", cmd_fanduty},
- {"flasherase", cmd_flash_erase},
- {"flasheraseasync", cmd_flash_erase},
- {"flashprotect", cmd_flash_protect},
- {"flashread", cmd_flash_read},
- {"flashwrite", cmd_flash_write},
- {"flashinfo", cmd_flash_info},
- {"flashspiinfo", cmd_flash_spi_info},
- {"flashpd", cmd_flash_pd},
- {"forcelidopen", cmd_force_lid_open},
- {"fpcontext", cmd_fp_context},
- {"fpencstatus", cmd_fp_enc_status},
- {"fpframe", cmd_fp_frame},
- {"fpinfo", cmd_fp_info},
- {"fpmode", cmd_fp_mode},
- {"fpseed", cmd_fp_seed},
- {"fpstats", cmd_fp_stats},
- {"fptemplate", cmd_fp_template},
- {"gpioget", cmd_gpio_get},
- {"gpioset", cmd_gpio_set},
- {"hangdetect", cmd_hang_detect},
- {"hello", cmd_hello},
- {"hibdelay", cmd_hibdelay},
- {"hostevent", cmd_hostevent},
- {"hostsleepstate", cmd_hostsleepstate},
- {"locatechip", cmd_locate_chip},
- {"i2cprotect", cmd_i2c_protect},
- {"i2cread", cmd_i2c_read},
- {"i2cwrite", cmd_i2c_write},
- {"i2cxfer", cmd_i2c_xfer},
- {"infopddev", cmd_pd_device_info},
- {"inventory", cmd_inventory},
- {"led", cmd_led},
- {"lightbar", cmd_lightbar},
- {"kbfactorytest", cmd_keyboard_factory_test},
- {"kbid", cmd_kbid},
- {"kbinfo", cmd_kbinfo},
- {"kbpress", cmd_kbpress},
- {"keyconfig", cmd_keyconfig},
- {"keyscan", cmd_keyscan},
- {"mkbpget", cmd_mkbp_get},
- {"mkbpwakemask", cmd_mkbp_wake_mask},
- {"motionsense", cmd_motionsense},
- {"nextevent", cmd_next_event},
- {"panicinfo", cmd_panic_info},
- {"pause_in_s5", cmd_s5},
- {"pchg", cmd_pchg},
- {"pdgetmode", cmd_pd_get_amode},
- {"pdsetmode", cmd_pd_set_amode},
- {"port80read", cmd_port80_read},
- {"pdlog", cmd_pd_log},
- {"pdcontrol", cmd_pd_control},
- {"pdchipinfo", cmd_pd_chip_info},
- {"pdwritelog", cmd_pd_write_log},
- {"powerinfo", cmd_power_info},
- {"protoinfo", cmd_proto_info},
- {"pse", cmd_pse},
- {"pstoreinfo", cmd_pstore_info},
- {"pstoreread", cmd_pstore_read},
- {"pstorewrite", cmd_pstore_write},
- {"pwmgetfanrpm", cmd_pwm_get_fan_rpm},
- {"pwmgetkblight", cmd_pwm_get_keyboard_backlight},
- {"pwmgetnumfans", cmd_pwm_get_num_fans},
- {"pwmgetduty", cmd_pwm_get_duty},
- {"pwmsetfanrpm", cmd_pwm_set_fan_rpm},
- {"pwmsetkblight", cmd_pwm_set_keyboard_backlight},
- {"pwmsetduty", cmd_pwm_set_duty},
- {"rand", cmd_rand},
- {"readtest", cmd_read_test},
- {"reboot_ec", cmd_reboot_ec},
- {"rollbackinfo", cmd_rollback_info},
- {"rtcget", cmd_rtc_get},
- {"rtcgetalarm", cmd_rtc_get_alarm},
- {"rtcset", cmd_rtc_set},
- {"rtcsetalarm", cmd_rtc_set_alarm},
- {"rwhashpd", cmd_rw_hash_pd},
- {"rwsig", cmd_rwsig},
- {"rwsigaction", cmd_rwsig_action_legacy},
- {"rwsigstatus", cmd_rwsig_status},
- {"sertest", cmd_serial_test},
- {"smartdischarge", cmd_smart_discharge},
- {"stress", cmd_stress_test},
- {"sysinfo", cmd_sysinfo},
- {"port80flood", cmd_port_80_flood},
- {"switches", cmd_switches},
- {"temps", cmd_temperature},
- {"tempsinfo", cmd_temp_sensor_info},
- {"test", cmd_test},
- {"thermalget", cmd_thermal_get_threshold},
- {"thermalset", cmd_thermal_set_threshold},
- {"tpselftest", cmd_tp_self_test},
- {"tpframeget", cmd_tp_frame_get},
- {"tmp006cal", cmd_tmp006cal},
- {"tmp006raw", cmd_tmp006raw},
- {"typeccontrol", cmd_typec_control},
- {"typecdiscovery", cmd_typec_discovery},
- {"typecstatus", cmd_typec_status},
- {"uptimeinfo", cmd_uptimeinfo},
- {"usbchargemode", cmd_usb_charge_set_mode},
- {"usbmux", cmd_usb_mux},
- {"usbpd", cmd_usb_pd},
- {"usbpdmuxinfo", cmd_usb_pd_mux_info},
- {"usbpdpower", cmd_usb_pd_power},
- {"version", cmd_version},
- {"waitevent", cmd_wait_event},
- {"wireless", cmd_wireless},
- {"reboot_ap_on_g3", cmd_reboot_ap_on_g3},
- {NULL, NULL}
-};
-
-int main(int argc, char *argv[])
-{
- const struct command *cmd;
- int dev = 0;
- int interfaces = COMM_ALL;
- int i2c_bus = -1;
- char device_name[41] = CROS_EC_DEV_NAME;
- int rv = 1;
- int parse_error = 0;
- char *e;
- int i;
-
- BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS);
-
- while ((i = getopt_long(argc, argv, "?", long_opts, NULL)) != -1) {
- switch (i) {
- case '?':
- /* Unhandled option */
- parse_error = 1;
- break;
-
- case OPT_DEV:
- dev = strtoull(optarg, &e, 0);
- if (!*optarg || (e && *e)) {
- fprintf(stderr, "Invalid --dev\n");
- parse_error = 1;
- }
- break;
-
- case OPT_INTERFACE:
- if (!strcasecmp(optarg, "dev")) {
- interfaces = COMM_DEV;
- } else if (!strcasecmp(optarg, "lpc")) {
- interfaces = COMM_LPC;
- } else if (!strcasecmp(optarg, "i2c")) {
- interfaces = COMM_I2C;
- } else if (!strcasecmp(optarg, "servo")) {
- interfaces = COMM_SERVO;
- } else {
- fprintf(stderr, "Invalid --interface\n");
- parse_error = 1;
- }
- break;
- case OPT_NAME:
- strncpy(device_name, optarg, 40);
- device_name[40] = '\0';
- break;
- case OPT_I2C_BUS:
- i2c_bus = strtoull(optarg, &e, 0);
- if (*optarg == '\0' || (e && *e != '\0')
- || i2c_bus < 0) {
- fprintf(stderr, "Invalid --i2c_bus\n");
- parse_error = 1;
- }
- break;
- case OPT_ASCII:
- ascii_mode = 1;
- break;
- }
- }
-
- if (i2c_bus != -1) {
- if (!(interfaces & COMM_I2C)) {
- fprintf(stderr, "--i2c_bus is specified, but --interface is set to something other than I2C\n");
- parse_error = 1;
- } else {
- interfaces = COMM_I2C;
- }
- }
-
- /* Must specify a command */
- if (!parse_error && optind == argc)
- parse_error = 1;
-
- /* 'ectool help' prints help with commands */
- if (!parse_error && !strcasecmp(argv[optind], "help")) {
- print_help(argv[0], 1);
- exit(1);
- }
-
- /* Handle sub-devices command offset */
- if (dev > 0 && dev < 4) {
- set_command_offset(EC_CMD_PASSTHRU_OFFSET(dev));
- } else if (dev == 8) {
- /* Special offset for Fingerprint MCU */
- strcpy(device_name, "cros_fp");
- } else if (dev != 0) {
- fprintf(stderr, "Bad device number %d\n", dev);
- parse_error = 1;
- }
-
- if (parse_error) {
- print_help(argv[0], 0);
- exit(1);
- }
-
- /* Prefer /dev method, which supports built-in mutex */
- if (!(interfaces & COMM_DEV) || comm_init_dev(device_name)) {
- /* If dev is excluded or isn't supported, find alternative */
- if (acquire_gec_lock(GEC_LOCK_TIMEOUT_SECS) < 0) {
- fprintf(stderr, "Could not acquire GEC lock.\n");
- exit(1);
- }
- if (comm_init_alt(interfaces, device_name, i2c_bus)) {
- fprintf(stderr, "Couldn't find EC\n");
- goto out;
- }
- }
-
- if (comm_init_buffer()) {
- fprintf(stderr, "Couldn't initialize buffers\n");
- goto out;
- }
-
- /* Handle commands */
- for (cmd = commands; cmd->name; cmd++) {
- if (!strcasecmp(argv[optind], cmd->name)) {
- rv = cmd->handler(argc - optind, argv + optind);
- goto out;
- }
- }
-
- /* If we're still here, command was unknown */
- fprintf(stderr, "Unknown command '%s'\n\n", argv[optind]);
- print_help(argv[0], 0);
-
-out:
- release_gec_lock();
- return !!rv;
-}