/*
 * ThingM blink(1) USB RGB LED driver
 *
 * Copyright 2013 Savoir-faire Linux Inc.
 *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
 *
 * 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/leds.h>
#include <linux/module.h>

#include "hid-ids.h"

#define BLINK1_CMD_SIZE		9

#define blink1_rgb_to_r(rgb)	((rgb & 0xFF0000) >> 16)
#define blink1_rgb_to_g(rgb)	((rgb & 0x00FF00) >> 8)
#define blink1_rgb_to_b(rgb)	((rgb & 0x0000FF) >> 0)

/**
 * struct blink1_data - blink(1) device specific data
 * @hdev:		HID device.
 * @led_cdev:		LED class instance.
 * @rgb:		8-bit per channel RGB notation.
 * @fade:		fade time in hundredths of a second.
 * @brightness:		brightness coefficient.
 * @play:		play/pause in-memory patterns.
 */
struct blink1_data {
	struct hid_device *hdev;
	struct led_classdev led_cdev;
	u32 rgb;
	u16 fade;
	u8 brightness;
	bool play;
};

static int blink1_send_command(struct blink1_data *data,
		u8 buf[BLINK1_CMD_SIZE])
{
	int ret;

	hid_dbg(data->hdev, "command: %d%c%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
			buf[0], buf[1], buf[2], buf[3], buf[4],
			buf[5], buf[6], buf[7], buf[8]);

	ret = hid_hw_raw_request(data->hdev, buf[0], buf, BLINK1_CMD_SIZE,
				 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);

	return ret < 0 ? ret : 0;
}

static int blink1_update_color(struct blink1_data *data)
{
	u8 buf[BLINK1_CMD_SIZE] = { 1, 'n', 0, 0, 0, 0, 0, 0, 0 };

	if (data->brightness) {
		unsigned int coef = DIV_ROUND_CLOSEST(255, data->brightness);

		buf[2] = DIV_ROUND_CLOSEST(blink1_rgb_to_r(data->rgb), coef);
		buf[3] = DIV_ROUND_CLOSEST(blink1_rgb_to_g(data->rgb), coef);
		buf[4] = DIV_ROUND_CLOSEST(blink1_rgb_to_b(data->rgb), coef);
	}

	if (data->fade) {
		buf[1] = 'c';
		buf[5] = (data->fade & 0xFF00) >> 8;
		buf[6] = (data->fade & 0x00FF);
	}

	return blink1_send_command(data, buf);
}

static void blink1_led_set(struct led_classdev *led_cdev,
		enum led_brightness brightness)
{
	struct blink1_data *data = dev_get_drvdata(led_cdev->dev->parent);

	data->brightness = brightness;
	if (blink1_update_color(data))
		hid_err(data->hdev, "failed to update color\n");
}

static enum led_brightness blink1_led_get(struct led_classdev *led_cdev)
{
	struct blink1_data *data = dev_get_drvdata(led_cdev->dev->parent);

	return data->brightness;
}

static ssize_t blink1_show_rgb(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct blink1_data *data = dev_get_drvdata(dev->parent);

	return sprintf(buf, "%.6X\n", data->rgb);
}

static ssize_t blink1_store_rgb(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct blink1_data *data = dev_get_drvdata(dev->parent);
	long unsigned int rgb;
	int ret;

	ret = kstrtoul(buf, 16, &rgb);
	if (ret)
		return ret;

	/* RGB triplet notation is 24-bit hexadecimal */
	if (rgb > 0xFFFFFF)
		return -EINVAL;

	data->rgb = rgb;
	ret = blink1_update_color(data);

	return ret ? ret : count;
}

static DEVICE_ATTR(rgb, S_IRUGO | S_IWUSR, blink1_show_rgb, blink1_store_rgb);

static ssize_t blink1_show_fade(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct blink1_data *data = dev_get_drvdata(dev->parent);

	return sprintf(buf, "%d\n", data->fade * 10);
}

static ssize_t blink1_store_fade(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct blink1_data *data = dev_get_drvdata(dev->parent);
	long unsigned int fade;
	int ret;

	ret = kstrtoul(buf, 10, &fade);
	if (ret)
		return ret;

	/* blink(1) accepts 16-bit fade time, number of 10ms ticks */
	fade = DIV_ROUND_CLOSEST(fade, 10);
	if (fade > 65535)
		return -EINVAL;

	data->fade = fade;

	return count;
}

static DEVICE_ATTR(fade, S_IRUGO | S_IWUSR,
		blink1_show_fade, blink1_store_fade);

static ssize_t blink1_show_play(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct blink1_data *data = dev_get_drvdata(dev->parent);

	return sprintf(buf, "%d\n", data->play);
}

static ssize_t blink1_store_play(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct blink1_data *data = dev_get_drvdata(dev->parent);
	u8 cmd[BLINK1_CMD_SIZE] = { 1, 'p', 0, 0, 0, 0, 0, 0, 0 };
	long unsigned int play;
	int ret;

	ret = kstrtoul(buf, 10, &play);
	if (ret)
		return ret;

	data->play = !!play;
	cmd[2] = data->play;
	ret = blink1_send_command(data, cmd);

	return ret ? ret : count;
}

static DEVICE_ATTR(play, S_IRUGO | S_IWUSR,
		blink1_show_play, blink1_store_play);

static const struct attribute_group blink1_sysfs_group = {
	.attrs = (struct attribute *[]) {
		&dev_attr_rgb.attr,
		&dev_attr_fade.attr,
		&dev_attr_play.attr,
		NULL
	},
};

static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	struct blink1_data *data;
	struct led_classdev *led;
	char led_name[13];
	int ret;

	data = devm_kzalloc(&hdev->dev, sizeof(struct blink1_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	hid_set_drvdata(hdev, data);
	data->hdev = hdev;
	data->rgb = 0xFFFFFF; /* set a default white color */

	ret = hid_parse(hdev);
	if (ret)
		goto error;

	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
	if (ret)
		goto error;

	/* blink(1) serial numbers range is 0x1A001000 to 0x1A002FFF */
	led = &data->led_cdev;
	snprintf(led_name, sizeof(led_name), "blink1::%s", hdev->uniq + 4);
	led->name = led_name;
	led->brightness_set = blink1_led_set;
	led->brightness_get = blink1_led_get;
	ret = led_classdev_register(&hdev->dev, led);
	if (ret)
		goto stop;

	ret = sysfs_create_group(&led->dev->kobj, &blink1_sysfs_group);
	if (ret)
		goto remove_led;

	return 0;

remove_led:
	led_classdev_unregister(led);
stop:
	hid_hw_stop(hdev);
error:
	return ret;
}

static void thingm_remove(struct hid_device *hdev)
{
	struct blink1_data *data = hid_get_drvdata(hdev);
	struct led_classdev *led = &data->led_cdev;

	sysfs_remove_group(&led->dev->kobj, &blink1_sysfs_group);
	led_classdev_unregister(led);
	hid_hw_stop(hdev);
}

static const struct hid_device_id thingm_table[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) },
	{ }
};
MODULE_DEVICE_TABLE(hid, thingm_table);

static struct hid_driver thingm_driver = {
	.name = "thingm",
	.probe = thingm_probe,
	.remove = thingm_remove,
	.id_table = thingm_table,
};

module_hid_driver(thingm_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vivien Didelot <vivien.didelot@savoirfairelinux.com>");
MODULE_DESCRIPTION("ThingM blink(1) USB RGB LED driver");
