// SPDX-License-Identifier: GPL-2.0 // ChromeOS EC communication protocol helper functions // // Copyright (C) 2015 Google, Inc #include <linux/delay.h> #include <linux/device.h> #include <linux/limits.h> #include <linux/module.h> #include <linux/platform_data/cros_ec_commands.h> #include <linux/platform_data/cros_ec_proto.h> #include <linux/slab.h> #include <asm/unaligned.h> #include "cros_ec_trace.h" #define EC_COMMAND_RETRIES … static const int cros_ec_error_map[] = …; static int cros_ec_map_error(uint32_t result) { … } static int prepare_tx(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { … } static int prepare_tx_legacy(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { … } static int cros_ec_xfer_command(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { … } static int cros_ec_wait_until_complete(struct cros_ec_device *ec_dev, uint32_t *result) { … } static int cros_ec_send_command(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { … } /** * cros_ec_prepare_tx() - Prepare an outgoing message in the output buffer. * @ec_dev: Device to register. * @msg: Message to write. * * This is used by all ChromeOS EC drivers to prepare the outgoing message * according to different protocol versions. * * Return: number of prepared bytes on success or negative error code. */ int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { … } EXPORT_SYMBOL(…); /** * cros_ec_check_result() - Check ec_msg->result. * @ec_dev: EC device. * @msg: Message to check. * * This is used by ChromeOS EC drivers to check the ec_msg->result for * EC_RES_IN_PROGRESS and to warn about them. * * The function should not check for furthermore error codes. Otherwise, * it would break the ABI. * * Return: -EAGAIN if ec_msg->result == EC_RES_IN_PROGRESS. Otherwise, 0. */ int cros_ec_check_result(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { … } EXPORT_SYMBOL(…); /** * cros_ec_get_host_event_wake_mask * * Get the mask of host events that cause wake from suspend. * * @ec_dev: EC device to call * @mask: result when function returns 0. * * LOCKING: * the caller has ec_dev->lock mutex, or the caller knows there is * no other command in progress. */ static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev, uint32_t *mask) { … } static int cros_ec_get_proto_info(struct cros_ec_device *ec_dev, int devidx) { … } static int cros_ec_get_proto_info_legacy(struct cros_ec_device *ec_dev) { … } /** * cros_ec_get_host_command_version_mask * * Get the version mask of a given command. * * @ec_dev: EC device to call * @cmd: command to get the version of. * @mask: result when function returns 0. * * @return 0 on success, error code otherwise * * LOCKING: * the caller has ec_dev->lock mutex or the caller knows there is * no other command in progress. */ static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, u16 cmd, u32 *mask) { … } /** * cros_ec_query_all() - Query the protocol version supported by the * ChromeOS EC. * @ec_dev: Device to register. * * Return: 0 on success or negative error code. */ int cros_ec_query_all(struct cros_ec_device *ec_dev) { … } EXPORT_SYMBOL(…); /** * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC. * @ec_dev: EC device. * @msg: Message to write. * * Call this to send a command to the ChromeOS EC. This should be used instead * of calling the EC's cmd_xfer() callback directly. This function does not * convert EC command execution error codes to Linux error codes. Most * in-kernel users will want to use cros_ec_cmd_xfer_status() instead since * that function implements the conversion. * * Return: * >0 - EC command was executed successfully. The return value is the number * of bytes returned by the EC (excluding the header). * =0 - EC communication was successful. EC command execution results are * reported in msg->result. The result will be EC_RES_SUCCESS if the * command was executed successfully or report an EC command execution * error. * <0 - EC communication error. Return value is the Linux error code. */ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { … } EXPORT_SYMBOL(…); /** * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. * @ec_dev: EC device. * @msg: Message to write. * * Call this to send a command to the ChromeOS EC. This should be used instead of calling the EC's * cmd_xfer() callback directly. It returns success status only if both the command was transmitted * successfully and the EC replied with success status. * * Return: * >=0 - The number of bytes transferred. * <0 - Linux error code */ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { … } EXPORT_SYMBOL(…); static int get_next_event_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg, struct ec_response_get_next_event_v3 *event, int version, uint32_t size) { … } static int get_next_event(struct cros_ec_device *ec_dev) { … } static int get_keyboard_state_event(struct cros_ec_device *ec_dev) { … } /** * cros_ec_get_next_event() - Fetch next event from the ChromeOS EC. * @ec_dev: Device to fetch event from. * @wake_event: Pointer to a bool set to true upon return if the event might be * treated as a wake event. Ignored if null. * @has_more_events: Pointer to bool set to true if more than one event is * pending. * Some EC will set this flag to indicate cros_ec_get_next_event() * can be called multiple times in a row. * It is an optimization to prevent issuing a EC command for * nothing or wait for another interrupt from the EC to process * the next message. * Ignored if null. * * Return: negative error code on errors; 0 for no data; or else number of * bytes received (i.e., an event was retrieved successfully). Event types are * written out to @ec_dev->event_data.event_type on success. */ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event, bool *has_more_events) { … } EXPORT_SYMBOL(…); /** * cros_ec_get_host_event() - Return a mask of event set by the ChromeOS EC. * @ec_dev: Device to fetch event from. * * When MKBP is supported, when the EC raises an interrupt, we collect the * events raised and call the functions in the ec notifier. This function * is a helper to know which events are raised. * * Return: 0 on error or non-zero bitmask of one or more EC_HOST_EVENT_*. */ u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev) { … } EXPORT_SYMBOL(…); /** * cros_ec_check_features() - Test for the presence of EC features * * @ec: EC device, does not have to be connected directly to the AP, * can be daisy chained through another device. * @feature: One of ec_feature_code bit. * * Call this function to test whether the ChromeOS EC supports a feature. * * Return: true if supported, false if not (or if an error was encountered). */ bool cros_ec_check_features(struct cros_ec_dev *ec, int feature) { … } EXPORT_SYMBOL_GPL(…); /** * cros_ec_get_sensor_count() - Return the number of MEMS sensors supported. * * @ec: EC device, does not have to be connected directly to the AP, * can be daisy chained through another device. * Return: < 0 in case of error. */ int cros_ec_get_sensor_count(struct cros_ec_dev *ec) { … } EXPORT_SYMBOL_GPL(…); /** * cros_ec_cmd - Send a command to the EC. * * @ec_dev: EC device * @version: EC command version * @command: EC command * @outdata: EC command output data * @outsize: Size of outdata * @indata: EC command input data * @insize: Size of indata * * Return: >= 0 on success, negative error number on failure. */ int cros_ec_cmd(struct cros_ec_device *ec_dev, unsigned int version, int command, const void *outdata, size_t outsize, void *indata, size_t insize) { … } EXPORT_SYMBOL_GPL(…); /** * cros_ec_cmd_readmem - Read from EC memory. * * @ec_dev: EC device * @offset: Is within EC_LPC_ADDR_MEMMAP region. * @size: Number of bytes to read. * @dest: EC command output data * * Return: >= 0 on success, negative error number on failure. */ int cros_ec_cmd_readmem(struct cros_ec_device *ec_dev, u8 offset, u8 size, void *dest) { … } EXPORT_SYMBOL_GPL(…); /** * cros_ec_get_cmd_versions - Get supported version mask. * * @ec_dev: EC device * @cmd: Command to test * * Return: version mask on success, negative error number on failure. */ int cros_ec_get_cmd_versions(struct cros_ec_device *ec_dev, u16 cmd) { … } EXPORT_SYMBOL_GPL(…);