// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 Google LLC
 *
 * Sysfs properties to view and modify EC-controlled features on Wilco devices.
 * The entries will appear under /sys/bus/platform/devices/GOOG000C:00/
 *
 * See Documentation/ABI/testing/sysfs-platform-wilco-ec for more information.
 */

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/platform_data/wilco-ec.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/types.h>

#define CMD_KB_CMOS			0x7C
#define SUB_CMD_KB_CMOS_AUTO_ON		0x03

struct boot_on_ac_request {
	u8 cmd;			/* Always CMD_KB_CMOS */
	u8 reserved1;
	u8 sub_cmd;		/* Always SUB_CMD_KB_CMOS_AUTO_ON */
	u8 reserved3to5[3];
	u8 val;			/* Either 0 or 1 */
	u8 reserved7;
} __packed;

#define CMD_USB_CHARGE 0x39

enum usb_charge_op {
	USB_CHARGE_GET = 0,
	USB_CHARGE_SET = 1,
};

struct usb_charge_request {
	u8 cmd;		/* Always CMD_USB_CHARGE */
	u8 reserved;
	u8 op;		/* One of enum usb_charge_op */
	u8 val;		/* When setting, either 0 or 1 */
} __packed;

struct usb_charge_response {
	u8 reserved;
	u8 status;	/* Set by EC to 0 on success, other value on failure */
	u8 val;		/* When getting, set by EC to either 0 or 1 */
} __packed;

#define CMD_EC_INFO			0x38
enum get_ec_info_op {
	CMD_GET_EC_LABEL	= 0,
	CMD_GET_EC_REV		= 1,
	CMD_GET_EC_MODEL	= 2,
	CMD_GET_EC_BUILD_DATE	= 3,
};

struct get_ec_info_req {
	u8 cmd;			/* Always CMD_EC_INFO */
	u8 reserved;
	u8 op;			/* One of enum get_ec_info_op */
} __packed;

struct get_ec_info_resp {
	u8 reserved[2];
	char value[9]; /* __nonstring: might not be null terminated */
} __packed;

static ssize_t boot_on_ac_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct wilco_ec_device *ec = dev_get_drvdata(dev);
	struct boot_on_ac_request rq;
	struct wilco_ec_message msg;
	int ret;
	u8 val;

	ret = kstrtou8(buf, 10, &val);
	if (ret < 0)
		return ret;
	if (val > 1)
		return -EINVAL;

	memset(&rq, 0, sizeof(rq));
	rq.cmd = CMD_KB_CMOS;
	rq.sub_cmd = SUB_CMD_KB_CMOS_AUTO_ON;
	rq.val = val;

	memset(&msg, 0, sizeof(msg));
	msg.type = WILCO_EC_MSG_LEGACY;
	msg.request_data = &rq;
	msg.request_size = sizeof(rq);
	ret = wilco_ec_mailbox(ec, &msg);
	if (ret < 0)
		return ret;

	return count;
}

static DEVICE_ATTR_WO(boot_on_ac);

static ssize_t get_info(struct device *dev, char *buf, enum get_ec_info_op op)
{
	struct wilco_ec_device *ec = dev_get_drvdata(dev);
	struct get_ec_info_req req = { .cmd = CMD_EC_INFO, .op = op };
	struct get_ec_info_resp resp;
	int ret;

	struct wilco_ec_message msg = {
		.type = WILCO_EC_MSG_LEGACY,
		.request_data = &req,
		.request_size = sizeof(req),
		.response_data = &resp,
		.response_size = sizeof(resp),
	};

	ret = wilco_ec_mailbox(ec, &msg);
	if (ret < 0)
		return ret;

	return sysfs_emit(buf, "%.*s\n", (int)sizeof(resp.value), (char *)&resp.value);
}

static ssize_t version_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	return get_info(dev, buf, CMD_GET_EC_LABEL);
}

static DEVICE_ATTR_RO(version);

static ssize_t build_revision_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	return get_info(dev, buf, CMD_GET_EC_REV);
}

static DEVICE_ATTR_RO(build_revision);

static ssize_t build_date_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	return get_info(dev, buf, CMD_GET_EC_BUILD_DATE);
}

static DEVICE_ATTR_RO(build_date);

static ssize_t model_number_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	return get_info(dev, buf, CMD_GET_EC_MODEL);
}

static DEVICE_ATTR_RO(model_number);

static int send_usb_charge(struct wilco_ec_device *ec,
				struct usb_charge_request *rq,
				struct usb_charge_response *rs)
{
	struct wilco_ec_message msg;
	int ret;

	memset(&msg, 0, sizeof(msg));
	msg.type = WILCO_EC_MSG_LEGACY;
	msg.request_data = rq;
	msg.request_size = sizeof(*rq);
	msg.response_data = rs;
	msg.response_size = sizeof(*rs);
	ret = wilco_ec_mailbox(ec, &msg);
	if (ret < 0)
		return ret;
	if (rs->status)
		return -EIO;

	return 0;
}

static ssize_t usb_charge_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	struct wilco_ec_device *ec = dev_get_drvdata(dev);
	struct usb_charge_request rq;
	struct usb_charge_response rs;
	int ret;

	memset(&rq, 0, sizeof(rq));
	rq.cmd = CMD_USB_CHARGE;
	rq.op = USB_CHARGE_GET;

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

	return sysfs_emit(buf, "%d\n", rs.val);
}

static ssize_t usb_charge_store(struct device *dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
{
	struct wilco_ec_device *ec = dev_get_drvdata(dev);
	struct usb_charge_request rq;
	struct usb_charge_response rs;
	int ret;
	u8 val;

	ret = kstrtou8(buf, 10, &val);
	if (ret < 0)
		return ret;
	if (val > 1)
		return -EINVAL;

	memset(&rq, 0, sizeof(rq));
	rq.cmd = CMD_USB_CHARGE;
	rq.op = USB_CHARGE_SET;
	rq.val = val;

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

	return count;
}

static DEVICE_ATTR_RW(usb_charge);

static struct attribute *wilco_dev_attrs[] = {
	&dev_attr_boot_on_ac.attr,
	&dev_attr_build_date.attr,
	&dev_attr_build_revision.attr,
	&dev_attr_model_number.attr,
	&dev_attr_usb_charge.attr,
	&dev_attr_version.attr,
	NULL,
};

static const struct attribute_group wilco_dev_attr_group = {
	.attrs = wilco_dev_attrs,
};

int wilco_ec_add_sysfs(struct wilco_ec_device *ec)
{
	return sysfs_create_group(&ec->dev->kobj, &wilco_dev_attr_group);
}

void wilco_ec_remove_sysfs(struct wilco_ec_device *ec)
{
	sysfs_remove_group(&ec->dev->kobj, &wilco_dev_attr_group);
}
