// SPDX-License-Identifier: GPL-2.0+
/*
 * Chromium OS cros_ec driver - I2C interface
 *
 * Copyright (c) 2012 The Chromium OS Authors.
 */

/*
 * The Matrix Keyboard Protocol driver handles talking to the keyboard
 * controller chip. Mostly this is for keyboard functions, but some other
 * things have slipped in, so we provide generic services to talk to the
 * KBC.
 */

#include <common.h>
#include <dm.h>
#include <i2c.h>
#include <cros_ec.h>
#include <log.h>

#ifdef DEBUG_TRACE
#define debug_trace(fmt, b...)	debug(fmt, #b)
#else
#define debug_trace(fmt, b...)
#endif

/**
 * Request format for protocol v3
 * byte 0	0xda (EC_COMMAND_PROTOCOL_3)
 * byte 1-8	struct ec_host_request
 * byte 10-	response data
 */
struct ec_host_request_i2c {
	/* Always 0xda to backward compatible with v2 struct */
	uint8_t  command_protocol;
	struct ec_host_request ec_request;
} __packed;

/*
 * Response format for protocol v3
 * byte 0	result code
 * byte 1	packet_length
 * byte 2-9	struct ec_host_response
 * byte 10-	response data
 */
struct ec_host_response_i2c {
	uint8_t result;
	uint8_t packet_length;
	struct ec_host_response ec_response;
} __packed;

static int cros_ec_i2c_packet(struct udevice *udev, int out_bytes, int in_bytes)
{
	struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
	struct dm_i2c_chip *chip = dev_get_parent_plat(udev);
	struct ec_host_request_i2c *ec_request_i2c =
		(struct ec_host_request_i2c *)dev->dout;
	struct ec_host_response_i2c *ec_response_i2c =
		(struct ec_host_response_i2c *)dev->din;
	struct i2c_msg i2c_msg[2];
	int ret;

	i2c_msg[0].addr = chip->chip_addr;
	i2c_msg[0].flags = 0;
	i2c_msg[1].addr = chip->chip_addr;
	i2c_msg[1].flags = I2C_M_RD;

	/* one extra byte, to indicate v3 */
	i2c_msg[0].len = out_bytes + 1;
	i2c_msg[0].buf = dev->dout;

	/* stitch on EC_COMMAND_PROTOCOL_3 */
	memmove(&ec_request_i2c->ec_request, dev->dout, out_bytes);
	ec_request_i2c->command_protocol = EC_COMMAND_PROTOCOL_3;

	/* two extra bytes for v3 */
	i2c_msg[1].len = in_bytes + 2;
	i2c_msg[1].buf = dev->din;

	ret = dm_i2c_xfer(udev, &i2c_msg[0], 2);
	if (ret) {
		printf("%s: Could not execute transfer: %d\n", __func__, ret);
		return ret;
	}

	/* When we send a v3 request to v2 ec, ec won't recognize the 0xda
	 * (EC_COMMAND_PROTOCOL_3) and will return with status
	 * EC_RES_INVALID_COMMAND with zero data length
	 *
	 * In case of invalid command for v3 protocol the data length
	 * will be at least sizeof(struct ec_host_response)
	 */
	if (ec_response_i2c->result == EC_RES_INVALID_COMMAND &&
	    ec_response_i2c->packet_length == 0)
		return -EPROTONOSUPPORT;

	if (ec_response_i2c->packet_length < sizeof(struct ec_host_response)) {
		printf("%s: response of %u bytes too short; not a full hdr\n",
		       __func__, ec_response_i2c->packet_length);
		return -EBADMSG;
	}


	/* drop result and packet_len */
	memmove(dev->din, &ec_response_i2c->ec_response, in_bytes);

	return in_bytes;
}

static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd,
			       int cmd_version, const uint8_t *dout,
			       int dout_len, uint8_t **dinp, int din_len)
{
	struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
	struct dm_i2c_chip *chip = dev_get_parent_plat(udev);
	struct i2c_msg i2c_msg[2];
	/* version8, cmd8, arglen8, out8[dout_len], csum8 */
	int out_bytes = dout_len + 4;
	/* response8, arglen8, in8[din_len], checksum8 */
	int in_bytes = din_len + 3;
	uint8_t *ptr;
	/* Receive input data, so that args will be dword aligned */
	uint8_t *in_ptr;
	int len, csum, ret;

	/*
	 * Sanity-check I/O sizes given transaction overhead in internal
	 * buffers.
	 */
	if (out_bytes > sizeof(dev->dout)) {
		debug("%s: Cannot send %d bytes\n", __func__, dout_len);
		return -1;
	}
	if (in_bytes > sizeof(dev->din)) {
		debug("%s: Cannot receive %d bytes\n", __func__, din_len);
		return -1;
	}
	assert(dout_len >= 0);
	assert(dinp);

	i2c_msg[0].addr = chip->chip_addr;
	i2c_msg[0].len = out_bytes;
	i2c_msg[0].buf = dev->dout;
	i2c_msg[0].flags = 0;

	/*
	 * Copy command and data into output buffer so we can do a single I2C
	 * burst transaction.
	 */
	ptr = dev->dout;

	/*
	 * in_ptr starts of pointing to a dword-aligned input data buffer.
	 * We decrement it back by the number of header bytes we expect to
	 * receive, so that the first parameter of the resulting input data
	 * will be dword aligned.
	 */
	in_ptr = dev->din + sizeof(int64_t);

	if (dev->protocol_version != 2) {
		/* Something we don't support */
		debug("%s: Protocol version %d unsupported\n",
		      __func__, dev->protocol_version);
		return -1;
	}

	*ptr++ = EC_CMD_VERSION0 + cmd_version;
	*ptr++ = cmd;
	*ptr++ = dout_len;
	in_ptr -= 2;	/* Expect status, length bytes */

	memcpy(ptr, dout, dout_len);
	ptr += dout_len;

	*ptr++ = (uint8_t)
		cros_ec_calc_checksum(dev->dout, dout_len + 3);

	i2c_msg[1].addr = chip->chip_addr;
	i2c_msg[1].len = in_bytes;
	i2c_msg[1].buf = in_ptr;
	i2c_msg[1].flags = I2C_M_RD;

	/* Send output data */
	cros_ec_dump_data("out", -1, dev->dout, out_bytes);

	ret = dm_i2c_xfer(udev, &i2c_msg[0], 2);
	if (ret) {
		debug("%s: Could not execute transfer to %s\n", __func__,
		      udev->name);
		ret = -1;
	}

	if (*in_ptr != EC_RES_SUCCESS) {
		debug("%s: Received bad result code %d\n", __func__, *in_ptr);
		return -(int)*in_ptr;
	}

	len = in_ptr[1];
	if (len + 3 > sizeof(dev->din)) {
		debug("%s: Received length %#02x too large\n",
		      __func__, len);
		return -1;
	}
	csum = cros_ec_calc_checksum(in_ptr, 2 + len);
	if (csum != in_ptr[2 + len]) {
		debug("%s: Invalid checksum rx %#02x, calced %#02x\n",
		      __func__, in_ptr[2 + din_len], csum);
		return -1;
	}
	din_len = min(din_len, len);
	cros_ec_dump_data("in", -1, in_ptr, din_len + 3);

	/* Return pointer to dword-aligned input data, if any */
	*dinp = dev->din + sizeof(int64_t);

	return din_len;
}

static int cros_ec_probe(struct udevice *dev)
{
	return cros_ec_register(dev);
}

static struct dm_cros_ec_ops cros_ec_ops = {
	.command = cros_ec_i2c_command,
	.packet = cros_ec_i2c_packet,
};

static const struct udevice_id cros_ec_ids[] = {
	{ .compatible = "google,cros-ec-i2c" },
	{ }
};

U_BOOT_DRIVER(google_cros_ec_i2c) = {
	.name		= "google_cros_ec_i2c",
	.id		= UCLASS_CROS_EC,
	.of_match	= cros_ec_ids,
	.probe		= cros_ec_probe,
	.ops		= &cros_ec_ops,
};
