summaryrefslogtreecommitdiff
path: root/common/ec_ec_comm_client.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /common/ec_ec_comm_client.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14528.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'common/ec_ec_comm_client.c')
-rw-r--r--common/ec_ec_comm_client.c371
1 files changed, 0 insertions, 371 deletions
diff --git a/common/ec_ec_comm_client.c b/common/ec_ec_comm_client.c
deleted file mode 100644
index c92433af8c..0000000000
--- a/common/ec_ec_comm_client.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* Copyright 2017 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.
- *
- * EC-EC communication, functions and definitions for client.
- */
-
-#include "battery.h"
-#include "common.h"
-#include "console.h"
-#include "crc8.h"
-#include "ec_commands.h"
-#include "ec_ec_comm_client.h"
-#include "timer.h"
-#include "uart.h"
-#include "util.h"
-
-/* Console output macros */
-#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
-
-/*
- * TODO(b:65697962): The packed structures below do not play well if we force EC
- * host commands structures to be aligned on 32-bit boundary. There are ways to
- * fix that, possibly requiring copying data around, or modifying
- * uart_alt_pad_write_read API to write the actual server response to a separate
- * buffer.
- */
-#ifdef CONFIG_HOSTCMD_ALIGNED
-#error "Cannot define CONFIG_HOSTCMD_ALIGNED with EC-EC communication client."
-#endif
-
-#define EC_EC_HOSTCMD_VERSION 4
-
-/* Print extra debugging information */
-#undef EXTRA_DEBUG
-
-/*
- * During early debugging, we would like to check that the error rate does
- * grow out of control.
- */
-#define DEBUG_EC_COMM_STATS
-#ifdef DEBUG_EC_COMM_STATS
-struct {
- int total;
- int errtimeout;
- int errbusy;
- int errunknown;
- int errdatacrc;
- int errcrc;
- int errinval;
-} comm_stats;
-
-#define INCR_COMM_STATS(var) (comm_stats.var++)
-#else
-#define INCR_COMM_STATS(var)
-#endif
-
-/**
- * Write a command on the EC-EC communication UART channel.
- *
- * @param command One of EC_CMD_*.
- * @param data Packed structure with this layout:
- * struct {
- * struct {
- * struct ec_host_request4 head;
- * struct ec_params_* param;
- * uint8_t crc8;
- * } req;
- * struct {
- * struct ec_host_response4 head;
- * struct ec_response_* info;
- * uint8_t crc8;
- * } resp;
- * } __packed data;
- *
- * Where req is the request to be transmitted (head and crc8 are computed by
- * this function), and resp is the response to be received (head integrity and
- * crc8 are verified by this function).
- *
- * This format is required as the EC-EC UART is half-duplex, and all the
- * transmitted data is received back, i.e. the client writes req, then reads
- * req, followed by resp.
- *
- * When a command does not take parameters, param/crc8 must be omitted in
- * tx structure. The same applies to rx structure if the response does not
- * include a payload: info/crc8 must be omitted.
- *
- * @param req_len size of req.param (0 if no parameter is passed).
- * @param resp_len size of resp.info (0 if no information is returned).
- * @param timeout_us timeout in microseconds for the transaction to complete.
- *
- * @return
- * - EC_SUCCESS on success.
- * - EC_ERROR_TIMEOUT when remote end times out replying.
- * - EC_ERROR_BUSY when UART is busy and cannot transmit currently.
- * - EC_ERROR_CRC when the header or data CRC is invalid.
- * - EC_ERROR_INVAL when the received header is invalid.
- * - EC_ERROR_UNKNOWN on other error.
- */
-static int write_command(uint16_t command,
- uint8_t *data, int req_len, int resp_len,
- int timeout_us)
-{
- /* Sequence number. */
- static uint8_t cur_seq;
- int ret;
- int hascrc, response_seq;
-
- struct ec_host_request4 *request_header = (void *)data;
- /* Request (TX) length is header + (data + crc8), response follows. */
- int tx_length =
- sizeof(*request_header) + ((req_len > 0) ? (req_len + 1) : 0);
-
- struct ec_host_response4 *response_header =
- (void *)&data[tx_length];
- /* RX length is TX length + response from server. */
- int rx_length = tx_length +
- sizeof(*request_header) + ((resp_len > 0) ? (resp_len + 1) : 0);
-
- /*
- * Make sure there is a gap between each command, so that the server
- * can recover its state machine after each command.
- *
- * TODO(b:65697962): We can be much smarter than this, and record the
- * last transaction time instead of just sleeping blindly.
- */
- usleep(10*MSEC);
-
-#ifdef DEBUG_EC_COMM_STATS
- if ((comm_stats.total % 128) == 0) {
- CPRINTF("UART %d (T%dB%d,U%dC%dD%dI%d)\n", comm_stats.total,
- comm_stats.errtimeout, comm_stats.errbusy,
- comm_stats.errunknown, comm_stats.errcrc,
- comm_stats.errdatacrc, comm_stats.errinval);
- }
-#endif
-
- cur_seq = (cur_seq + 1) &
- (EC_PACKET4_0_SEQ_NUM_MASK >> EC_PACKET4_0_SEQ_NUM_SHIFT);
-
- memset(request_header, 0, sizeof(*request_header));
- /* fields0: leave seq_dup and is_response as 0. */
- request_header->fields0 =
- EC_EC_HOSTCMD_VERSION | /* version */
- (cur_seq << EC_PACKET4_0_SEQ_NUM_SHIFT); /* seq_num */
- /* fields1: leave command_version as 0. */
- if (req_len > 0)
- request_header->fields1 |= EC_PACKET4_1_DATA_CRC_PRESENT_MASK;
- request_header->command = command;
- request_header->data_len = req_len;
- request_header->header_crc =
- cros_crc8((uint8_t *)request_header, sizeof(*request_header)-1);
- if (req_len > 0)
- data[sizeof(*request_header) + req_len] =
- cros_crc8(&data[sizeof(*request_header)], req_len);
-
- ret = uart_alt_pad_write_read((void *)data, tx_length,
- (void *)data, rx_length, timeout_us);
-
- INCR_COMM_STATS(total);
-
-#ifdef EXTRA_DEBUG
- CPRINTF("EC-EC ret=%d/%d\n", ret, rx_length);
-#endif
-
- if (ret != rx_length) {
- if (ret == -EC_ERROR_TIMEOUT) {
- INCR_COMM_STATS(errtimeout);
- return EC_ERROR_TIMEOUT;
- }
-
- if (ret == -EC_ERROR_BUSY) {
- INCR_COMM_STATS(errbusy);
- return EC_ERROR_BUSY;
- }
-
- INCR_COMM_STATS(errunknown);
- return EC_ERROR_UNKNOWN;
- }
-
- if (response_header->header_crc !=
- cros_crc8((uint8_t *)response_header,
- sizeof(*response_header) - 1)) {
- INCR_COMM_STATS(errcrc);
- return EC_ERROR_CRC;
- }
-
- hascrc = response_header->fields1 & EC_PACKET4_1_DATA_CRC_PRESENT_MASK;
- response_seq = (response_header->fields0 & EC_PACKET4_0_SEQ_NUM_MASK) >>
- EC_PACKET4_0_SEQ_NUM_SHIFT;
-
- /*
- * Validate received header.
- * Note that we _require_ data crc to be present if there is data to be
- * read back, else we would not know how many bytes to read exactly.
- */
- if ((response_header->fields0 & EC_PACKET4_0_STRUCT_VERSION_MASK)
- != EC_EC_HOSTCMD_VERSION ||
- !(response_header->fields0 &
- EC_PACKET4_0_IS_RESPONSE_MASK) ||
- response_seq != cur_seq ||
- (response_header->data_len > 0 && !hascrc) ||
- response_header->data_len != resp_len) {
- INCR_COMM_STATS(errinval);
- return EC_ERROR_INVAL;
- }
-
- /* Check data CRC. */
- if (hascrc &&
- data[rx_length - 1] !=
- cros_crc8(&data[tx_length + sizeof(*request_header)],
- resp_len)) {
- INCR_COMM_STATS(errdatacrc);
- return EC_ERROR_CRC;
- }
-
- return EC_SUCCESS;
-}
-
-/**
- * handle error from write_command
- *
- * @param ret is return value from write_command
- * @param request_result is data.resp.head.result (response result value)
- *
- * @return EC_RES_ERROR if ret is not EC_SUCCESS, else request_result.
- */
-static int handle_error(const char *func, int ret, int request_result)
-{
- if (ret != EC_SUCCESS) {
- /* Do not print busy errors as they just spam the console. */
- if (ret != EC_ERROR_BUSY)
- CPRINTF("%s: tx error %d\n", func, ret);
- return EC_RES_ERROR;
- }
-
- if (request_result != EC_RES_SUCCESS)
- CPRINTF("%s: cmd error %d\n", func, ret);
-
- return request_result;
-}
-
-#ifdef CONFIG_EC_EC_COMM_BATTERY
-int ec_ec_client_base_get_dynamic_info(void)
-{
- int ret;
- struct {
- struct {
- struct ec_host_request4 head;
- struct ec_params_battery_dynamic_info param;
- uint8_t crc8;
- } req;
- struct {
- struct ec_host_response4 head;
- struct ec_response_battery_dynamic_info info;
- uint8_t crc8;
- } resp;
- } __packed data;
-
- data.req.param.index = 0;
-
- ret = write_command(EC_CMD_BATTERY_GET_DYNAMIC,
- (void *)&data, sizeof(data.req.param),
- sizeof(data.resp.info), 15 * MSEC);
- ret = handle_error(__func__, ret, data.resp.head.result);
- if (ret != EC_RES_SUCCESS)
- return ret;
-
-#ifdef EXTRA_DEBUG
- CPRINTF("V: %d mV\n", data.resp.info.actual_voltage);
- CPRINTF("I: %d mA\n", data.resp.info.actual_current);
- CPRINTF("Remaining: %d mAh\n", data.resp.info.remaining_capacity);
- CPRINTF("Cap-full: %d mAh\n", data.resp.info.full_capacity);
- CPRINTF("Flags: %04x\n", data.resp.info.flags);
- CPRINTF("V-desired: %d mV\n", data.resp.info.desired_voltage);
- CPRINTF("I-desired: %d mA\n", data.resp.info.desired_current);
-#endif
-
- memcpy(&battery_dynamic[BATT_IDX_BASE], &data.resp.info,
- sizeof(battery_dynamic[BATT_IDX_BASE]));
- return EC_RES_SUCCESS;
-}
-
-int ec_ec_client_base_get_static_info(void)
-{
- int ret;
- struct {
- struct {
- struct ec_host_request4 head;
- struct ec_params_battery_static_info param;
- uint8_t crc8;
- } req;
- struct {
- struct ec_host_response4 head;
- struct ec_response_battery_static_info info;
- uint8_t crc8;
- } resp;
- } __packed data;
-
- data.req.param.index = 0;
-
- ret = write_command(EC_CMD_BATTERY_GET_STATIC,
- (void *)&data, sizeof(data.req.param),
- sizeof(data.resp.info), 15 * MSEC);
- ret = handle_error(__func__, ret, data.resp.head.result);
- if (ret != EC_RES_SUCCESS)
- return ret;
-
-#ifdef EXTRA_DEBUG
- CPRINTF("Cap-design: %d mAh\n", data.resp.info.design_capacity);
- CPRINTF("V-design: %d mV\n", data.resp.info.design_voltage);
- CPRINTF("Manuf: %s\n", data.resp.info.manufacturer);
- CPRINTF("Model: %s\n", data.resp.info.model);
- CPRINTF("Serial: %s\n", data.resp.info.serial);
- CPRINTF("Type: %s\n", data.resp.info.type);
- CPRINTF("C-count: %d\n", data.resp.info.cycle_count);
-#endif
-
- memcpy(&battery_static[BATT_IDX_BASE], &data.resp.info,
- sizeof(battery_static[BATT_IDX_BASE]));
- return EC_RES_SUCCESS;
-}
-
-int ec_ec_client_base_charge_control(int max_current,
- int otg_voltage,
- int allow_charging)
-{
- int ret;
- struct {
- struct {
- struct ec_host_request4 head;
- struct ec_params_charger_control ctrl;
- uint8_t crc8;
- } req;
- struct {
- struct ec_host_response4 head;
- } resp;
- } __packed data;
-
- data.req.ctrl.allow_charging = allow_charging;
- data.req.ctrl.max_current = max_current;
- data.req.ctrl.otg_voltage = otg_voltage;
-
- ret = write_command(EC_CMD_CHARGER_CONTROL,
- (void *)&data, sizeof(data.req.ctrl), 0, 30 * MSEC);
-
- return handle_error(__func__, ret, data.resp.head.result);
-}
-
-int ec_ec_client_hibernate(void)
-{
- int ret;
- struct {
- struct {
- struct ec_host_request4 head;
- struct ec_params_reboot_ec param;
- } req;
- struct {
- struct ec_host_response4 head;
- } resp;
- } __packed data;
-
- data.req.param.cmd = EC_REBOOT_HIBERNATE;
- data.req.param.flags = 0;
-
- ret = write_command(EC_CMD_REBOOT_EC,
- (void *)&data, sizeof(data.req.param), 0, 30 * MSEC);
-
- return handle_error(__func__, ret, data.resp.head.result);
-}
-#endif /* CONFIG_EC_EC_COMM_BATTERY */