/*
 *  HID driver for Quickstep, ChromeOS's Latency Measurement Gadget
 *
 *  The device is connected via USB and transmits a byte each time a
 *  laster is crossed.  The job of the driver is to record when those events
 *  happen and then make that information availible to the user via sysfs
 *  entries.
 */

#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/time.h>

#include "hid-ids.h"

#define MAX_CROSSINGS 64

enum change_type { OFF, ON };

struct qs_event {
	struct timespec64 time;
	enum change_type direction;
};

struct qs_data {
	unsigned int head;
	struct qs_event events[MAX_CROSSINGS];
};

static ssize_t append_event(struct qs_event *event, char *buf, ssize_t len)
{
	return snprintf(buf, len, "%010lld.%09ld\t%d\n", event->time.tv_sec,
			event->time.tv_nsec, event->direction);

}

static ssize_t show_log(struct device *dev, struct device_attribute *attr,
		char *buf)
{
	int i, str_len;
	struct qs_data *data = dev_get_drvdata(dev);

	str_len = snprintf(buf, PAGE_SIZE,
			"Laser Crossings:\ntime\t\t\tdirection\n");

	if (data->head >= MAX_CROSSINGS) {
		for (i = data->head % MAX_CROSSINGS; i < MAX_CROSSINGS; i++) {
			str_len += append_event(&data->events[i], buf + str_len,
						PAGE_SIZE - str_len);
		}
	}

	for (i = 0; i < data->head % MAX_CROSSINGS; i++) {
		str_len += append_event(&data->events[i], buf + str_len,
					PAGE_SIZE - str_len);
	}

	return str_len;
}

static void empty_quickstep_data(struct qs_data *data)
{
	if (data == NULL)
		return;
	data->head = 0;
}

static ssize_t clear_log(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t len)
{
	empty_quickstep_data(dev_get_drvdata(dev));
	return len;
}

static DEVICE_ATTR(laser, 0444, show_log, NULL);
static DEVICE_ATTR(clear, 0220, NULL, clear_log);
static struct attribute *dev_attrs[] = {
	&dev_attr_laser.attr,
	&dev_attr_clear.attr,
	NULL,
};
static struct attribute_group dev_attr_group = {.attrs = dev_attrs};

static int quickstep_probe(struct hid_device *hdev,
		const struct hid_device_id *id)
{
	int ret;
	struct qs_data *data;

	ret = hid_parse(hdev);
	if (ret) {
		hid_err(hdev, "parse failed\n");
		return ret;
	}

	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (ret) {
		hid_err(hdev, "hw start failed\n");
		return ret;
	}

	ret = hid_hw_open(hdev);
	if (ret) {
		hid_err(hdev, "hw open failed\n");
		hid_hw_stop(hdev);
		return ret;
	}

	data = kmalloc(sizeof(struct qs_data), GFP_KERNEL);
	empty_quickstep_data(data);
	hid_set_drvdata(hdev, data);

	ret = sysfs_create_group(&hdev->dev.kobj, &dev_attr_group);

	return ret;
}

static void quickstep_remove(struct hid_device *hdev)
{
	sysfs_remove_group(&hdev->dev.kobj, &dev_attr_group);
	hid_hw_stop(hdev);
	kfree(hid_get_drvdata(hdev));
}

static int quickstep_raw_event(struct hid_device *hdev,
	struct hid_report *report, u8 *msg, int size)
{
	struct timespec64 time;
	struct qs_data *data = hid_get_drvdata(hdev);

	ktime_get_real_ts64(&time);

	data->events[data->head % MAX_CROSSINGS].time = time;
	data->events[data->head % MAX_CROSSINGS].direction = msg[0] ? ON : OFF;

	data->head++;
	if (data->head >= MAX_CROSSINGS * 2)
		data->head = MAX_CROSSINGS + data->head % MAX_CROSSINGS;

	return 0;
}

static const struct hid_device_id quickstep_devices[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_GOOGLE,
		USB_DEVICE_ID_GOOGLE_QUICKSTEP) },
	{ }
};
MODULE_DEVICE_TABLE(hid, quickstep_devices);

static struct hid_driver quickstep_driver = {
	.name = "quickstep",
	.id_table = quickstep_devices,
	.probe = quickstep_probe,
	.remove = quickstep_remove,
	.raw_event = quickstep_raw_event,
};

static int __init quickstep_init(void)
{
	return hid_register_driver(&quickstep_driver);
}

static void __exit quickstep_exit(void)
{
	hid_unregister_driver(&quickstep_driver);
}

module_init(quickstep_init);
module_exit(quickstep_exit);
MODULE_AUTHOR("Charlie Mooney <charliemooney@google.com>");
MODULE_LICENSE("GPL");
