// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 Google LLC
 */

#include <linux/platform_data/wilco-ec.h>
#include <linux/string.h>
#include <asm/unaligned.h>

/* Operation code; what the EC should do with the property */
enum ec_property_op {
	EC_OP_GET = 0,
	EC_OP_SET = 1,
};

struct ec_property_request {
	u8 op; /* One of enum ec_property_op */
	u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
	u8 length;
	u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
} __packed;

struct ec_property_response {
	u8 reserved[2];
	u8 op; /* One of enum ec_property_op */
	u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
	u8 length;
	u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
} __packed;

static int send_property_msg(struct wilco_ec_device *ec,
			     struct ec_property_request *rq,
			     struct ec_property_response *rs)
{
	struct wilco_ec_message ec_msg;
	int ret;

	memset(&ec_msg, 0, sizeof(ec_msg));
	ec_msg.type = WILCO_EC_MSG_PROPERTY;
	ec_msg.request_data = rq;
	ec_msg.request_size = sizeof(*rq);
	ec_msg.response_data = rs;
	ec_msg.response_size = sizeof(*rs);

	ret = wilco_ec_mailbox(ec, &ec_msg);
	if (ret < 0)
		return ret;
	if (rs->op != rq->op)
		return -EBADMSG;
	if (memcmp(rq->property_id, rs->property_id, sizeof(rs->property_id)))
		return -EBADMSG;

	return 0;
}

int wilco_ec_get_property(struct wilco_ec_device *ec,
			  struct wilco_ec_property_msg *prop_msg)
{
	struct ec_property_request rq;
	struct ec_property_response rs;
	int ret;

	memset(&rq, 0, sizeof(rq));
	rq.op = EC_OP_GET;
	put_unaligned_le32(prop_msg->property_id, rq.property_id);

	ret = send_property_msg(ec, &rq, &rs);
	if (ret < 0)
		return ret;

	prop_msg->length = rs.length;
	memcpy(prop_msg->data, rs.data, rs.length);

	return 0;
}
EXPORT_SYMBOL_GPL(wilco_ec_get_property);

int wilco_ec_set_property(struct wilco_ec_device *ec,
			  struct wilco_ec_property_msg *prop_msg)
{
	struct ec_property_request rq;
	struct ec_property_response rs;
	int ret;

	memset(&rq, 0, sizeof(rq));
	rq.op = EC_OP_SET;
	put_unaligned_le32(prop_msg->property_id, rq.property_id);
	rq.length = prop_msg->length;
	memcpy(rq.data, prop_msg->data, prop_msg->length);

	ret = send_property_msg(ec, &rq, &rs);
	if (ret < 0)
		return ret;
	if (rs.length != prop_msg->length)
		return -EBADMSG;

	return 0;
}
EXPORT_SYMBOL_GPL(wilco_ec_set_property);

int wilco_ec_get_byte_property(struct wilco_ec_device *ec, u32 property_id,
			       u8 *val)
{
	struct wilco_ec_property_msg msg;
	int ret;

	msg.property_id = property_id;

	ret = wilco_ec_get_property(ec, &msg);
	if (ret < 0)
		return ret;
	if (msg.length != 1)
		return -EBADMSG;

	*val = msg.data[0];

	return 0;
}
EXPORT_SYMBOL_GPL(wilco_ec_get_byte_property);

int wilco_ec_set_byte_property(struct wilco_ec_device *ec, u32 property_id,
			       u8 val)
{
	struct wilco_ec_property_msg msg;

	msg.property_id = property_id;
	msg.data[0] = val;
	msg.length = 1;

	return wilco_ec_set_property(ec, &msg);
}
EXPORT_SYMBOL_GPL(wilco_ec_set_byte_property);
