/*
 * cros_ec_lightbar - expose the Chromebook Pixel lightbar to userspace
 *
 * Copyright (C) 2014 Google, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#define pr_fmt(fmt) "cros_ec_lightbar: " fmt

#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/kobject.h>
#include <linux/mfd/cros_ec.h>
#include <linux/mfd/cros_ec_commands.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/slab.h>

#include "cros_ec_dev.h"

/* Rate-limit the lightbar interface to prevent DoS. */
static unsigned long lb_interval_jiffies = 50 * HZ / 1000;

/*
 * Whether or not we have given userspace control of the lightbar.
 * If this is true, we won't do anything during suspend/resume.
 */
static bool userspace_control;
static struct cros_ec_dev *ec_with_lightbar;

static ssize_t interval_msec_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{
	unsigned long msec = lb_interval_jiffies * 1000 / HZ;

	return scnprintf(buf, PAGE_SIZE, "%lu\n", msec);
}

static ssize_t interval_msec_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
{
	unsigned long msec;

	if (kstrtoul(buf, 0, &msec))
		return -EINVAL;

	lb_interval_jiffies = msec * HZ / 1000;

	return count;
}

static DEFINE_MUTEX(lb_mutex);
/* Return 0 if able to throttle correctly, error otherwise */
static int lb_throttle(void)
{
	static unsigned long last_access;
	unsigned long now, next_timeslot;
	long delay;
	int ret = 0;

	mutex_lock(&lb_mutex);

	now = jiffies;
	next_timeslot = last_access + lb_interval_jiffies;

	if (time_before(now, next_timeslot)) {
		delay = (long)(next_timeslot) - (long)now;
		set_current_state(TASK_INTERRUPTIBLE);
		if (schedule_timeout(delay) > 0) {
			/* interrupted - just abort */
			ret = -EINTR;
			goto out;
		}
		now = jiffies;
	}

	last_access = now;
out:
	mutex_unlock(&lb_mutex);

	return ret;
}

static struct cros_ec_command *alloc_lightbar_cmd_msg(struct cros_ec_dev *ec)
{
	struct cros_ec_command *msg;
	int len;

	len = max(sizeof(struct ec_params_lightbar),
		  sizeof(struct ec_response_lightbar));

	msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL);
	if (!msg)
		return NULL;

	msg->version = 0;
	msg->command = EC_CMD_LIGHTBAR_CMD + ec->cmd_offset;
	msg->outsize = sizeof(struct ec_params_lightbar);
	msg->insize = sizeof(struct ec_response_lightbar);

	return msg;
}

static int get_lightbar_version(struct cros_ec_dev *ec,
				uint32_t *ver_ptr, uint32_t *flg_ptr)
{
	struct ec_params_lightbar *param;
	struct ec_response_lightbar *resp;
	struct cros_ec_command *msg;
	int ret;

	msg = alloc_lightbar_cmd_msg(ec);
	if (!msg)
		return 0;

	param = (struct ec_params_lightbar *)msg->data;
	param->cmd = LIGHTBAR_CMD_VERSION;
	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
	if (ret < 0) {
		ret = 0;
		goto exit;
	}

	switch (msg->result) {
	case EC_RES_INVALID_PARAM:
		/* Pixel had no version command. */
		if (ver_ptr)
			*ver_ptr = 0;
		if (flg_ptr)
			*flg_ptr = 0;
		ret = 1;
		goto exit;

	case EC_RES_SUCCESS:
		resp = (struct ec_response_lightbar *)msg->data;

		/* Future devices w/lightbars should implement this command */
		if (ver_ptr)
			*ver_ptr = resp->version.num;
		if (flg_ptr)
			*flg_ptr = resp->version.flags;
		ret = 1;
		goto exit;
	}

	/* Anything else (ie, EC_RES_INVALID_COMMAND) - no lightbar */
	ret = 0;
exit:
	kfree(msg);
	return ret;
}

static ssize_t version_show(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	uint32_t version = 0, flags = 0;
	struct cros_ec_dev *ec = container_of(dev,
					      struct cros_ec_dev, class_dev);
	int ret;

	ret = lb_throttle();
	if (ret)
		return ret;

	/* This should always succeed, because we check during init. */
	if (!get_lightbar_version(ec, &version, &flags))
		return -EIO;

	return scnprintf(buf, PAGE_SIZE, "%d %d\n", version, flags);
}

static ssize_t brightness_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct ec_params_lightbar *param;
	struct cros_ec_command *msg;
	int ret;
	unsigned int val;
	struct cros_ec_dev *ec = container_of(dev,
					      struct cros_ec_dev, class_dev);

	if (kstrtouint(buf, 0, &val))
		return -EINVAL;

	msg = alloc_lightbar_cmd_msg(ec);
	if (!msg)
		return -ENOMEM;

	param = (struct ec_params_lightbar *)msg->data;
	param->cmd = LIGHTBAR_CMD_SET_BRIGHTNESS;
	param->set_brightness.num = val;
	ret = lb_throttle();
	if (ret)
		goto exit;

	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
	if (ret < 0)
		goto exit;

	if (msg->result != EC_RES_SUCCESS) {
		ret = -EINVAL;
		goto exit;
	}

	ret = count;
exit:
	kfree(msg);
	return ret;
}


/*
 * We expect numbers, and we'll keep reading until we find them, skipping over
 * any whitespace (sysfs guarantees that the input is null-terminated). Every
 * four numbers are sent to the lightbar as <LED,R,G,B>. We fail at the first
 * parsing error, if we don't parse any numbers, or if we have numbers left
 * over.
 */
static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr,
			     const char *buf, size_t count)
{
	struct ec_params_lightbar *param;
	struct cros_ec_command *msg;
	struct cros_ec_dev *ec = container_of(dev,
					      struct cros_ec_dev, class_dev);
	unsigned int val[4];
	int ret, i = 0, j = 0, ok = 0;

	msg = alloc_lightbar_cmd_msg(ec);
	if (!msg)
		return -ENOMEM;

	do {
		/* Skip any whitespace */
		while (*buf && isspace(*buf))
			buf++;

		if (!*buf)
			break;

		ret = sscanf(buf, "%i", &val[i++]);
		if (ret == 0)
			goto exit;

		if (i == 4) {
			param = (struct ec_params_lightbar *)msg->data;
			param->cmd = LIGHTBAR_CMD_SET_RGB;
			param->set_rgb.led = val[0];
			param->set_rgb.red = val[1];
			param->set_rgb.green = val[2];
			param->set_rgb.blue = val[3];
			/*
			 * Throttle only the first of every four transactions,
			 * so that the user can update all four LEDs at once.
			 */
			if ((j++ % 4) == 0) {
				ret = lb_throttle();
				if (ret)
					goto exit;
			}

			ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
			if (ret < 0)
				goto exit;

			if (msg->result != EC_RES_SUCCESS)
				goto exit;

			i = 0;
			ok = 1;
		}

		/* Skip over the number we just read */
		while (*buf && !isspace(*buf))
			buf++;

	} while (*buf);

exit:
	kfree(msg);
	return (ok && i == 0) ? count : -EINVAL;
}

static char const *seqname[] = {
	"ERROR", "S5", "S3", "S0", "S5S3", "S3S0",
	"S0S3", "S3S5", "STOP", "RUN", "KONAMI",
	"TAP", "PROGRAM",
};

static ssize_t sequence_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct ec_params_lightbar *param;
	struct ec_response_lightbar *resp;
	struct cros_ec_command *msg;
	int ret;
	struct cros_ec_dev *ec = container_of(dev,
					      struct cros_ec_dev, class_dev);

	msg = alloc_lightbar_cmd_msg(ec);
	if (!msg)
		return -ENOMEM;

	param = (struct ec_params_lightbar *)msg->data;
	param->cmd = LIGHTBAR_CMD_GET_SEQ;
	ret = lb_throttle();
	if (ret)
		goto exit;

	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
	if (ret < 0)
		goto exit;

	if (msg->result != EC_RES_SUCCESS) {
		ret = scnprintf(buf, PAGE_SIZE,
				"ERROR: EC returned %d\n", msg->result);
		goto exit;
	}

	resp = (struct ec_response_lightbar *)msg->data;
	if (resp->get_seq.num >= ARRAY_SIZE(seqname))
		ret = scnprintf(buf, PAGE_SIZE, "%d\n", resp->get_seq.num);
	else
		ret = scnprintf(buf, PAGE_SIZE, "%s\n",
				seqname[resp->get_seq.num]);

exit:
	kfree(msg);
	return ret;
}

static int lb_send_empty_cmd(struct cros_ec_dev *ec, uint8_t cmd)
{
	struct ec_params_lightbar *param;
	struct cros_ec_command *msg;
	int ret;

	msg = alloc_lightbar_cmd_msg(ec);
	if (!msg)
		return -ENOMEM;

	param = (struct ec_params_lightbar *)msg->data;
	param->cmd = cmd;

	ret = lb_throttle();
	if (ret)
		goto error;

	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
	if (ret < 0)
		goto error;
	if (msg->result != EC_RES_SUCCESS) {
		ret = -EINVAL;
		goto error;
	}
	ret = 0;
error:
	kfree(msg);

	return ret;
}

int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable)
{
	struct ec_params_lightbar *param;
	struct cros_ec_command *msg;
	int ret;

	if (ec != ec_with_lightbar)
		return 0;

	msg = alloc_lightbar_cmd_msg(ec);
	if (!msg)
		return -ENOMEM;

	param = (struct ec_params_lightbar *)msg->data;

	param->cmd = LIGHTBAR_CMD_MANUAL_SUSPEND_CTRL;
	param->manual_suspend_ctrl.enable = enable;

	ret = lb_throttle();
	if (ret)
		goto error;

	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
	if (ret < 0)
		goto error;
	if (msg->result != EC_RES_SUCCESS) {
		ret = -EINVAL;
		goto error;
	}
	ret = 0;
error:
	kfree(msg);

	return ret;
}

int lb_suspend(struct cros_ec_dev *ec)
{
	if (userspace_control || ec != ec_with_lightbar)
		return 0;

	return lb_send_empty_cmd(ec, LIGHTBAR_CMD_SUSPEND);
}

int lb_resume(struct cros_ec_dev *ec)
{
	if (userspace_control || ec != ec_with_lightbar)
		return 0;

	return lb_send_empty_cmd(ec, LIGHTBAR_CMD_RESUME);
}

static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
			      const char *buf, size_t count)
{
	struct ec_params_lightbar *param;
	struct cros_ec_command *msg;
	unsigned int num;
	int ret, len;
	struct cros_ec_dev *ec = container_of(dev,
					      struct cros_ec_dev, class_dev);

	for (len = 0; len < count; len++)
		if (!isalnum(buf[len]))
			break;

	for (num = 0; num < ARRAY_SIZE(seqname); num++)
		if (!strncasecmp(seqname[num], buf, len))
			break;

	if (num >= ARRAY_SIZE(seqname)) {
		ret = kstrtouint(buf, 0, &num);
		if (ret)
			return ret;
	}

	msg = alloc_lightbar_cmd_msg(ec);
	if (!msg)
		return -ENOMEM;

	param = (struct ec_params_lightbar *)msg->data;
	param->cmd = LIGHTBAR_CMD_SEQ;
	param->seq.num = num;
	ret = lb_throttle();
	if (ret)
		goto exit;

	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
	if (ret < 0)
		goto exit;

	if (msg->result != EC_RES_SUCCESS) {
		ret = -EINVAL;
		goto exit;
	}

	ret = count;
exit:
	kfree(msg);
	return ret;
}

static ssize_t program_store(struct device *dev, struct device_attribute *attr,
			     const char *buf, size_t count)
{
	int extra_bytes, max_size, ret;
	struct ec_params_lightbar *param;
	struct cros_ec_command *msg;
	struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev,
					      class_dev);

	/*
	 * We might need to reject the program for size reasons. The EC
	 * enforces a maximum program size, but we also don't want to try
	 * and send a program that is too big for the protocol. In order
	 * to ensure the latter, we also need to ensure we have extra bytes
	 * to represent the rest of the packet.
	 */
	extra_bytes = sizeof(*param) - sizeof(param->set_program.data);
	max_size = min(EC_LB_PROG_LEN, ec->ec_dev->max_request - extra_bytes);
	if (count > max_size) {
		dev_err(dev, "Program is %u bytes, too long to send (max: %u)",
			(unsigned int)count, max_size);

		return -EINVAL;
	}

	msg = alloc_lightbar_cmd_msg(ec);
	if (!msg)
		return -ENOMEM;

	ret = lb_throttle();
	if (ret)
		goto exit;

	dev_info(dev, "Copying %zu byte program to EC", count);

	param = (struct ec_params_lightbar *)msg->data;
	param->cmd = LIGHTBAR_CMD_SET_PROGRAM;

	param->set_program.size = count;
	memcpy(param->set_program.data, buf, count);

	/*
	 * We need to set the message size manually or else it will use
	 * EC_LB_PROG_LEN. This might be too long, and the program
	 * is unlikely to use all of the space.
	 */
	msg->outsize = count + extra_bytes;

	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
	if (ret < 0)
		goto exit;
	if (msg->result != EC_RES_SUCCESS) {
		ret = -EINVAL;
		goto exit;
	}

	ret = count;
exit:
	kfree(msg);

	return ret;
}

static ssize_t userspace_control_show(struct device *dev,
				      struct device_attribute *attr,
				      char *buf)
{
	return scnprintf(buf, PAGE_SIZE, "%d\n", userspace_control);
}

static ssize_t userspace_control_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf,
				       size_t count)
{
	bool enable;
	int ret;

	ret = strtobool(buf, &enable);
	if (ret < 0)
		return ret;

	userspace_control = enable;

	return count;
}

/* Module initialization */

static DEVICE_ATTR_RW(interval_msec);
static DEVICE_ATTR_RO(version);
static DEVICE_ATTR_WO(brightness);
static DEVICE_ATTR_WO(led_rgb);
static DEVICE_ATTR_RW(sequence);
static DEVICE_ATTR_WO(program);
static DEVICE_ATTR_RW(userspace_control);

static struct attribute *__lb_cmds_attrs[] = {
	&dev_attr_interval_msec.attr,
	&dev_attr_version.attr,
	&dev_attr_brightness.attr,
	&dev_attr_led_rgb.attr,
	&dev_attr_sequence.attr,
	&dev_attr_program.attr,
	&dev_attr_userspace_control.attr,
	NULL,
};

bool ec_has_lightbar(struct cros_ec_dev *ec)
{
	return !!get_lightbar_version(ec, NULL, NULL);
}

static umode_t cros_ec_lightbar_attrs_are_visible(struct kobject *kobj,
						  struct attribute *a, int n)
{
	struct device *dev = container_of(kobj, struct device, kobj);
	struct cros_ec_dev *ec = container_of(dev,
					      struct cros_ec_dev, class_dev);
	struct platform_device *pdev = to_platform_device(ec->dev);
	struct cros_ec_platform *pdata = pdev->dev.platform_data;
	int is_cros_ec;

	is_cros_ec = strcmp(pdata->ec_name, CROS_EC_DEV_NAME);

	if (is_cros_ec != 0)
		return 0;

	/* Only instantiate this stuff if the EC has a lightbar */
	if (ec_has_lightbar(ec)) {
		ec_with_lightbar = ec;
		return a->mode;
	}
	return 0;
}

struct attribute_group cros_ec_lightbar_attr_group = {
	.name = "lightbar",
	.attrs = __lb_cmds_attrs,
	.is_visible = cros_ec_lightbar_attrs_are_visible,
};
