Loading drivers/platform/chrome/wilco_ec/Makefile +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 drivers/platform/chrome/wilco_ec/properties.c 0 → 100644 +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); include/linux/platform_data/wilco-ec.h +71 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading
drivers/platform/chrome/wilco_ec/Makefile +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
drivers/platform/chrome/wilco_ec/properties.c 0 → 100644 +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);
include/linux/platform_data/wilco-ec.h +71 −0 Original line number Diff line number Diff line Loading @@ -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 */