/*
 * Roccat Isku driver for Linux
 *
 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
 */

/*
 * 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.
 */

/*
 * Roccat Isku is a gamer keyboard with macro keys that can be configured in
 * 5 profiles.
 */

#include <linux/device.h>
#include <linux/input.h>
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/hid-roccat.h>
#include "hid-ids.h"
#include "hid-roccat-common.h"
#include "hid-roccat-isku.h"

static struct class *isku_class;

static void isku_profile_activated(struct isku_device *isku, uint new_profile)
{
	isku->actual_profile = new_profile;
}

static int isku_receive(struct usb_device *usb_dev, uint command,
		void *buf, uint size)
{
	return roccat_common2_receive(usb_dev, command, buf, size);
}

static int isku_get_actual_profile(struct usb_device *usb_dev)
{
	struct isku_actual_profile buf;
	int retval;

	retval = isku_receive(usb_dev, ISKU_COMMAND_ACTUAL_PROFILE,
			&buf, sizeof(struct isku_actual_profile));
	return retval ? retval : buf.actual_profile;
}

static int isku_set_actual_profile(struct usb_device *usb_dev, int new_profile)
{
	struct isku_actual_profile buf;

	buf.command = ISKU_COMMAND_ACTUAL_PROFILE;
	buf.size = sizeof(struct isku_actual_profile);
	buf.actual_profile = new_profile;
	return roccat_common2_send_with_status(usb_dev,
			ISKU_COMMAND_ACTUAL_PROFILE, &buf,
			sizeof(struct isku_actual_profile));
}

static ssize_t isku_sysfs_show_actual_profile(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct isku_device *isku =
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
	return snprintf(buf, PAGE_SIZE, "%d\n", isku->actual_profile);
}

static ssize_t isku_sysfs_set_actual_profile(struct device *dev,
		struct device_attribute *attr, char const *buf, size_t size)
{
	struct isku_device *isku;
	struct usb_device *usb_dev;
	unsigned long profile;
	int retval;
	struct isku_roccat_report roccat_report;

	dev = dev->parent->parent;
	isku = hid_get_drvdata(dev_get_drvdata(dev));
	usb_dev = interface_to_usbdev(to_usb_interface(dev));

	retval = kstrtoul(buf, 10, &profile);
	if (retval)
		return retval;

	if (profile > 4)
		return -EINVAL;

	mutex_lock(&isku->isku_lock);

	retval = isku_set_actual_profile(usb_dev, profile);
	if (retval) {
		mutex_unlock(&isku->isku_lock);
		return retval;
	}

	isku_profile_activated(isku, profile);

	roccat_report.event = ISKU_REPORT_BUTTON_EVENT_PROFILE;
	roccat_report.data1 = profile + 1;
	roccat_report.data2 = 0;
	roccat_report.profile = profile + 1;
	roccat_report_event(isku->chrdev_minor, (uint8_t const *)&roccat_report);

	mutex_unlock(&isku->isku_lock);

	return size;
}
static DEVICE_ATTR(actual_profile, 0660, isku_sysfs_show_actual_profile,
		   isku_sysfs_set_actual_profile);

static struct attribute *isku_attrs[] = {
	&dev_attr_actual_profile.attr,
	NULL,
};

static ssize_t isku_sysfs_read(struct file *fp, struct kobject *kobj,
		char *buf, loff_t off, size_t count,
		size_t real_size, uint command)
{
	struct device *dev =
			container_of(kobj, struct device, kobj)->parent->parent;
	struct isku_device *isku = hid_get_drvdata(dev_get_drvdata(dev));
	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
	int retval;

	if (off >= real_size)
		return 0;

	if (off != 0 || count > real_size)
		return -EINVAL;

	mutex_lock(&isku->isku_lock);
	retval = isku_receive(usb_dev, command, buf, count);
	mutex_unlock(&isku->isku_lock);

	return retval ? retval : count;
}

static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj,
		void const *buf, loff_t off, size_t count,
		size_t real_size, uint command)
{
	struct device *dev =
			container_of(kobj, struct device, kobj)->parent->parent;
	struct isku_device *isku = hid_get_drvdata(dev_get_drvdata(dev));
	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
	int retval;

	if (off != 0 || count > real_size)
		return -EINVAL;

	mutex_lock(&isku->isku_lock);
	retval = roccat_common2_send_with_status(usb_dev, command,
			(void *)buf, count);
	mutex_unlock(&isku->isku_lock);

	return retval ? retval : count;
}

#define ISKU_SYSFS_W(thingy, THINGY) \
static ssize_t isku_sysfs_write_ ## thingy(struct file *fp, struct kobject *kobj, \
		struct bin_attribute *attr, char *buf, \
		loff_t off, size_t count) \
{ \
	return isku_sysfs_write(fp, kobj, buf, off, count, \
			ISKU_SIZE_ ## THINGY, ISKU_COMMAND_ ## THINGY); \
}

#define ISKU_SYSFS_R(thingy, THINGY) \
static ssize_t isku_sysfs_read_ ## thingy(struct file *fp, struct kobject *kobj, \
		struct bin_attribute *attr, char *buf, \
		loff_t off, size_t count) \
{ \
	return isku_sysfs_read(fp, kobj, buf, off, count, \
			ISKU_SIZE_ ## THINGY, ISKU_COMMAND_ ## THINGY); \
}

#define ISKU_SYSFS_RW(thingy, THINGY) \
ISKU_SYSFS_R(thingy, THINGY) \
ISKU_SYSFS_W(thingy, THINGY)

#define ISKU_BIN_ATTR_RW(thingy, THINGY) \
ISKU_SYSFS_RW(thingy, THINGY); \
static struct bin_attribute bin_attr_##thingy = { \
	.attr = { .name = #thingy, .mode = 0660 }, \
	.size = ISKU_SIZE_ ## THINGY, \
	.read = isku_sysfs_read_ ## thingy, \
	.write = isku_sysfs_write_ ## thingy \
}

#define ISKU_BIN_ATTR_R(thingy, THINGY) \
ISKU_SYSFS_R(thingy, THINGY); \
static struct bin_attribute bin_attr_##thingy = { \
	.attr = { .name = #thingy, .mode = 0440 }, \
	.size = ISKU_SIZE_ ## THINGY, \
	.read = isku_sysfs_read_ ## thingy, \
}

#define ISKU_BIN_ATTR_W(thingy, THINGY) \
ISKU_SYSFS_W(thingy, THINGY); \
static struct bin_attribute bin_attr_##thingy = { \
	.attr = { .name = #thingy, .mode = 0220 }, \
	.size = ISKU_SIZE_ ## THINGY, \
	.write = isku_sysfs_write_ ## thingy \
}

ISKU_BIN_ATTR_RW(macro, MACRO);
ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION);
ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE);
ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA);
ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER);
ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO);
ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK);
ISKU_BIN_ATTR_RW(light, LIGHT);
ISKU_BIN_ATTR_RW(key_mask, KEY_MASK);
ISKU_BIN_ATTR_RW(last_set, LAST_SET);
ISKU_BIN_ATTR_W(talk, TALK);
ISKU_BIN_ATTR_W(talkfx, TALKFX);
ISKU_BIN_ATTR_W(control, CONTROL);
ISKU_BIN_ATTR_W(reset, RESET);
ISKU_BIN_ATTR_R(info, INFO);

static struct bin_attribute *isku_bin_attributes[] = {
	&bin_attr_macro,
	&bin_attr_keys_function,
	&bin_attr_keys_easyzone,
	&bin_attr_keys_media,
	&bin_attr_keys_thumbster,
	&bin_attr_keys_macro,
	&bin_attr_keys_capslock,
	&bin_attr_light,
	&bin_attr_key_mask,
	&bin_attr_last_set,
	&bin_attr_talk,
	&bin_attr_talkfx,
	&bin_attr_control,
	&bin_attr_reset,
	&bin_attr_info,
	NULL,
};

static const struct attribute_group isku_group = {
	.attrs = isku_attrs,
	.bin_attrs = isku_bin_attributes,
};

static const struct attribute_group *isku_groups[] = {
	&isku_group,
	NULL,
};

static int isku_init_isku_device_struct(struct usb_device *usb_dev,
		struct isku_device *isku)
{
	int retval;

	mutex_init(&isku->isku_lock);

	retval = isku_get_actual_profile(usb_dev);
	if (retval < 0)
		return retval;
	isku_profile_activated(isku, retval);

	return 0;
}

static int isku_init_specials(struct hid_device *hdev)
{
	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
	struct usb_device *usb_dev = interface_to_usbdev(intf);
	struct isku_device *isku;
	int retval;

	if (intf->cur_altsetting->desc.bInterfaceProtocol
			!= ISKU_USB_INTERFACE_PROTOCOL) {
		hid_set_drvdata(hdev, NULL);
		return 0;
	}

	isku = kzalloc(sizeof(*isku), GFP_KERNEL);
	if (!isku) {
		hid_err(hdev, "can't alloc device descriptor\n");
		return -ENOMEM;
	}
	hid_set_drvdata(hdev, isku);

	retval = isku_init_isku_device_struct(usb_dev, isku);
	if (retval) {
		hid_err(hdev, "couldn't init struct isku_device\n");
		goto exit_free;
	}

	retval = roccat_connect(isku_class, hdev,
			sizeof(struct isku_roccat_report));
	if (retval < 0) {
		hid_err(hdev, "couldn't init char dev\n");
	} else {
		isku->chrdev_minor = retval;
		isku->roccat_claimed = 1;
	}

	return 0;
exit_free:
	kfree(isku);
	return retval;
}

static void isku_remove_specials(struct hid_device *hdev)
{
	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
	struct isku_device *isku;

	if (intf->cur_altsetting->desc.bInterfaceProtocol
			!= ISKU_USB_INTERFACE_PROTOCOL)
		return;

	isku = hid_get_drvdata(hdev);
	if (isku->roccat_claimed)
		roccat_disconnect(isku->chrdev_minor);
	kfree(isku);
}

static int isku_probe(struct hid_device *hdev,
		const struct hid_device_id *id)
{
	int retval;

	retval = hid_parse(hdev);
	if (retval) {
		hid_err(hdev, "parse failed\n");
		goto exit;
	}

	retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (retval) {
		hid_err(hdev, "hw start failed\n");
		goto exit;
	}

	retval = isku_init_specials(hdev);
	if (retval) {
		hid_err(hdev, "couldn't install keyboard\n");
		goto exit_stop;
	}

	return 0;

exit_stop:
	hid_hw_stop(hdev);
exit:
	return retval;
}

static void isku_remove(struct hid_device *hdev)
{
	isku_remove_specials(hdev);
	hid_hw_stop(hdev);
}

static void isku_keep_values_up_to_date(struct isku_device *isku,
		u8 const *data)
{
	struct isku_report_button const *button_report;

	switch (data[0]) {
	case ISKU_REPORT_NUMBER_BUTTON:
		button_report = (struct isku_report_button const *)data;
		switch (button_report->event) {
		case ISKU_REPORT_BUTTON_EVENT_PROFILE:
			isku_profile_activated(isku, button_report->data1 - 1);
			break;
		}
		break;
	}
}

static void isku_report_to_chrdev(struct isku_device const *isku,
		u8 const *data)
{
	struct isku_roccat_report roccat_report;
	struct isku_report_button const *button_report;

	if (data[0] != ISKU_REPORT_NUMBER_BUTTON)
		return;

	button_report = (struct isku_report_button const *)data;

	roccat_report.event = button_report->event;
	roccat_report.data1 = button_report->data1;
	roccat_report.data2 = button_report->data2;
	roccat_report.profile = isku->actual_profile + 1;
	roccat_report_event(isku->chrdev_minor,
			(uint8_t const *)&roccat_report);
}

static int isku_raw_event(struct hid_device *hdev,
		struct hid_report *report, u8 *data, int size)
{
	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
	struct isku_device *isku = hid_get_drvdata(hdev);

	if (intf->cur_altsetting->desc.bInterfaceProtocol
			!= ISKU_USB_INTERFACE_PROTOCOL)
		return 0;

	if (isku == NULL)
		return 0;

	isku_keep_values_up_to_date(isku, data);

	if (isku->roccat_claimed)
		isku_report_to_chrdev(isku, data);

	return 0;
}

static const struct hid_device_id isku_devices[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKUFX) },
	{ }
};

MODULE_DEVICE_TABLE(hid, isku_devices);

static struct hid_driver isku_driver = {
		.name = "isku",
		.id_table = isku_devices,
		.probe = isku_probe,
		.remove = isku_remove,
		.raw_event = isku_raw_event
};

static int __init isku_init(void)
{
	int retval;
	isku_class = class_create(THIS_MODULE, "isku");
	if (IS_ERR(isku_class))
		return PTR_ERR(isku_class);
	isku_class->dev_groups = isku_groups;

	retval = hid_register_driver(&isku_driver);
	if (retval)
		class_destroy(isku_class);
	return retval;
}

static void __exit isku_exit(void)
{
	hid_unregister_driver(&isku_driver);
	class_destroy(isku_class);
}

module_init(isku_init);
module_exit(isku_exit);

MODULE_AUTHOR("Stefan Achatz");
MODULE_DESCRIPTION("USB Roccat Isku/FX driver");
MODULE_LICENSE("GPL v2");
