2019-04-25 00:56:50 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/*
|
|
|
|
* Copyright 2019 Google LLC
|
|
|
|
*/
|
|
|
|
|
2020-02-05 17:48:28 +08:00
|
|
|
#include <linux/errno.h>
|
|
|
|
#include <linux/export.h>
|
2019-04-25 00:56:50 +08:00
|
|
|
#include <linux/platform_data/wilco-ec.h>
|
|
|
|
#include <linux/string.h>
|
2020-02-05 17:48:28 +08:00
|
|
|
#include <linux/types.h>
|
platform/chrome: wilco_ec: Include asm/unaligned instead of linux/ path
It seems that we shouldn't try to include the include/linux/ path to
unaligned functions. Just include asm/unaligned.h instead so that we
don't run into compilation warnings like below.
In file included from drivers/platform/chrome/wilco_ec/properties.c:8:0:
include/linux/unaligned/le_memmove.h:7:19: error: redefinition of 'get_unaligned_le16'
static inline u16 get_unaligned_le16(const void *p)
^~~~~~~~~~~~~~~~~~
In file included from arch/ia64/include/asm/unaligned.h:5:0,
from arch/ia64/include/asm/io.h:23,
from arch/ia64/include/asm/smp.h:21,
from include/linux/smp.h:68,
from include/linux/percpu.h:7,
from include/linux/arch_topology.h:9,
from include/linux/topology.h:30,
from include/linux/gfp.h:9,
from include/linux/xarray.h:14,
from include/linux/radix-tree.h:18,
from include/linux/idr.h:15,
from include/linux/kernfs.h:13,
from include/linux/sysfs.h:16,
from include/linux/kobject.h:20,
from include/linux/device.h:16,
from include/linux/platform_data/wilco-ec.h:11,
from drivers/platform/chrome/wilco_ec/properties.c:6:
include/linux/unaligned/le_struct.h:7:19: note: previous definition of 'get_unaligned_le16' was here
static inline u16 get_unaligned_le16(const void *p)
^~~~~~~~~~~~~~~~~~
Reported-by: kbuild test robot <lkp@intel.com>
Fixes: 60fb8a8e93ca ("platform/chrome: wilco_ec: Allow wilco to be compiled in COMPILE_TEST")
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
2020-02-04 01:46:19 +08:00
|
|
|
#include <asm/unaligned.h>
|
2019-04-25 00:56:50 +08:00
|
|
|
|
|
|
|
/* 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);
|