/*
 * Simple USB RGB LED driver
 *
 * Copyright 2016 Heiner Kallweit <hkallweit1@gmail.com>
 * Based on drivers/hid/hid-thingm.c and
 * drivers/usb/misc/usbled.c
 *
 * 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, version 2.
 */

#include <linux/hid.h>
#include <linux/hidraw.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/mutex.h>

#include "hid-ids.h"

enum hidled_report_type {
	RAW_REQUEST,
	OUTPUT_REPORT
};

enum hidled_type {
	RISO_KAGAKU,
	DREAM_CHEEKY,
	THINGM,
	DELCOM,
};

static unsigned const char riso_kagaku_tbl[] = {
/* R+2G+4B -> riso kagaku color index */
	[0] = 0, /* black   */
	[1] = 2, /* red     */
	[2] = 1, /* green   */
	[3] = 5, /* yellow  */
	[4] = 3, /* blue    */
	[5] = 6, /* magenta */
	[6] = 4, /* cyan    */
	[7] = 7  /* white   */
};

#define RISO_KAGAKU_IX(r, g, b) riso_kagaku_tbl[((r)?1:0)+((g)?2:0)+((b)?4:0)]

union delcom_packet {
	__u8 data[8];
	struct {
		__u8 major_cmd;
		__u8 minor_cmd;
		__u8 data_lsb;
		__u8 data_msb;
	} tx;
	struct {
		__u8 cmd;
	} rx;
	struct {
		__le16 family_code;
		__le16 security_code;
		__u8 fw_version;
	} fw;
};

#define DELCOM_GREEN_LED	0
#define DELCOM_RED_LED		1
#define DELCOM_BLUE_LED		2

struct hidled_device;
struct hidled_rgb;

struct hidled_config {
	enum hidled_type	type;
	const char		*name;
	const char		*short_name;
	enum led_brightness	max_brightness;
	int			num_leds;
	size_t			report_size;
	enum hidled_report_type	report_type;
	int (*init)(struct hidled_device *ldev);
	int (*write)(struct led_classdev *cdev, enum led_brightness br);
};

struct hidled_led {
	struct led_classdev	cdev;
	struct hidled_rgb	*rgb;
	char			name[32];
};

struct hidled_rgb {
	struct hidled_device	*ldev;
	struct hidled_led	red;
	struct hidled_led	green;
	struct hidled_led	blue;
	u8			num;
};

struct hidled_device {
	const struct hidled_config *config;
	struct hid_device       *hdev;
	struct hidled_rgb	*rgb;
	struct mutex		lock;
};

#define MAX_REPORT_SIZE		16

#define to_hidled_led(arg) container_of(arg, struct hidled_led, cdev)

static bool riso_kagaku_switch_green_blue;
module_param(riso_kagaku_switch_green_blue, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(riso_kagaku_switch_green_blue,
	"switch green and blue RGB component for Riso Kagaku devices");

static int hidled_send(struct hidled_device *ldev, __u8 *buf)
{
	int ret;

	mutex_lock(&ldev->lock);

	if (ldev->config->report_type == RAW_REQUEST)
		ret = hid_hw_raw_request(ldev->hdev, buf[0], buf,
					 ldev->config->report_size,
					 HID_FEATURE_REPORT,
					 HID_REQ_SET_REPORT);
	else if (ldev->config->report_type == OUTPUT_REPORT)
		ret = hid_hw_output_report(ldev->hdev, buf,
					   ldev->config->report_size);
	else
		ret = -EINVAL;

	mutex_unlock(&ldev->lock);

	if (ret < 0)
		return ret;

	return ret == ldev->config->report_size ? 0 : -EMSGSIZE;
}

/* reading data is supported for report type RAW_REQUEST only */
static int hidled_recv(struct hidled_device *ldev, __u8 *buf)
{
	int ret;

	if (ldev->config->report_type != RAW_REQUEST)
		return -EINVAL;

	mutex_lock(&ldev->lock);

	ret = hid_hw_raw_request(ldev->hdev, buf[0], buf,
				 ldev->config->report_size,
				 HID_FEATURE_REPORT,
				 HID_REQ_SET_REPORT);
	if (ret < 0)
		goto err;

	ret = hid_hw_raw_request(ldev->hdev, buf[0], buf,
				 ldev->config->report_size,
				 HID_FEATURE_REPORT,
				 HID_REQ_GET_REPORT);
err:
	mutex_unlock(&ldev->lock);

	return ret < 0 ? ret : 0;
}

static u8 riso_kagaku_index(struct hidled_rgb *rgb)
{
	enum led_brightness r, g, b;

	r = rgb->red.cdev.brightness;
	g = rgb->green.cdev.brightness;
	b = rgb->blue.cdev.brightness;

	if (riso_kagaku_switch_green_blue)
		return RISO_KAGAKU_IX(r, b, g);
	else
		return RISO_KAGAKU_IX(r, g, b);
}

static int riso_kagaku_write(struct led_classdev *cdev, enum led_brightness br)
{
	struct hidled_led *led = to_hidled_led(cdev);
	struct hidled_rgb *rgb = led->rgb;
	__u8 buf[MAX_REPORT_SIZE] = {};

	buf[1] = riso_kagaku_index(rgb);

	return hidled_send(rgb->ldev, buf);
}

static int dream_cheeky_write(struct led_classdev *cdev, enum led_brightness br)
{
	struct hidled_led *led = to_hidled_led(cdev);
	struct hidled_rgb *rgb = led->rgb;
	__u8 buf[MAX_REPORT_SIZE] = {};

	buf[1] = rgb->red.cdev.brightness;
	buf[2] = rgb->green.cdev.brightness;
	buf[3] = rgb->blue.cdev.brightness;
	buf[7] = 0x1a;
	buf[8] = 0x05;

	return hidled_send(rgb->ldev, buf);
}

static int dream_cheeky_init(struct hidled_device *ldev)
{
	__u8 buf[MAX_REPORT_SIZE] = {};

	/* Dream Cheeky magic */
	buf[1] = 0x1f;
	buf[2] = 0x02;
	buf[4] = 0x5f;
	buf[7] = 0x1a;
	buf[8] = 0x03;

	return hidled_send(ldev, buf);
}

static int _thingm_write(struct led_classdev *cdev, enum led_brightness br,
			 u8 offset)
{
	struct hidled_led *led = to_hidled_led(cdev);
	__u8 buf[MAX_REPORT_SIZE] = { 1, 'c' };

	buf[2] = led->rgb->red.cdev.brightness;
	buf[3] = led->rgb->green.cdev.brightness;
	buf[4] = led->rgb->blue.cdev.brightness;
	buf[7] = led->rgb->num + offset;

	return hidled_send(led->rgb->ldev, buf);
}

static int thingm_write_v1(struct led_classdev *cdev, enum led_brightness br)
{
	return _thingm_write(cdev, br, 0);
}

static int thingm_write(struct led_classdev *cdev, enum led_brightness br)
{
	return _thingm_write(cdev, br, 1);
}

static const struct hidled_config hidled_config_thingm_v1 = {
	.name = "ThingM blink(1) v1",
	.short_name = "thingm",
	.max_brightness = 255,
	.num_leds = 1,
	.report_size = 9,
	.report_type = RAW_REQUEST,
	.write = thingm_write_v1,
};

static int thingm_init(struct hidled_device *ldev)
{
	__u8 buf[MAX_REPORT_SIZE] = { 1, 'v' };
	int ret;

	ret = hidled_recv(ldev, buf);
	if (ret)
		return ret;

	/* Check for firmware major version 1 */
	if (buf[3] == '1')
		ldev->config = &hidled_config_thingm_v1;

	return 0;
}

static inline int delcom_get_lednum(const struct hidled_led *led)
{
	if (led == &led->rgb->red)
		return DELCOM_RED_LED;
	else if (led == &led->rgb->green)
		return DELCOM_GREEN_LED;
	else
		return DELCOM_BLUE_LED;
}

static int delcom_enable_led(struct hidled_led *led)
{
	union delcom_packet dp = { .tx.major_cmd = 101, .tx.minor_cmd = 12 };

	dp.tx.data_lsb = 1 << delcom_get_lednum(led);
	dp.tx.data_msb = 0;

	return hidled_send(led->rgb->ldev, dp.data);
}

static int delcom_set_pwm(struct hidled_led *led)
{
	union delcom_packet dp = { .tx.major_cmd = 101, .tx.minor_cmd = 34 };

	dp.tx.data_lsb = delcom_get_lednum(led);
	dp.tx.data_msb = led->cdev.brightness;

	return hidled_send(led->rgb->ldev, dp.data);
}

static int delcom_write(struct led_classdev *cdev, enum led_brightness br)
{
	struct hidled_led *led = to_hidled_led(cdev);
	int ret;

	/*
	 * enable LED
	 * We can't do this in the init function already because the device
	 * is internally reset later.
	 */
	ret = delcom_enable_led(led);
	if (ret)
		return ret;

	return delcom_set_pwm(led);
}

static int delcom_init(struct hidled_device *ldev)
{
	union delcom_packet dp = { .rx.cmd = 104 };
	int ret;

	ret = hidled_recv(ldev, dp.data);
	if (ret)
		return ret;
	/*
	 * Several Delcom devices share the same USB VID/PID
	 * Check for family id 2 for Visual Signal Indicator
	 */
	return dp.fw.family_code == 2 ? 0 : -ENODEV;
}

static const struct hidled_config hidled_configs[] = {
	{
		.type = RISO_KAGAKU,
		.name = "Riso Kagaku Webmail Notifier",
		.short_name = "riso_kagaku",
		.max_brightness = 1,
		.num_leds = 1,
		.report_size = 6,
		.report_type = OUTPUT_REPORT,
		.write = riso_kagaku_write,
	},
	{
		.type = DREAM_CHEEKY,
		.name = "Dream Cheeky Webmail Notifier",
		.short_name = "dream_cheeky",
		.max_brightness = 31,
		.num_leds = 1,
		.report_size = 9,
		.report_type = RAW_REQUEST,
		.init = dream_cheeky_init,
		.write = dream_cheeky_write,
	},
	{
		.type = THINGM,
		.name = "ThingM blink(1)",
		.short_name = "thingm",
		.max_brightness = 255,
		.num_leds = 2,
		.report_size = 9,
		.report_type = RAW_REQUEST,
		.init = thingm_init,
		.write = thingm_write,
	},
	{
		.type = DELCOM,
		.name = "Delcom Visual Signal Indicator G2",
		.short_name = "delcom",
		.max_brightness = 100,
		.num_leds = 1,
		.report_size = 8,
		.report_type = RAW_REQUEST,
		.init = delcom_init,
		.write = delcom_write,
	},
};

static int hidled_init_led(struct hidled_led *led, const char *color_name,
			   struct hidled_rgb *rgb, unsigned int minor)
{
	const struct hidled_config *config = rgb->ldev->config;

	if (config->num_leds > 1)
		snprintf(led->name, sizeof(led->name), "%s%u:%s:led%u",
			 config->short_name, minor, color_name, rgb->num);
	else
		snprintf(led->name, sizeof(led->name), "%s%u:%s",
			 config->short_name, minor, color_name);
	led->cdev.name = led->name;
	led->cdev.max_brightness = config->max_brightness;
	led->cdev.brightness_set_blocking = config->write;
	led->cdev.flags = LED_HW_PLUGGABLE;
	led->rgb = rgb;

	return devm_led_classdev_register(&rgb->ldev->hdev->dev, &led->cdev);
}

static int hidled_init_rgb(struct hidled_rgb *rgb, unsigned int minor)
{
	int ret;

	/* Register the red diode */
	ret = hidled_init_led(&rgb->red, "red", rgb, minor);
	if (ret)
		return ret;

	/* Register the green diode */
	ret = hidled_init_led(&rgb->green, "green", rgb, minor);
	if (ret)
		return ret;

	/* Register the blue diode */
	return hidled_init_led(&rgb->blue, "blue", rgb, minor);
}

static int hidled_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	struct hidled_device *ldev;
	unsigned int minor;
	int ret, i;

	ldev = devm_kzalloc(&hdev->dev, sizeof(*ldev), GFP_KERNEL);
	if (!ldev)
		return -ENOMEM;

	ret = hid_parse(hdev);
	if (ret)
		return ret;

	ldev->hdev = hdev;
	mutex_init(&ldev->lock);

	for (i = 0; !ldev->config && i < ARRAY_SIZE(hidled_configs); i++)
		if (hidled_configs[i].type == id->driver_data)
			ldev->config = &hidled_configs[i];

	if (!ldev->config)
		return -EINVAL;

	if (ldev->config->init) {
		ret = ldev->config->init(ldev);
		if (ret)
			return ret;
	}

	ldev->rgb = devm_kcalloc(&hdev->dev, ldev->config->num_leds,
				 sizeof(struct hidled_rgb), GFP_KERNEL);
	if (!ldev->rgb)
		return -ENOMEM;

	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
	if (ret)
		return ret;

	minor = ((struct hidraw *) hdev->hidraw)->minor;

	for (i = 0; i < ldev->config->num_leds; i++) {
		ldev->rgb[i].ldev = ldev;
		ldev->rgb[i].num = i;
		ret = hidled_init_rgb(&ldev->rgb[i], minor);
		if (ret) {
			hid_hw_stop(hdev);
			return ret;
		}
	}

	hid_info(hdev, "%s initialized\n", ldev->config->name);

	return 0;
}

static const struct hid_device_id hidled_table[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU,
	  USB_DEVICE_ID_RI_KA_WEBMAIL), .driver_data = RISO_KAGAKU },
	{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY,
	  USB_DEVICE_ID_DREAM_CHEEKY_WN), .driver_data = DREAM_CHEEKY },
	{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY,
	  USB_DEVICE_ID_DREAM_CHEEKY_FA), .driver_data = DREAM_CHEEKY },
	{ HID_USB_DEVICE(USB_VENDOR_ID_THINGM,
	  USB_DEVICE_ID_BLINK1), .driver_data = THINGM },
	{ HID_USB_DEVICE(USB_VENDOR_ID_DELCOM,
	  USB_DEVICE_ID_DELCOM_VISUAL_IND), .driver_data = DELCOM },
	{ }
};
MODULE_DEVICE_TABLE(hid, hidled_table);

static struct hid_driver hidled_driver = {
	.name = "hid-led",
	.probe = hidled_probe,
	.id_table = hidled_table,
};

module_hid_driver(hidled_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Heiner Kallweit <hkallweit1@gmail.com>");
MODULE_DESCRIPTION("Simple USB RGB LED driver");
