Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e10694d authored by Sebastian Reichel's avatar Sebastian Reichel
Browse files

Merge tag 'tags/ib-chrome-psy-5.3' into psy-next



Immutable branch between Power Supply and Chrome Platform due for the
v5.3 merge window

Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
parents 2ffb500d 0c0b7ea2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

wilco_ec-objs				:= core.o mailbox.o
wilco_ec-objs				:= core.o mailbox.o properties.o
obj-$(CONFIG_WILCO_EC)			+= wilco_ec.o
wilco_ec_debugfs-objs			:= debugfs.o
obj-$(CONFIG_WILCO_EC_DEBUGFS)		+= wilco_ec_debugfs.o
+132 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 Google LLC
 */

#include <linux/platform_data/wilco-ec.h>
#include <linux/string.h>
#include <linux/unaligned/le_memmove.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);
+71 −0
Original line number Diff line number Diff line
@@ -123,4 +123,75 @@ struct wilco_ec_message {
 */
int wilco_ec_mailbox(struct wilco_ec_device *ec, struct wilco_ec_message *msg);

/*
 * A Property is typically a data item that is stored to NVRAM
 * by the EC. Each of these data items has an index associated
 * with it, known as the Property ID (PID). Properties may have
 * variable lengths, up to a max of WILCO_EC_PROPERTY_MAX_SIZE
 * bytes. Properties can be simple integers, or they may be more
 * complex binary data.
 */

#define WILCO_EC_PROPERTY_MAX_SIZE	4

/**
 * struct ec_property_set_msg - Message to get or set a property.
 * @property_id: Which property to get or set.
 * @length: Number of bytes of |data| that are used.
 * @data: Actual property data.
 */
struct wilco_ec_property_msg {
	u32 property_id;
	int length;
	u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
};

/**
 * wilco_ec_get_property() - Retrieve a property from the EC.
 * @ec: Embedded Controller device.
 * @prop_msg: Message for request and response.
 *
 * The property_id field of |prop_msg| should be filled before calling this
 * function. The result will be stored in the data and length fields.
 *
 * Return: 0 on success, negative error code on failure.
 */
int wilco_ec_get_property(struct wilco_ec_device *ec,
			  struct wilco_ec_property_msg *prop_msg);

/**
 * wilco_ec_set_property() - Store a property on the EC.
 * @ec: Embedded Controller device.
 * @prop_msg: Message for request and response.
 *
 * The property_id, length, and data fields of |prop_msg| should be
 * filled before calling this function.
 *
 * Return: 0 on success, negative error code on failure.
 */
int wilco_ec_set_property(struct wilco_ec_device *ec,
			  struct wilco_ec_property_msg *prop_msg);

/**
 * wilco_ec_get_byte_property() - Retrieve a byte-size property from the EC.
 * @ec: Embedded Controller device.
 * @property_id: Which property to retrieve.
 * @val: The result value, will be filled by this function.
 *
 * Return: 0 on success, negative error code on failure.
 */
int wilco_ec_get_byte_property(struct wilco_ec_device *ec, u32 property_id,
			       u8 *val);

/**
 * wilco_ec_get_byte_property() - Store a byte-size property on the EC.
 * @ec: Embedded Controller device.
 * @property_id: Which property to store.
 * @val: Value to store.
 *
 * Return: 0 on success, negative error code on failure.
 */
int wilco_ec_set_byte_property(struct wilco_ec_device *ec, u32 property_id,
			       u8 val);

#endif /* WILCO_EC_H */